wip: new onboarding

This commit is contained in:
reya
2023-10-16 14:42:19 +07:00
parent cd3b9ada5a
commit 3aa4f294f9
28 changed files with 550 additions and 559 deletions
@@ -1,21 +1,16 @@
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useStorage } from '@libs/storage/provider';
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
import { ArrowLeftIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
import { User } from '@shared/user';
import { useOnboarding } from '@stores/onboarding';
import { useNostr } from '@utils/hooks/useNostr';
import { arrayToNIP02 } from '@utils/transform';
export function OnboardStep1Screen() {
const navigate = useNavigate();
const setStep = useOnboarding((state) => state.setStep);
export function OnboardEnrichScreen() {
const { publish, fetchUserData } = useNostr();
const { db } = useStorage();
const { status, data } = useQuery(['trending-profiles-widget'], async () => {
@@ -29,6 +24,8 @@ export function OnboardStep1Screen() {
const [loading, setLoading] = useState(false);
const [follows, setFollows] = useState([]);
const navigate = useNavigate();
// toggle follow state
const toggleFollow = (pubkey: string) => {
const arr = follows.includes(pubkey)
@@ -59,27 +56,28 @@ export function OnboardStep1Screen() {
}
};
useEffect(() => {
// save current step, if user close app and reopen it
setStep('/auth/onboarding');
}, []);
return (
<div className="flex h-full w-full flex-col justify-center">
<div className="mx-auto mb-4 w-full max-w-md border-b border-white/10 pb-4">
<h1 className="mb-2 text-center text-2xl font-semibold text-white">
<div className="relative flex h-full w-full flex-col justify-center">
<div className="absolute left-[8px] top-4">
<button
onClick={() => navigate(-1)}
className="inline-flex items-center gap-2 text-sm font-medium"
>
<div className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-200 text-neutral-800 dark:bg-neutral-800 dark:text-neutral-200">
<ArrowLeftIcon className="h-5 w-5" />
</div>
Back
</button>
</div>
<div className="mx-auto mb-8 w-full max-w-md px-3">
<h1 className="text-center text-2xl font-semibold text-neutral-900 dark:text-neutral-100">
{loading ? 'Loading...' : 'Enrich your network'}
</h1>
<p className="text-white/70">
Choose the account you want to follow. These accounts are trending in the last
24 hours. If none of the accounts interest you, you can explore more options and
add them later.
</p>
</div>
<div className="flex w-full flex-nowrap items-center gap-4 overflow-x-auto px-4 scrollbar-none">
{status === 'loading' ? (
<div className="flex h-full w-full items-center justify-center">
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
<LoaderIcon className="h-4 w-4 animate-spin text-neutral-900 dark:text-neutral-100" />
</div>
) : (
data?.profiles.map((item: { pubkey: string; profile: { content: string } }) => (
@@ -87,7 +85,7 @@ export function OnboardStep1Screen() {
key={item.pubkey}
type="button"
onClick={() => toggleFollow(item.pubkey)}
className="relative h-[300px] shrink-0 grow-0 basis-[250px] rounded-lg border-t border-white/10 bg-white/20 px-4 py-4 hover:bg-white/30"
className="relative h-[300px] shrink-0 grow-0 basis-[250px] overflow-hidden rounded-lg bg-neutral-200 px-4 py-4 hover:bg-neutral-300 dark:bg-neutral-800 dark:hover:bg-neutral-700"
>
<User
pubkey={item.pubkey}
@@ -96,42 +94,29 @@ export function OnboardStep1Screen() {
/>
{follows.includes(item.pubkey) && (
<div className="absolute right-2 top-2">
<CheckCircleIcon className="h-4 w-4 text-green-400" />
<CheckCircleIcon className="h-5 w-5 text-teal-400" />
</div>
)}
</button>
))
)}
</div>
<div className="mx-auto mt-4 w-full max-w-md">
<div className="flex flex-col gap-2">
<button
type="button"
onClick={submit}
disabled={loading || follows.length === 0}
className="inline-flex h-12 w-full items-center justify-between gap-2 rounded-lg border-t border-white/10 bg-blue-500 px-6 font-medium leading-none text-white hover:bg-blue-600 focus:outline-none disabled:opacity-50"
>
{loading ? (
<>
<span className="w-5" />
<span>It might take a bit, please patient...</span>
<LoaderIcon className="h-5 w-5 animate-spin text-white" />
</>
) : (
<>
<span className="w-5" />
<span>Follow {follows.length} accounts & Continue</span>
<ArrowRightCircleIcon className="h-5 w-5" />
</>
)}
</button>
<Link
to="/auth/onboarding/step-2"
className="inline-flex h-12 w-full items-center justify-center rounded-lg border-t border-white/10 bg-white/20 px-6 font-medium leading-none text-white backdrop-blur-xl hover:bg-white/30 focus:outline-none"
>
Skip, you can add later
</Link>
</div>
<div className="mx-auto mt-8 w-full max-w-md px-3">
<button
type="button"
onClick={submit}
disabled={loading || follows.length === 0}
className="inline-flex h-9 w-full items-center justify-center gap-2 rounded-lg bg-blue-500 font-medium text-white hover:bg-blue-600 focus:outline-none disabled:opacity-50"
>
{loading ? (
<>
<LoaderIcon className="h-4 w-4 animate-spin" />
<span>It might take a bit, please patient...</span>
</>
) : (
<span>Follow {follows.length} accounts & Continue</span>
)}
</button>
</div>
</div>
);
@@ -1,12 +1,11 @@
import { message } from '@tauri-apps/plugin-dialog';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useStorage } from '@libs/storage/provider';
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
import { useOnboarding } from '@stores/onboarding';
import { WidgetKinds } from '@stores/widgets';
const data = [
@@ -32,15 +31,13 @@ const data = [
{ hashtag: '#dev' },
];
export function OnboardStep2Screen() {
export function OnboardHashtagScreen() {
const { db } = useStorage();
const navigate = useNavigate();
const [setStep, clearStep] = useOnboarding((state) => [state.setStep, state.clearStep]);
const [loading, setLoading] = useState(false);
const [tags, setTags] = useState(new Set<string>());
const { db } = useStorage();
const toggleTag = (tag: string) => {
if (tags.has(tag)) {
setTags((prev) => {
@@ -57,9 +54,6 @@ export function OnboardStep2Screen() {
// update last login
await db.updateLastLogin();
// clear local storage
clearStep();
navigate('/auth/complete', { replace: true });
};
@@ -74,9 +68,6 @@ export function OnboardStep2Screen() {
// update last login
await db.updateLastLogin();
// clear local storage
clearStep();
navigate('/auth/complete', { replace: true });
} catch (e) {
setLoading(false);
@@ -84,11 +75,6 @@ export function OnboardStep2Screen() {
}
};
useEffect(() => {
// save current step, if user close app and reopen it
setStep('/auth/onboarding/step-2');
}, []);
return (
<div className="mx-auto w-full max-w-md">
<div className="mb-4 border-b border-white/10 pb-4">
+1 -5
View File
@@ -1,9 +1,5 @@
import { Outlet } from 'react-router-dom';
export function OnboardingScreen() {
return (
<div className="flex h-full w-full items-center justify-center">
<Outlet />
</div>
);
return <Outlet />;
}
+41
View File
@@ -0,0 +1,41 @@
import { Link, useLocation } from 'react-router-dom';
import { CustomRelay } from '@app/auth/components/features/customRelay';
import { FavoriteHashtag } from '@app/auth/components/features/favoriteHashtag';
import { FollowList } from '@app/auth/components/features/followList';
import { LinkList } from '@app/auth/components/features/linkList';
import { NIP04 } from '@app/auth/components/features/nip04';
import { SuggestFollow } from '@app/auth/components/features/suggestFollow';
export function OnboardingListScreen() {
const { state } = useLocation();
const { newuser }: { newuser: boolean } = state;
return (
<div className="relative flex h-full w-full items-center justify-center">
<div className="mx-auto flex w-full max-w-md flex-col gap-10">
<div className="text-center">
<h1 className="text-2xl text-neutral-900 dark:text-neutral-100">
You&apos;re almost ready to use Lume.
</h1>
<h2 className="text-xl font-semibold text-neutral-900 dark:text-neutral-100">
Let&apos;s start personalizing your experience.
</h2>
</div>
<div className="flex flex-col gap-3">
{newuser ? <SuggestFollow /> : <FollowList />}
<FavoriteHashtag />
<LinkList />
<NIP04 />
<CustomRelay />
<Link
to="/"
className="inline-flex h-9 w-full items-center justify-center rounded-lg bg-blue-500 font-semibold text-white hover:bg-blue-600"
>
Continue
</Link>
</div>
</div>
</div>
);
}
@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useNDK } from '@libs/ndk/provider';
@@ -9,14 +9,12 @@ import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons
import { User } from '@shared/user';
import { FULL_RELAYS } from '@stores/constants';
import { useOnboarding } from '@stores/onboarding';
import { useNostr } from '@utils/hooks/useNostr';
export function OnboardStep3Screen() {
export function OnboardRelaysScreen() {
const navigate = useNavigate();
const [setStep, clearStep] = useOnboarding((state) => [state.setStep, state.clearStep]);
const [loading, setLoading] = useState(false);
const [relays, setRelays] = useState(new Set<string>());
@@ -81,7 +79,6 @@ export function OnboardStep3Screen() {
// update last login
await db.updateLastLogin();
clearStep();
navigate('/', { replace: true });
} catch (e) {
setLoading(false);
@@ -89,11 +86,6 @@ export function OnboardStep3Screen() {
}
};
useEffect(() => {
// save current step, if user close app and reopen it
setStep('/auth/onboarding/step-3');
}, []);
return (
<div className="mx-auto w-full max-w-md">
<div className="mb-8 text-center">