Browse Source

feat: implement new-match profile viewing page and translation support

front-test-2
ghorbani 4 weeks ago
parent
commit
d6214466a6
  1. 4
      src/app/layout.tsx
  2. 76
      src/app/new-match/profile/page.tsx
  3. 1
      src/translations/locales/en.json

4
src/app/layout.tsx

@ -42,7 +42,7 @@ export default function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return (
<html lang="en">
<html lang="en" suppressHydrationWarning>
<head> <head>
<link rel="preconnect" href="https://habibapp.com" /> <link rel="preconnect" href="https://habibapp.com" />
<link rel="dns-prefetch" href="https://habibapp.com" /> <link rel="dns-prefetch" href="https://habibapp.com" />
@ -161,7 +161,7 @@ export default function RootLayout({
}} }}
/> />
</head> </head>
<body className={`${faminela.variable} ${amiri.variable}`}>
<body className={`${faminela.variable} ${amiri.variable}`} suppressHydrationWarning>
<Providers> <Providers>
<div className="fixed top-3 left-3 z-[9999] pointer-events-auto"> <div className="fixed top-3 left-3 z-[9999] pointer-events-auto">
<TokenSwitcher /> <TokenSwitcher />

76
src/app/new-match/profile/page.tsx

@ -143,6 +143,76 @@ function MatchPublicProfileFields({
); );
} }
function NewMatchProfileSkeleton() {
const { dictionary: t } = useI18n();
return (
<>
<PageBackground />
<main className="-mx-[17px] flex min-h-screen flex-col bg-[linear-gradient(180deg,rgba(255,197,196,0.2)_0%,rgba(251,237,237,0.7)_100%)] pb-10">
<StickyHeader>
<div className="flex items-center justify-between gap-3">
<NavigationButton
variant="transparent"
icon="close"
iconLabel={t.match.goBack}
/>
<h1 className="min-w-0 flex-1 text-center group-16 font-bold text-white">
{t.match.title}
</h1>
<div className="size-10 shrink-0" />
</div>
</StickyHeader>
<section className="px-[17px] pb-32 pt-5">
<div className="flex flex-col items-start">
<div className="size-[90px] rounded-full bg-white/60 animate-pulse shadow-sm" />
<div className="mt-3.5 h-7 w-44 rounded-xl bg-white/70 animate-pulse shadow-xs" />
</div>
<div className="mt-6 space-y-4 rounded-[18px] bg-white/80 p-5 shadow-xs animate-pulse">
<div className="h-4 w-44 rounded-md bg-[#F0445B]/20 border-b border-[#F0445B]/15 pb-2" />
<div className="space-y-4 pt-1">
<div className="space-y-1.5 border-b border-[#000000]/05 pb-3">
<div className="h-3 w-24 rounded bg-gray-200/90" />
<div className="h-4 w-48 rounded bg-gray-300/80" />
</div>
<div className="space-y-1.5 border-b border-[#000000]/05 pb-3">
<div className="h-3 w-28 rounded bg-gray-200/90" />
<div className="h-4 w-36 rounded bg-gray-300/80" />
</div>
<div className="space-y-1.5 border-b border-[#000000]/05 pb-3">
<div className="h-3 w-20 rounded bg-gray-200/90" />
<div className="h-4 w-56 rounded bg-gray-300/80" />
</div>
<div className="space-y-1.5 border-b border-[#000000]/05 pb-3">
<div className="h-3 w-32 rounded bg-gray-200/90" />
<div className="h-4 w-40 rounded bg-gray-300/80" />
</div>
</div>
</div>
</section>
<div
style={{ paddingBottom: `var(--safe-bottom)` }}
className="fixed inset-x-0 bottom-0 z-30 px-[17px]"
>
<div className="mx-auto w-full sm:max-w-[375px] rounded-t-[24px] bg-white px-4 py-4 shadow-[0_12px_30px_rgba(0,0,0,0.14)]">
<div className="flex gap-3">
<div className="w-1/3 h-[46px] rounded-[12px] bg-gray-200/80 animate-pulse" />
<div className="w-2/3 h-[46px] rounded-[12px] bg-[#F0445B]/30 animate-pulse" />
</div>
</div>
</div>
</main>
</>
);
}
export default function NewMatchProfilePage() { export default function NewMatchProfilePage() {
const { dictionary: t, locale } = useI18n(); const { dictionary: t, locale } = useI18n();
const router = useRouter(); const router = useRouter();
@ -151,7 +221,7 @@ export default function NewMatchProfilePage() {
const [isRejectSheetOpen, setIsRejectSheetOpen] = useState(false); const [isRejectSheetOpen, setIsRejectSheetOpen] = useState(false);
const [isDismissReasonSheetOpen, setIsDismissReasonSheetOpen] = const [isDismissReasonSheetOpen, setIsDismissReasonSheetOpen] =
useState(false); useState(false);
const { data: profile, refetch: refetchProfile } = useMarriageProfileQuery();
const { data: profile, isLoading, refetch: refetchProfile } = useMarriageProfileQuery();
useEffect(() => { useEffect(() => {
if (!profile) { if (!profile) {
@ -195,6 +265,10 @@ export default function NewMatchProfilePage() {
return formatFieldValue(firstVal) || "نامشخص"; return formatFieldValue(firstVal) || "نامشخص";
}, [profile?.match_summary?.public_info]); }, [profile?.match_summary?.public_info]);
if (isLoading || !profile) {
return <NewMatchProfileSkeleton />;
}
const isSubmitting = respondMutation.isPending; const isSubmitting = respondMutation.isPending;
const isAcceptProfileEnabled = const isAcceptProfileEnabled =
Boolean(caseId) && Boolean(caseId) &&

1
src/translations/locales/en.json

@ -64,6 +64,7 @@
"match": { "match": {
"title": "New Match", "title": "New Match",
"goBack": "Go back", "goBack": "Go back",
"loadingProfile": "Loading match profile...",
"acceptProfile": "Accept Profile", "acceptProfile": "Accept Profile",
"requestProceedTitle": "Request to Proceed", "requestProceedTitle": "Request to Proceed",
"requestProceedDescription": "With your approval, we will approach their family on your behalf to propose marriage. After their family agrees, you will be introduced to each other for further acquaintance.", "requestProceedDescription": "With your approval, we will approach their family on your behalf to propose marriage. After their family agrees, you will be introduced to each other for further acquaintance.",

Loading…
Cancel
Save