diff --git a/client/cms/src/components/events/event-join.dialog.container.tsx b/client/cms/src/components/events/event-join.dialog.container.tsx index 4bd056d..e447f44 100644 --- a/client/cms/src/components/events/event-join.dialog.container.tsx +++ b/client/cms/src/components/events/event-join.dialog.container.tsx @@ -6,7 +6,7 @@ import { Dialog } from '../ui/dialog'; import { EventJoinDialogView } from './event-join.dialog.view'; export function EventJoinDialogContainer({ event, children }: { event: EventInfo; children: React.ReactNode }) { - const { mutateAsync } = useJoinEvent(); + const { mutateAsync, isPending } = useJoinEvent(); const join = useCallback(() => { mutateAsync({ body: { event_id: event.eventId } }).then(() => { toast('加入活动成功'); @@ -19,7 +19,7 @@ export function EventJoinDialogContainer({ event, children }: { event: EventInfo return ( {children} - + ); } diff --git a/client/cms/src/components/events/event-join.dialog.view.tsx b/client/cms/src/components/events/event-join.dialog.view.tsx index 3a90d1f..27bf33e 100644 --- a/client/cms/src/components/events/event-join.dialog.view.tsx +++ b/client/cms/src/components/events/event-join.dialog.view.tsx @@ -1,8 +1,9 @@ import type { EventInfo } from './types'; +import { Loader2 } from 'lucide-react'; import { Button } from '../ui/button'; import { DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog'; -export function EventJoinDialogView({ event, onJoinEvent }: { event: EventInfo; onJoinEvent: () => void }) { +export function EventJoinDialogView({ event, onJoinEvent, isPending }: { event: EventInfo; onJoinEvent: () => void; isPending: boolean }) { return ( @@ -18,7 +19,7 @@ export function EventJoinDialogView({ event, onJoinEvent }: { event: EventInfo; - + ); diff --git a/client/cms/src/components/events/kyc/kyc-method-selection.dialog.view.tsx b/client/cms/src/components/events/kyc/kyc-method-selection.dialog.view.tsx index 238f666..19f23d6 100644 --- a/client/cms/src/components/events/kyc/kyc-method-selection.dialog.view.tsx +++ b/client/cms/src/components/events/kyc/kyc-method-selection.dialog.view.tsx @@ -1,5 +1,6 @@ import type { KycSubmission } from './kyc.types'; import { useForm } from '@tanstack/react-form'; +import { Loader2 } from 'lucide-react'; import { useState } from 'react'; import { toast } from 'sonner'; import z from 'zod'; @@ -80,7 +81,7 @@ function CnridForm({ onSubmit }: { onSubmit: OnSubmit }) { [state.canSubmit, state.isPristine, state.isSubmitting]} children={([canSubmit, isPristine, isSubmitting]) => ( - + )} /> diff --git a/client/cms/src/components/login-form.tsx b/client/cms/src/components/login-form.tsx index f2f5c05..d680048 100644 --- a/client/cms/src/components/login-form.tsx +++ b/client/cms/src/components/login-form.tsx @@ -2,6 +2,7 @@ import type { TurnstileInstance } from '@marsidev/react-turnstile'; import type { AuthorizeSearchParams } from '@/routes/authorize'; import { Turnstile } from '@marsidev/react-turnstile'; import { useNavigate } from '@tanstack/react-router'; +import { Loader2 } from 'lucide-react'; import { useRef, useState } from 'react'; import { toast } from 'sonner'; import NixOSLogo from '@/assets/nixos.svg?react'; @@ -41,6 +42,7 @@ export function LoginForm({ }); }; + const isLoading = isPending || token === null; return (
@@ -63,7 +65,8 @@ export function LoginForm({ /> - diff --git a/client/cms/src/components/profile/edit-profile.dialog.view.tsx b/client/cms/src/components/profile/edit-profile.dialog.view.tsx index 897205e..884800d 100644 --- a/client/cms/src/components/profile/edit-profile.dialog.view.tsx +++ b/client/cms/src/components/profile/edit-profile.dialog.view.tsx @@ -1,5 +1,6 @@ import type { ServiceUserUserInfoData } from '@/client'; import { useForm } from '@tanstack/react-form'; +import { Loader2 } from 'lucide-react'; import { useEffect, useState, @@ -164,9 +165,11 @@ export function EditProfileDialogView({ user, updateProfile }: { user: ServiceUs [state.canSubmit]} - children={([canSubmit]) => ( - + selector={state => [state.canSubmit, state.isSubmitting]} + children={([canSubmit, isSubmitting]) => ( + )} /> diff --git a/client/cms/src/components/profile/profile.view.tsx b/client/cms/src/components/profile/profile.view.tsx index 5981f0b..c0eb78d 100644 --- a/client/cms/src/components/profile/profile.view.tsx +++ b/client/cms/src/components/profile/profile.view.tsx @@ -6,7 +6,7 @@ import { isEmpty, isNil, } from 'lodash-es'; -import { Mail, Pencil } from 'lucide-react'; +import { Loader2, Mail, Pencil } from 'lucide-react'; import { useMemo, useState } from 'react'; import Markdown from 'react-markdown'; import { toast } from 'sonner'; @@ -18,6 +18,7 @@ import { EditProfileDialogContainer } from './edit-profile.dialog.container'; export function ProfileView({ user, onSaveBio }: { user: ServiceUserUserInfoData; onSaveBio: (bio: string) => Promise }) { const [bio, setBio] = useState(() => base64ToUtf8(user.bio ?? '')); const [enableBioEdit, setEnableBioEdit] = useState(false); + const [isSubmittingBio, setIsSubmittingBio] = useState(false); const IdentIcon = useMemo(() => { const avatar = createAvatar(identicon, { @@ -53,12 +54,12 @@ export function ProfileView({ user, onSaveBio }: { user: ServiceUserUserInfoData {/* Bio */} {enableBioEdit ? ( - - ) + + ) :
{bio}
}
diff --git a/client/cms/src/stories/events/join-dialog.stories.tsx b/client/cms/src/stories/events/join-dialog.stories.tsx index 5b53c14..82c25f7 100644 --- a/client/cms/src/stories/events/join-dialog.stories.tsx +++ b/client/cms/src/stories/events/join-dialog.stories.tsx @@ -22,5 +22,6 @@ export const Confirm: Story = { args: { event: exampleEvent, onJoinEvent: () => { }, + isPending: false, }, };