diff --git a/apps/remix/app/components/forms/avatar-image.tsx b/apps/remix/app/components/forms/avatar-image.tsx index dc8881f7b..852063287 100644 --- a/apps/remix/app/components/forms/avatar-image.tsx +++ b/apps/remix/app/components/forms/avatar-image.tsx @@ -42,7 +42,7 @@ export type AvatarImageFormProps = { }; export const AvatarImageForm = ({ className }: AvatarImageFormProps) => { - const { user } = useSession(); + const { user, refreshSession } = useSession(); const { _ } = useLingui(); const { toast } = useToast(); const { revalidate } = useRevalidator(); @@ -103,13 +103,13 @@ export const AvatarImageForm = ({ className }: AvatarImageFormProps) => { teamId: team?.id, }); + await refreshSession(); + toast({ title: _(msg`Avatar Updated`), description: _(msg`Your avatar has been updated successfully.`), duration: 5000, }); - - void revalidate(); } catch (err) { const error = AppError.parseError(err); diff --git a/apps/remix/app/components/forms/profile.tsx b/apps/remix/app/components/forms/profile.tsx index c5e179e15..f6493a6cd 100644 --- a/apps/remix/app/components/forms/profile.tsx +++ b/apps/remix/app/components/forms/profile.tsx @@ -3,7 +3,6 @@ import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { useForm } from 'react-hook-form'; -import { useRevalidator } from 'react-router'; import { z } from 'zod'; import { useSession } from '@documenso/lib/client-only/providers/session'; @@ -42,8 +41,7 @@ export type ProfileFormProps = { export const ProfileForm = ({ className }: ProfileFormProps) => { const { _ } = useLingui(); const { toast } = useToast(); - const { user } = useSession(); - const { revalidate } = useRevalidator(); + const { user, refreshSession } = useSession(); const form = useForm({ values: { @@ -64,13 +62,13 @@ export const ProfileForm = ({ className }: ProfileFormProps) => { signature, }); + await refreshSession(); + toast({ title: _(msg`Profile updated`), description: _(msg`Your profile has been updated successfully.`), duration: 5000, }); - - await revalidate(); } catch (err) { toast({ title: _(msg`An unknown error occurred`), diff --git a/apps/remix/app/components/forms/public-profile-claim-dialog.tsx b/apps/remix/app/components/forms/public-profile-claim-dialog.tsx deleted file mode 100644 index f5e55e2ef..000000000 --- a/apps/remix/app/components/forms/public-profile-claim-dialog.tsx +++ /dev/null @@ -1,197 +0,0 @@ -import React, { useState } from 'react'; - -import { zodResolver } from '@hookform/resolvers/zod'; -import { msg } from '@lingui/core/macro'; -import { useLingui } from '@lingui/react'; -import type { User } from '@prisma/client'; -import { useForm } from 'react-hook-form'; -import { z } from 'zod'; - -import profileClaimTeaserImage from '@documenso/assets/images/profile-claim-teaser.png'; -import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; -import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; -import { trpc } from '@documenso/trpc/react'; -import { cn } from '@documenso/ui/lib/utils'; -import { Button } from '@documenso/ui/primitives/button'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, -} from '@documenso/ui/primitives/dialog'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@documenso/ui/primitives/form/form'; -import { Input } from '@documenso/ui/primitives/input'; -import { useToast } from '@documenso/ui/primitives/use-toast'; - -import { UserProfileSkeleton } from '../general/user-profile-skeleton'; - -export const ZClaimPublicProfileFormSchema = z.object({ - url: z - .string() - .trim() - .toLowerCase() - .min(1, { message: 'Please enter a valid username.' }) - .regex(/^[a-z0-9-]+$/, { - message: 'Username can only container alphanumeric characters and dashes.', - }), -}); - -export type TClaimPublicProfileFormSchema = z.infer; - -export type ClaimPublicProfileDialogFormProps = { - open: boolean; - onOpenChange?: (open: boolean) => void; - onClaimed?: () => void; - user: User; -}; - -export const ClaimPublicProfileDialogForm = ({ - open, - onOpenChange, - onClaimed, - user, -}: ClaimPublicProfileDialogFormProps) => { - const { _ } = useLingui(); - const { toast } = useToast(); - - const [claimed, setClaimed] = useState(false); - - const baseUrl = new URL(NEXT_PUBLIC_WEBAPP_URL() ?? 'http://localhost:3000'); - - const form = useForm({ - values: { - url: user.url || '', - }, - resolver: zodResolver(ZClaimPublicProfileFormSchema), - }); - - const { mutateAsync: updatePublicProfile } = trpc.profile.updatePublicProfile.useMutation(); - - const isSubmitting = form.formState.isSubmitting; - - const onFormSubmit = async ({ url }: TClaimPublicProfileFormSchema) => { - try { - await updatePublicProfile({ - url, - }); - - setClaimed(true); - onClaimed?.(); - } catch (err) { - const error = AppError.parseError(err); - - if (error.code === 'PROFILE_URL_TAKEN') { - form.setError('url', { - type: 'manual', - message: _(msg`This username is already taken`), - }); - } else if (error.code === 'PREMIUM_PROFILE_URL') { - form.setError('url', { - type: 'manual', - message: error.message, - }); - } else if (error.code !== AppErrorCode.UNKNOWN_ERROR) { - toast({ - title: 'An error occurred', - description: error.userMessage ?? error.message, - variant: 'destructive', - }); - } else { - toast({ - title: _(msg`An unknown error occurred`), - description: _( - msg`We encountered an unknown error while attempting to save your details. Please try again later.`, - ), - variant: 'destructive', - }); - } - } - }; - - return ( - - - {!claimed && ( - <> - - - Introducing public profiles! - - - - Reserve your Documenso public profile username - - - - profile claim teaser - -
- -
- ( - - Public profile username - - - - - - - -
- {baseUrl.host}/u/{field.value || ''} -
-
- )} - /> -
- -
- -
-
- - - )} - - {claimed && ( - <> - - All set! - - - We will let you know as soon as this features is launched - - - - - -
- -
- - )} -
-
- ); -}; diff --git a/apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx b/apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx index 23fb8c68e..cf7b96a4c 100644 --- a/apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx +++ b/apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx @@ -8,6 +8,7 @@ import { Link, redirect, useNavigate } from 'react-router'; import { match } from 'ts-pattern'; import { authClient } from '@documenso/auth/client'; +import { useOptionalSession } from '@documenso/lib/client-only/providers/session'; import { EMAIL_VERIFICATION_STATE } from '@documenso/lib/constants/email'; import { Button } from '@documenso/ui/primitives/button'; import { useToast } from '@documenso/ui/primitives/use-toast'; @@ -29,6 +30,7 @@ export const loader = ({ params }: Route.LoaderArgs) => { export default function VerifyEmailPage({ loaderData }: Route.ComponentProps) { const { token } = loaderData; + const { refreshSession } = useOptionalSession(); const { _ } = useLingui(); const { toast } = useToast(); const navigate = useNavigate(); @@ -44,6 +46,8 @@ export default function VerifyEmailPage({ loaderData }: Route.ComponentProps) { token, }); + await refreshSession(); + setState(response.state); } catch (err) { console.error(err); diff --git a/packages/lib/client-only/providers/session.tsx b/packages/lib/client-only/providers/session.tsx index b9ad7862c..be86a040d 100644 --- a/packages/lib/client-only/providers/session.tsx +++ b/packages/lib/client-only/providers/session.tsx @@ -22,7 +22,7 @@ interface SessionProviderProps { interface SessionContextValue { sessionData: AppSession | null; - refresh: () => Promise; + refreshSession: () => Promise; } const SessionContext = createContext(null); @@ -40,7 +40,7 @@ export const useSession = () => { return { ...context.sessionData, - refreshSession: context.refresh, + refreshSession: context.refreshSession, }; }; @@ -102,7 +102,7 @@ export const SessionProvider = ({ children, initialSession }: SessionProviderPro {children}