From 8b6abe24bc177ed43975f1a9da4b41ee25355f3d Mon Sep 17 00:00:00 2001 From: TheoForger Date: Thu, 27 Nov 2025 21:18:59 -0500 Subject: [PATCH] use client side rendering for local dates --- .../certificate/certificate-available.tsx | 12 +++---- app/components/certificate/description.tsx | 36 +++++++++++++++---- app/routes/_auth.certificate._index.tsx | 14 ++------ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/components/certificate/certificate-available.tsx b/app/components/certificate/certificate-available.tsx index 9c8f0887..b088fc86 100644 --- a/app/components/certificate/certificate-available.tsx +++ b/app/components/certificate/certificate-available.tsx @@ -21,14 +21,14 @@ import type { CertificateWithFullChain } from '~/models/certificate.server'; interface CertificateAvailableProps { certificate: CertificateWithFullChain; - validFromFormatted: string; - validToFormatted: string; + validFromISO: string; + validToISO: string; } export default function CertificateAvailable({ certificate, - validFromFormatted, - validToFormatted, + validFromISO, + validToISO, }: CertificateAvailableProps) { const isRenewable = useMemo((): boolean => { if (certificate.validTo) { @@ -44,8 +44,8 @@ export default function CertificateAvailable({ diff --git a/app/components/certificate/description.tsx b/app/components/certificate/description.tsx index f71cd4ff..354d29d3 100644 --- a/app/components/certificate/description.tsx +++ b/app/components/certificate/description.tsx @@ -1,5 +1,6 @@ import { RepeatIcon, DeleteIcon } from '@chakra-ui/icons'; import { Form, Link as RemixLink } from '@remix-run/react'; +import { useEffect, useState } from 'react'; import { Flex, Text, @@ -15,8 +16,8 @@ import { interface DescriptionSectionProps { certRequested: boolean; - validFromFormatted?: string; - validToFormatted?: string; + validFromISO?: string; + validToISO?: string; description: string; isRenewable?: boolean; link?: string; @@ -24,8 +25,8 @@ interface DescriptionSectionProps { export default function DescriptionSection({ certRequested, - validFromFormatted, - validToFormatted, + validFromISO, + validToISO, description, isRenewable, link, @@ -45,15 +46,19 @@ export default function DescriptionSection({ )} - {certRequested && !!validFromFormatted && !!validToFormatted && ( + {certRequested && !!validFromISO && !!validToISO && ( Created On - {validFromFormatted} + + + Expires On - {validToFormatted} + + + @@ -87,3 +92,20 @@ export default function DescriptionSection({ ); } + +function LocalDate({ iso }: { iso: string }) { + const [formatted, setFormatted] = useState(''); + + useEffect(() => { + const date = new Date(iso); + setFormatted( + date.toLocaleDateString('en-CA', { + month: 'short', + day: '2-digit', + year: 'numeric', + }) + ); + }, [iso]); + + return ; +} diff --git a/app/routes/_auth.certificate._index.tsx b/app/routes/_auth.certificate._index.tsx index ff47cf87..267d3ebb 100644 --- a/app/routes/_auth.certificate._index.tsx +++ b/app/routes/_auth.certificate._index.tsx @@ -77,16 +77,6 @@ export const action = async ({ request }: ActionFunctionArgs) => { }); }; -function formatDate(val: Date): string { - const date = val.toLocaleDateString('en-US', { - month: 'short', - day: '2-digit', - year: 'numeric', - }); - - return date; -} - function mapStatusToErrorText(statusCode: number): string { switch (statusCode) { case 404: @@ -140,8 +130,8 @@ export default function CertificateIndexRoute() { {certificate?.status === 'issued' ? ( ) : (