diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx
index c77cb64..9184e11 100644
--- a/src/pages/Dashboard.tsx
+++ b/src/pages/Dashboard.tsx
@@ -4,6 +4,7 @@ import { supabase } from '@/integrations/supabase';
import type { Database } from '@/integrations/supabase/types';
import { useAuth } from '@/hooks/useAuth';
import { useToast } from '@/hooks/use-toast';
+import { useLocalizedDateFormatter } from '@/hooks/useLocalizedDateFormatter';
import { Button } from '@/components/ui/button';
import {
Card,
@@ -26,7 +27,6 @@ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import Loading from '@/components/Loading';
import { AlertTriangle, Loader2, LogOut, RefreshCcw } from 'lucide-react';
import { useTranslation } from 'react-i18next';
-import { getNormalizedLocale } from '@/lib/i18n';
type Profile = Database['public']['Tables']['profiles']['Row'];
type Lead = Database['public']['Tables']['leads']['Row'];
@@ -34,7 +34,7 @@ type NewsletterSubscriber =
Database['public']['Tables']['newsletter_subscribers']['Row'];
const Dashboard = () => {
- const { t, i18n } = useTranslation();
+ const { t } = useTranslation();
const { user, signOut } = useAuth();
const { toast } = useToast();
const navigate = useNavigate();
@@ -149,45 +149,12 @@ const Dashboard = () => {
void loadDashboard();
}, [loadDashboard]);
- const normalizedLocale = useMemo(
- () => getNormalizedLocale(i18n.language),
- [i18n.language]
- );
-
- const fallbackDateFormatter = useMemo(
- () =>
- new Intl.DateTimeFormat('en-US', {
- dateStyle: 'short',
- timeStyle: 'short',
- }),
- []
- );
-
- const dateTimeFormatter = useMemo(() => {
- try {
- return new Intl.DateTimeFormat(normalizedLocale, {
- dateStyle: 'short',
- timeStyle: 'short',
- });
- } catch (error) {
- console.error('Unsupported locale for dashboard date formatting', error);
- return fallbackDateFormatter;
- }
- }, [fallbackDateFormatter, normalizedLocale]);
-
- const formatDate = useCallback(
- (value: string | null | undefined) => {
- if (!value) return '—';
-
- try {
- return dateTimeFormatter.format(new Date(value));
- } catch (error) {
- console.error('Error formatting dashboard date', error);
- return fallbackDateFormatter.format(new Date(value));
- }
+ const { formatDate } = useLocalizedDateFormatter({
+ dateOptions: {
+ dateStyle: 'short',
+ timeStyle: 'short',
},
- [dateTimeFormatter, fallbackDateFormatter]
- );
+ });
const handleRefresh = () => {
void loadDashboard();
diff --git a/src/pages/Projects.tsx b/src/pages/Projects.tsx
index 1c3de55..92c788f 100644
--- a/src/pages/Projects.tsx
+++ b/src/pages/Projects.tsx
@@ -1,4 +1,4 @@
-import { useMemo, useCallback } from 'react';
+import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { Github, ExternalLink, Calendar, ArrowRight } from 'lucide-react';
import Layout from '../components/Layout';
@@ -6,18 +6,12 @@ import Meta from '@/components/Meta';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
-import {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
-} from '@/components/ui/breadcrumb';
+import { PageBreadcrumb } from '@/components/PageBreadcrumb';
import { supabase } from '@/integrations/supabase';
import { useTranslation, Trans } from 'react-i18next';
import { Link } from 'react-router-dom';
import useRepositorySync from '@/hooks/useRepositorySync';
+import { useLocalizedDateFormatter } from '@/hooks/useLocalizedDateFormatter';
import {
fetchSupabaseSolutions,
getFallbackSolutions,
@@ -25,7 +19,6 @@ import {
} from '@/lib/solutions';
import type { GitHubRepository } from '@/lib/solutions';
import type { SolutionContent } from '@/types/solutions';
-import { getNormalizedLocale } from '@/lib/i18n';
import { SolutionCard, sectionContainer, sectionPaddingY } from '@monynha/ui';
import { cn } from '@/lib/utils';
@@ -43,50 +36,18 @@ const GITHUB_REPOS_URL =
'https://api.github.com/orgs/Monynha-Softwares/repos?per_page=100';
const Projects = () => {
- const { t, i18n } = useTranslation();
+ const { t } = useTranslation();
useRepositorySync();
const memoizedFallbackSolutions = useMemo(() => getFallbackSolutions(), []);
- const normalizedLocale = useMemo(
- () => getNormalizedLocale(i18n.language),
- [i18n.language]
- );
-
- const fallbackDateFormatter = useMemo(
- () =>
- new Intl.DateTimeFormat('en-US', {
- year: 'numeric',
- month: 'short',
- day: 'numeric',
- }),
- []
- );
-
- const dateFormatter = useMemo(() => {
- try {
- return new Intl.DateTimeFormat(normalizedLocale, {
- year: 'numeric',
- month: 'short',
- day: 'numeric',
- });
- } catch (error) {
- console.error('Unsupported locale for project date formatting', error);
- return fallbackDateFormatter;
- }
- }, [fallbackDateFormatter, normalizedLocale]);
-
- const formatDate = useCallback(
- (dateString: string) => {
- try {
- return dateFormatter.format(new Date(dateString));
- } catch (error) {
- console.error('Error formatting project date', error);
- return fallbackDateFormatter.format(new Date(dateString));
- }
+ const { formatDate } = useLocalizedDateFormatter({
+ dateOptions: {
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric',
},
- [dateFormatter, fallbackDateFormatter]
- );
+ });
const {
data: repositories = [],
@@ -251,21 +212,7 @@ const Projects = () => {
ogDescription={t('projects.description')}
ogImage="/placeholder.svg"
/>
-
-
-
-
-
- {t('navigation.home')}
-
-
-
-
- {t('navigation.projects')}
-
-
-
-
+
diff --git a/src/pages/Solutions.tsx b/src/pages/Solutions.tsx
index ce173c0..f4f3eef 100644
--- a/src/pages/Solutions.tsx
+++ b/src/pages/Solutions.tsx
@@ -3,15 +3,8 @@ import { useQuery } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import Layout from '@/components/Layout';
import Meta from '@/components/Meta';
+import { PageBreadcrumb } from '@/components/PageBreadcrumb';
import { Link } from 'react-router-dom';
-import {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
-} from '@/components/ui/breadcrumb';
import { ArrowRight } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { supabase } from '@/integrations/supabase';
@@ -102,21 +95,7 @@ const Solutions = () => {
ogDescription={t('solutionsPage.description')}
ogImage="/placeholder.svg"
/>
-
-
-
-
-
- {t('navigation.home')}
-
-
-
-
- {t('navigation.solutions')}
-
-
-
-
+
{/* Hero Section */}
diff --git a/src/pages/blog/[slug].tsx b/src/pages/blog/[slug].tsx
index 42a3727..9c4c274 100644
--- a/src/pages/blog/[slug].tsx
+++ b/src/pages/blog/[slug].tsx
@@ -8,7 +8,7 @@ import Meta from '@/components/Meta';
import NewsletterSection from '@/components/NewsletterSection';
import CommentsSection from '@/components/blog/CommentsSection';
import { supabase } from '@/integrations/supabase';
-import { getNormalizedLocale } from '@/lib/i18n';
+import { useLocalizedDateFormatter } from '@/hooks/useLocalizedDateFormatter';
import type { Database } from '@/integrations/supabase/types';
import {
Breadcrumb,
@@ -227,23 +227,11 @@ const renderBlogContent = (content: string): ReactNode[] => {
const BlogPostPage = () => {
const { slug } = useParams<{ slug: string }>();
- const { t, i18n } = useTranslation();
-
- const normalizedLocale = useMemo(
- () => getNormalizedLocale(i18n.language),
- [i18n.language]
- );
+ const { t } = useTranslation();
- const dateFormatter = useMemo(() => {
- try {
- return new Intl.DateTimeFormat(normalizedLocale, {
- dateStyle: 'long',
- });
- } catch (error) {
- console.error('Unsupported locale for blog post date formatting', error);
- return new Intl.DateTimeFormat('en-US', { dateStyle: 'long' });
- }
- }, [normalizedLocale]);
+ const { formatDate } = useLocalizedDateFormatter({
+ dateOptions: { dateStyle: 'long' },
+ });
const {
data: post,
@@ -279,9 +267,7 @@ const BlogPostPage = () => {
[post?.content]
);
- const updatedDate = post
- ? dateFormatter.format(new Date(post.updated_at))
- : '';
+ const updatedDate = post ? formatDate(post.updated_at) : '';
const fallbackMetaTitle = t('blog.metaTitle');
const metaTitle = post