@djangocfg/layouts 2.1.42 → 2.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/package.json +7 -6
  2. package/src/components/RedirectPage/RedirectPage.tsx +2 -1
  3. package/src/components/core/ClientOnly.tsx +2 -1
  4. package/src/components/core/LucideIcon.tsx +3 -2
  5. package/src/components/core/Suspense.tsx +1 -1
  6. package/src/components/errors/ErrorBoundary.tsx +1 -1
  7. package/src/components/errors/ErrorLayout.tsx +2 -0
  8. package/src/components/errors/ErrorsTracker/components/ErrorButtons.tsx +6 -6
  9. package/src/components/errors/ErrorsTracker/components/ErrorToast.tsx +4 -3
  10. package/src/components/errors/ErrorsTracker/providers/ErrorTrackingProvider.tsx +10 -9
  11. package/src/layouts/AdminLayout/AdminLayout.tsx +2 -1
  12. package/src/layouts/AppLayout/AppLayout.tsx +4 -2
  13. package/src/layouts/AppLayout/BaseApp.tsx +10 -7
  14. package/src/layouts/AuthLayout/AuthHelp.tsx +1 -1
  15. package/src/layouts/AuthLayout/AuthLayout.tsx +2 -2
  16. package/src/layouts/AuthLayout/IdentifierForm.tsx +4 -16
  17. package/src/layouts/AuthLayout/OAuthCallback.tsx +5 -4
  18. package/src/layouts/AuthLayout/OAuthProviders.tsx +2 -2
  19. package/src/layouts/AuthLayout/OTPForm.tsx +3 -9
  20. package/src/layouts/PrivateLayout/PrivateLayout.tsx +7 -3
  21. package/src/layouts/PrivateLayout/components/PrivateContent.tsx +1 -0
  22. package/src/layouts/PrivateLayout/components/PrivateHeader.tsx +6 -7
  23. package/src/layouts/PrivateLayout/components/PrivateSidebar.tsx +6 -12
  24. package/src/layouts/ProfileLayout/ProfileLayout.tsx +4 -13
  25. package/src/layouts/ProfileLayout/components/AvatarSection.tsx +7 -3
  26. package/src/layouts/ProfileLayout/components/ProfileForm.tsx +8 -18
  27. package/src/layouts/PublicLayout/PublicLayout.tsx +4 -6
  28. package/src/layouts/PublicLayout/components/PublicFooter/FooterBottom.tsx +3 -1
  29. package/src/layouts/PublicLayout/components/PublicFooter/FooterMenuSections.tsx +2 -1
  30. package/src/layouts/PublicLayout/components/PublicFooter/FooterProjectInfo.tsx +3 -1
  31. package/src/layouts/PublicLayout/components/PublicFooter/FooterSocialLinks.tsx +3 -10
  32. package/src/layouts/PublicLayout/components/PublicFooter/PublicFooter.tsx +6 -3
  33. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +7 -9
  34. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +8 -5
  35. package/src/layouts/_components/UserMenu.tsx +8 -14
  36. package/src/pages/legal/LegalPage.tsx +3 -6
  37. package/src/pages/legal/pages.tsx +2 -6
  38. package/src/snippets/Analytics/AnalyticsProvider.tsx +1 -0
  39. package/src/snippets/Analytics/useAnalytics.ts +2 -1
  40. package/src/snippets/AuthDialog/AuthDialog.tsx +2 -6
  41. package/src/snippets/AuthDialog/useAuthDialog.ts +2 -1
  42. package/src/snippets/Breadcrumbs.tsx +4 -4
  43. package/src/snippets/McpChat/components/AIChatWidget.tsx +8 -4
  44. package/src/snippets/McpChat/components/AskAIButton.tsx +4 -1
  45. package/src/snippets/McpChat/components/ChatMessages.tsx +5 -2
  46. package/src/snippets/McpChat/components/ChatPanel.tsx +5 -3
  47. package/src/snippets/McpChat/components/ChatSidebar.tsx +5 -3
  48. package/src/snippets/McpChat/components/ChatWidget.tsx +6 -3
  49. package/src/snippets/McpChat/components/MessageBubble.tsx +6 -2
  50. package/src/snippets/McpChat/components/MessageInput.tsx +3 -2
  51. package/src/snippets/McpChat/context/AIChatContext.tsx +7 -3
  52. package/src/snippets/McpChat/context/ChatContext.tsx +7 -3
  53. package/src/snippets/McpChat/hooks/useAIChat.ts +5 -2
  54. package/src/snippets/McpChat/hooks/useChatLayout.ts +5 -3
  55. package/src/snippets/McpChat/hooks/useMcpChat.ts +1 -0
  56. package/src/snippets/PWAInstall/components/A2HSHint.tsx +6 -5
  57. package/src/snippets/PWAInstall/components/DesktopGuide.tsx +4 -11
  58. package/src/snippets/PWAInstall/components/IOSGuide.tsx +1 -1
  59. package/src/snippets/PWAInstall/components/IOSGuideDrawer.tsx +2 -9
  60. package/src/snippets/PWAInstall/components/IOSGuideModal.tsx +3 -10
  61. package/src/snippets/PWAInstall/context/InstallContext.tsx +2 -2
  62. package/src/snippets/PWAInstall/hooks/useInstallPrompt.ts +3 -2
  63. package/src/snippets/PWAInstall/hooks/useIsPWA.ts +2 -1
  64. package/src/snippets/PushNotifications/components/PushPrompt.tsx +5 -3
  65. package/src/snippets/PushNotifications/context/DjangoPushContext.tsx +3 -1
  66. package/src/snippets/PushNotifications/hooks/useDjangoPush.ts +7 -6
  67. package/src/snippets/PushNotifications/hooks/usePushNotifications.ts +3 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/layouts",
3
- "version": "2.1.42",
3
+ "version": "2.1.44",
4
4
  "description": "Simple, straightforward layout components for Next.js - import and use with props",
5
5
  "keywords": [
6
6
  "layouts",
@@ -92,9 +92,9 @@
92
92
  "check": "tsc --noEmit"
93
93
  },
94
94
  "peerDependencies": {
95
- "@djangocfg/api": "^2.1.42",
96
- "@djangocfg/centrifugo": "^2.1.42",
97
- "@djangocfg/ui-nextjs": "^2.1.42",
95
+ "@djangocfg/api": "^2.1.44",
96
+ "@djangocfg/centrifugo": "^2.1.44",
97
+ "@djangocfg/ui-nextjs": "^2.1.44",
98
98
  "@hookform/resolvers": "^5.2.0",
99
99
  "consola": "^3.4.2",
100
100
  "lucide-react": "^0.545.0",
@@ -107,14 +107,15 @@
107
107
  "swr": "^2.3.7",
108
108
  "tailwindcss": "^4.1.14",
109
109
  "tailwindcss-animate": "^1.0.7",
110
- "zod": "^4.1.13"
110
+ "zod": "^4.1.13",
111
+ "moment": "^2.30.1"
111
112
  },
112
113
  "dependencies": {
113
114
  "react-ga4": "^2.1.0",
114
115
  "uuid": "^11.1.0"
115
116
  },
116
117
  "devDependencies": {
117
- "@djangocfg/typescript-config": "^2.1.42",
118
+ "@djangocfg/typescript-config": "^2.1.44",
118
119
  "@types/node": "^24.7.2",
119
120
  "@types/react": "^19.1.0",
120
121
  "@types/react-dom": "^19.1.0",
@@ -1,9 +1,10 @@
1
1
  'use client';
2
2
 
3
3
  import { useEffect } from 'react';
4
+
4
5
  import { useAuth } from '@djangocfg/api/auth';
5
- import { useCfgRouter } from '@djangocfg/ui-nextjs/hooks';
6
6
  import { Preloader } from '@djangocfg/ui-nextjs/components';
7
+ import { useCfgRouter } from '@djangocfg/ui-nextjs/hooks';
7
8
 
8
9
  export interface RedirectPageProps {
9
10
  /**
@@ -22,7 +22,8 @@
22
22
 
23
23
  'use client';
24
24
 
25
- import { useState, useEffect, ReactNode } from 'react';
25
+ import { ReactNode, useEffect, useState } from 'react';
26
+
26
27
  import { Preloader } from '@djangocfg/ui-nextjs/components';
27
28
 
28
29
  export interface ClientOnlyProps {
@@ -17,11 +17,12 @@
17
17
 
18
18
  'use client';
19
19
 
20
- import React from 'react';
21
20
  import * as LucideIcons from 'lucide-react';
22
- import type { LucideIcon as LucideIconType } from 'lucide-react';
21
+ import React from 'react';
22
+
23
23
  import { cn } from '@djangocfg/ui-nextjs';
24
24
 
25
+ import type { LucideIcon as LucideIconType } from 'lucide-react';
25
26
  export interface LucideIconProps extends Omit<React.SVGProps<SVGSVGElement>, 'children'> {
26
27
  /**
27
28
  * Icon name (string) or icon component (LucideIcon)
@@ -7,7 +7,7 @@
7
7
 
8
8
  'use client';
9
9
 
10
- import { Suspense as ReactSuspense, ReactNode } from 'react';
10
+ import { ReactNode, Suspense as ReactSuspense } from 'react';
11
11
 
12
12
  interface SuspenseProps {
13
13
  children: ReactNode;
@@ -6,7 +6,7 @@
6
6
 
7
7
  'use client';
8
8
 
9
- import React, { Component, ReactNode, ErrorInfo } from 'react';
9
+ import React, { Component, ErrorInfo, ReactNode } from 'react';
10
10
 
11
11
  interface ErrorBoundaryProps {
12
12
  children: ReactNode;
@@ -18,7 +18,9 @@
18
18
  'use client';
19
19
 
20
20
  import React from 'react';
21
+
21
22
  import { Button } from '@djangocfg/ui-nextjs/components';
23
+
22
24
  import { getErrorContent } from './errorConfig';
23
25
 
24
26
  export interface ErrorLayoutProps {
@@ -6,17 +6,17 @@
6
6
 
7
7
  'use client';
8
8
 
9
+ import { Copy, Terminal } from 'lucide-react';
9
10
  import React from 'react';
11
+
10
12
  import { Button, useCopy } from '@djangocfg/ui-nextjs';
11
- import { Copy, Terminal } from 'lucide-react';
12
- import type { ValidationErrorDetail, CORSErrorDetail, NetworkErrorDetail } from '../types';
13
+
14
+ import { generateCurlFromError } from '../utils/curl-generator';
13
15
  import {
14
- formatValidationErrorForClipboard,
15
- formatCORSErrorForClipboard,
16
- formatNetworkErrorForClipboard,
16
+ formatCORSErrorForClipboard, formatNetworkErrorForClipboard, formatValidationErrorForClipboard
17
17
  } from '../utils/formatters';
18
- import { generateCurlFromError } from '../utils/curl-generator';
19
18
 
19
+ import type { ValidationErrorDetail, CORSErrorDetail, NetworkErrorDetail } from '../types';
20
20
  export interface ErrorButtonsProps {
21
21
  detail: ValidationErrorDetail | CORSErrorDetail | NetworkErrorDetail;
22
22
  }
@@ -7,6 +7,10 @@
7
7
  'use client';
8
8
 
9
9
  import React from 'react';
10
+
11
+ import { extractDomain, formatErrorTitle, formatZodIssues } from '../utils/formatters';
12
+ import { ErrorButtons } from './ErrorButtons';
13
+
10
14
  import type {
11
15
  ValidationErrorDetail,
12
16
  CORSErrorDetail,
@@ -15,9 +19,6 @@ import type {
15
19
  CORSErrorConfig,
16
20
  NetworkErrorConfig,
17
21
  } from '../types';
18
- import { formatZodIssues, formatErrorTitle, extractDomain } from '../utils/formatters';
19
- import { ErrorButtons } from './ErrorButtons';
20
-
21
22
  /**
22
23
  * Build validation error description
23
24
  */
@@ -26,8 +26,17 @@
26
26
 
27
27
  'use client';
28
28
 
29
- import React, { createContext, useContext, useCallback, useEffect, useState, ReactNode } from 'react';
29
+ import React, {
30
+ createContext, ReactNode, useCallback, useContext, useEffect, useState
31
+ } from 'react';
32
+
30
33
  import { toast } from '@djangocfg/ui-nextjs';
34
+
35
+ import { createErrorToast } from '../components/ErrorToast';
36
+ import {
37
+ DEFAULT_CORS_CONFIG, DEFAULT_NETWORK_CONFIG, DEFAULT_VALIDATION_CONFIG, ERROR_EVENTS
38
+ } from '../types';
39
+
31
40
  import type {
32
41
  ErrorDetail,
33
42
  StoredError,
@@ -40,14 +49,6 @@ import type {
40
49
  NetworkErrorDetail,
41
50
  ErrorTrackingContextValue,
42
51
  } from '../types';
43
- import {
44
- DEFAULT_VALIDATION_CONFIG,
45
- DEFAULT_CORS_CONFIG,
46
- DEFAULT_NETWORK_CONFIG,
47
- ERROR_EVENTS,
48
- } from '../types';
49
- import { createErrorToast } from '../components/ErrorToast';
50
-
51
52
  const ErrorTrackingContext = createContext<ErrorTrackingContextValue | undefined>(undefined);
52
53
 
53
54
  /**
@@ -37,7 +37,8 @@
37
37
  'use client';
38
38
 
39
39
  import { ReactNode } from 'react';
40
- import { PrivateLayout, type PrivateLayoutProps } from '../PrivateLayout/PrivateLayout';
40
+
41
+ import { PrivateLayout, PrivateLayoutProps} from '../PrivateLayout/PrivateLayout';
41
42
 
42
43
  export interface AdminLayoutProps extends PrivateLayoutProps {
43
44
  children: ReactNode;
@@ -32,10 +32,12 @@
32
32
 
33
33
  'use client';
34
34
 
35
- import React, { ReactNode, useMemo } from 'react';
36
35
  import { usePathname } from 'next/navigation';
37
- import { Suspense, ClientOnly } from '../../components/core';
36
+ import React, { ReactNode, useMemo } from 'react';
37
+
38
+ import { ClientOnly, Suspense } from '../../components/core';
38
39
  import { BaseApp } from './BaseApp';
40
+
39
41
  import type {
40
42
  ThemeConfig,
41
43
  AnalyticsConfig,
@@ -44,20 +44,23 @@
44
44
 
45
45
  'use client';
46
46
 
47
- import { ReactNode } from 'react';
48
47
  import dynamic from 'next/dynamic';
48
+ import { ReactNode } from 'react';
49
49
  import { SWRConfig } from 'swr';
50
- import { ThemeProvider, SonnerToaster, TooltipProvider } from '@djangocfg/ui-nextjs';
50
+
51
+ import { getCentrifugoAuthTokenRetrieve } from '@djangocfg/api';
51
52
  import { AuthProvider } from '@djangocfg/api/auth';
52
53
  import { CentrifugoProvider } from '@djangocfg/centrifugo';
53
- import { getCentrifugoAuthTokenRetrieve } from '@djangocfg/api';
54
- import { ErrorTrackingProvider } from '../../components/errors/ErrorsTracker';
55
- import { ErrorBoundary } from '../../components/errors/ErrorBoundary';
54
+ import { SonnerToaster, ThemeProvider, TooltipProvider } from '@djangocfg/ui-nextjs';
55
+
56
56
  import { PageProgress } from '../../components/core/PageProgress';
57
+ import { ErrorBoundary } from '../../components/errors/ErrorBoundary';
58
+ import { ErrorTrackingProvider } from '../../components/errors/ErrorsTracker';
57
59
  import { AnalyticsProvider } from '../../snippets/Analytics';
58
- import { PwaProvider, A2HSHint } from '../../snippets/PWAInstall';
59
- import { DjangoPushProvider, PushPrompt } from '../../snippets/PushNotifications';
60
60
  import { AuthDialog } from '../../snippets/AuthDialog';
61
+ import { DjangoPushProvider, PushPrompt } from '../../snippets/PushNotifications';
62
+ import { A2HSHint, PwaProvider } from '../../snippets/PWAInstall';
63
+
61
64
  import type { BaseLayoutProps } from '../types/layout.types';
62
65
 
63
66
  // Lazy load MCP Chat Widget with dynamic import
@@ -1,4 +1,4 @@
1
- import { Mail, MessageCircle, HelpCircle } from 'lucide-react';
1
+ import { HelpCircle, Mail, MessageCircle } from 'lucide-react';
2
2
  import React from 'react';
3
3
 
4
4
  import { Button } from '@djangocfg/ui-nextjs/components';
@@ -27,11 +27,11 @@
27
27
 
28
28
  import React from 'react';
29
29
 
30
+ import { Suspense } from '../../components';
30
31
  import { AuthProvider, useAuthContext } from './AuthContext';
31
32
  import { IdentifierForm } from './IdentifierForm';
32
- import { OTPForm } from './OTPForm';
33
33
  import { OAuthCallback } from './OAuthCallback';
34
- import { Suspense } from '../../components';
34
+ import { OTPForm } from './OTPForm';
35
35
 
36
36
  import type { AuthProps } from './types';
37
37
 
@@ -1,23 +1,11 @@
1
1
  'use client';
2
2
 
3
- import React, { useState, useEffect } from 'react';
4
- import { Mail, Phone, User, Send } from 'lucide-react';
3
+ import { Mail, Phone, Send, User } from 'lucide-react';
4
+ import React, { useEffect, useState } from 'react';
5
5
 
6
6
  import {
7
- Button,
8
- Card,
9
- CardContent,
10
- CardDescription,
11
- CardHeader,
12
- CardTitle,
13
- Checkbox,
14
- Input,
15
- Label,
16
- Tabs,
17
- TabsContent,
18
- TabsList,
19
- TabsTrigger,
20
- PhoneInput,
7
+ Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, Label,
8
+ PhoneInput, Tabs, TabsContent, TabsList, TabsTrigger
21
9
  } from '@djangocfg/ui-nextjs/components';
22
10
 
23
11
  import { useAuthContext } from './AuthContext';
@@ -1,12 +1,13 @@
1
1
  'use client';
2
2
 
3
- import React, { useEffect, useState } from 'react';
3
+ import { AlertCircle, CheckCircle, Loader2 } from 'lucide-react';
4
4
  import { useSearchParams } from 'next/navigation';
5
- import { Loader2, AlertCircle, CheckCircle } from 'lucide-react';
6
-
7
- import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@djangocfg/ui-nextjs/components';
5
+ import React, { useEffect, useState } from 'react';
8
6
 
9
7
  import { useGithubAuth } from '@djangocfg/api/auth';
8
+ import {
9
+ Card, CardContent, CardDescription, CardHeader, CardTitle
10
+ } from '@djangocfg/ui-nextjs/components';
10
11
 
11
12
  export interface OAuthCallbackProps {
12
13
  onSuccess?: (user: any, isNewUser: boolean, provider: string) => void;
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
 
3
- import React from 'react';
4
3
  import { Github, Loader2 } from 'lucide-react';
4
+ import React from 'react';
5
5
 
6
+ import { useGithubAuth } from '@djangocfg/api/auth';
6
7
  import { Button } from '@djangocfg/ui-nextjs/components';
7
8
 
8
- import { useGithubAuth } from '@djangocfg/api/auth';
9
9
  import { useAuthContext } from './AuthContext';
10
10
 
11
11
  /**
@@ -1,21 +1,15 @@
1
1
  'use client';
2
2
 
3
+ import { ArrowLeft, Mail, MessageCircle, RotateCw, ShieldCheck } from 'lucide-react';
3
4
  import React from 'react';
4
- import { Mail, MessageCircle, ArrowLeft, RotateCw, ShieldCheck } from 'lucide-react';
5
5
 
6
6
  import {
7
- Button,
8
- Card,
9
- CardContent,
10
- CardDescription,
11
- CardHeader,
12
- CardTitle,
13
- OTPInput,
7
+ Button, Card, CardContent, CardDescription, CardHeader, CardTitle, OTPInput
14
8
  } from '@djangocfg/ui-nextjs/components';
15
9
 
10
+ import { config } from '../../utils';
16
11
  import { useAuthContext } from './AuthContext';
17
12
  import { AuthHelp } from './AuthHelp';
18
- import { config } from '../../utils';
19
13
 
20
14
  export const OTPForm: React.FC = () => {
21
15
  const {
@@ -47,12 +47,16 @@
47
47
  'use client';
48
48
 
49
49
  import React, { ReactNode } from 'react';
50
- import { SidebarProvider, SidebarInset, Preloader, ButtonLink } from '@djangocfg/ui-nextjs/components';
50
+
51
51
  import { useAuth } from '@djangocfg/api/auth';
52
- import { PrivateSidebar, PrivateHeader, PrivateContent } from './components';
53
- import type { LucideIcon as LucideIconType } from 'lucide-react';
52
+ import {
53
+ ButtonLink, Preloader, SidebarInset, SidebarProvider
54
+ } from '@djangocfg/ui-nextjs/components';
55
+
54
56
  import { UserMenuConfig } from '../types';
57
+ import { PrivateContent, PrivateHeader, PrivateSidebar } from './components';
55
58
 
59
+ import type { LucideIcon as LucideIconType } from 'lucide-react';
56
60
  export interface SidebarItem {
57
61
  label: string;
58
62
  href: string;
@@ -7,6 +7,7 @@
7
7
  'use client';
8
8
 
9
9
  import React, { ReactNode } from 'react';
10
+
10
11
  import { cn } from '@djangocfg/ui-nextjs/lib';
11
12
 
12
13
  interface PrivateContentProps {
@@ -6,16 +6,15 @@
6
6
 
7
7
  'use client';
8
8
 
9
- import React from 'react';
10
9
  import Link from 'next/link';
11
- import {
12
- Button,
13
- Separator,
14
- SidebarTrigger,
15
- } from '@djangocfg/ui-nextjs/components';
16
- import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
10
+ import React from 'react';
11
+
17
12
  import { useAuth } from '@djangocfg/api/auth';
13
+ import { Button, Separator, SidebarTrigger } from '@djangocfg/ui-nextjs/components';
14
+ import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
15
+
18
16
  import { UserMenu } from '../../_components/UserMenu';
17
+
19
18
  import type { HeaderConfig } from '../PrivateLayout';
20
19
 
21
20
  interface PrivateHeaderProps {
@@ -6,24 +6,18 @@
6
6
 
7
7
  'use client';
8
8
 
9
- import React from 'react';
10
9
  import Link from 'next/link';
11
10
  import { usePathname } from 'next/navigation';
11
+ import React from 'react';
12
+
12
13
  import {
13
- Sidebar,
14
- SidebarContent,
15
- SidebarGroup,
16
- SidebarGroupContent,
17
- SidebarGroupLabel,
18
- SidebarHeader,
19
- SidebarMenu,
20
- SidebarMenuBadge,
21
- SidebarMenuButton,
22
- SidebarMenuItem,
23
- useSidebar,
14
+ Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader,
15
+ SidebarMenu, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, useSidebar
24
16
  } from '@djangocfg/ui-nextjs/components';
25
17
  import { cn } from '@djangocfg/ui-nextjs/lib';
18
+
26
19
  import { LucideIcon } from '../../../components';
20
+
27
21
  import type { SidebarItem, SidebarConfig } from '../PrivateLayout';
28
22
 
29
23
  interface PrivateSidebarProps {
@@ -2,17 +2,12 @@
2
2
  'use client';
3
3
 
4
4
  import React from 'react';
5
+ import moment from 'moment';
5
6
 
7
+ import { AccountsProvider, useAuth } from '@djangocfg/api/auth';
6
8
  import {
7
- Card,
8
- CardContent,
9
- CardDescription,
10
- CardHeader,
11
- CardTitle,
12
- Preloader,
9
+ Card, CardContent, CardDescription, CardHeader, CardTitle, Preloader
13
10
  } from '@djangocfg/ui-nextjs/components';
14
- import { AccountsProvider } from '@djangocfg/api/auth';
15
- import { useAuth } from '@djangocfg/api/auth';
16
11
 
17
12
  import { AvatarSection, ProfileForm } from './components';
18
13
 
@@ -37,11 +32,7 @@ const ProfileContent = ({
37
32
  const { user, isLoading } = useAuth();
38
33
 
39
34
  const formatDate = (dateString: string) => {
40
- return new Date(dateString).toLocaleDateString('en-US', {
41
- year: 'numeric',
42
- month: 'long',
43
- day: 'numeric',
44
- });
35
+ return moment.utc(dateString).local().format('MMMM D, YYYY');
45
36
  };
46
37
 
47
38
  React.useEffect(() => {
@@ -4,9 +4,9 @@ import { Check, Upload, X } from 'lucide-react';
4
4
  import React, { useState } from 'react';
5
5
  import { toast } from 'sonner';
6
6
 
7
+ import { useAccountsContext, useAuth } from '@djangocfg/api/auth';
7
8
  import { Avatar, AvatarFallback, Button } from '@djangocfg/ui-nextjs/components';
8
- import { useAccountsContext } from '@djangocfg/api/auth';
9
- import { useAuth } from '@djangocfg/api/auth';
9
+
10
10
  import { profileLogger } from '../../../utils/logger';
11
11
 
12
12
  export const AvatarSection = () => {
@@ -26,6 +26,10 @@ export const AvatarSection = () => {
26
26
  .slice(0, 2);
27
27
  };
28
28
 
29
+ const formatFileSize = (bytes: number) => {
30
+ return (bytes / 1024 / 1024).toFixed(2);
31
+ };
32
+
29
33
  const handleAvatarChange = (event: React.ChangeEvent<HTMLInputElement>) => {
30
34
  const file = event.target.files?.[0];
31
35
  if (file) {
@@ -142,7 +146,7 @@ export const AvatarSection = () => {
142
146
  {avatarFile && (
143
147
  <div className="mt-3 text-center">
144
148
  <p className="text-xs text-muted-foreground">
145
- {avatarFile.name} ({(avatarFile.size / 1024 / 1024).toFixed(2)} MB)
149
+ {avatarFile.name} ({formatFileSize(avatarFile.size)} MB)
146
150
  </p>
147
151
  </div>
148
152
  )}
@@ -3,28 +3,18 @@
3
3
 
4
4
  import React, { useEffect, useState } from 'react';
5
5
  import { useForm } from 'react-hook-form';
6
- import { zodResolver } from '@hookform/resolvers/zod';
7
6
  import { toast } from 'sonner';
8
- import { profileLogger } from '../../../utils/logger';
9
7
 
10
8
  import {
11
- Button,
12
- Form,
13
- FormControl,
14
- FormField,
15
- FormItem,
16
- FormLabel,
17
- FormMessage,
18
- Input,
19
- Label,
20
- PhoneInput,
21
- } from '@djangocfg/ui-nextjs/components';
22
- import {
23
- useAccountsContext,
24
- PatchedUserProfileUpdateRequestSchema,
25
- type PatchedUserProfileUpdateRequest
9
+ PatchedUserProfileUpdateRequest, PatchedUserProfileUpdateRequestSchema, type
10
+ useAccountsContext, useAuth
26
11
  } from '@djangocfg/api/auth';
27
- import { useAuth } from '@djangocfg/api/auth';
12
+ import {
13
+ Button, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input, Label, PhoneInput
14
+ } from '@djangocfg/ui-nextjs/components';
15
+ import { zodResolver } from '@hookform/resolvers/zod';
16
+
17
+ import { profileLogger } from '../../../utils/logger';
28
18
 
29
19
  export const ProfileForm = () => {
30
20
  const { user } = useAuth();
@@ -28,14 +28,12 @@
28
28
 
29
29
  'use client';
30
30
 
31
- import { ReactNode, useState, useEffect } from 'react';
32
31
  import { usePathname } from 'next/navigation';
33
- import type { NavigationItem, UserMenuConfig } from '../types';
34
- import {
35
- PublicNavigation,
36
- PublicMobileDrawer,
37
- } from './components';
32
+ import { ReactNode, useEffect, useState } from 'react';
33
+
34
+ import { PublicMobileDrawer, PublicNavigation } from './components';
38
35
 
36
+ import type { NavigationItem, UserMenuConfig } from '../types';
39
37
  export interface PublicLayoutProps {
40
38
  children: ReactNode;
41
39
  /** Logo path or URL */
@@ -4,9 +4,11 @@
4
4
 
5
5
  'use client';
6
6
 
7
- import React from 'react';
8
7
  import Link from 'next/link';
8
+ import React from 'react';
9
+
9
10
  import { DjangoCFGLogo } from './DjangoCFGLogo';
11
+
10
12
  import type { FooterLink } from './types';
11
13
 
12
14
  export interface FooterBottomProps {
@@ -4,8 +4,9 @@
4
4
 
5
5
  'use client';
6
6
 
7
- import React from 'react';
8
7
  import Link from 'next/link';
8
+ import React from 'react';
9
+
9
10
  import type { FooterMenuSection } from './types';
10
11
 
11
12
  export interface FooterMenuSectionsProps {
@@ -5,9 +5,11 @@
5
5
  'use client';
6
6
 
7
7
  import React from 'react';
8
- import type { LucideIcon } from 'lucide-react';
8
+
9
9
  import { DjangoCFGLogo } from './DjangoCFGLogo';
10
10
  import { FooterSocialLinksComponent } from './FooterSocialLinks';
11
+
12
+ import type { LucideIcon } from 'lucide-react';
11
13
  import type { FooterSocialLinks } from './types';
12
14
 
13
15
  export interface FooterProjectInfoProps {
@@ -4,18 +4,11 @@
4
4
 
5
5
  'use client';
6
6
 
7
- import React from 'react';
8
7
  import {
9
- Github,
10
- Linkedin,
11
- Twitter,
12
- MessageCircle,
13
- Youtube,
14
- Facebook,
15
- Instagram,
16
- Mail,
17
- MessageSquare,
8
+ Facebook, Github, Instagram, Linkedin, Mail, MessageCircle, MessageSquare, Twitter, Youtube
18
9
  } from 'lucide-react';
10
+ import React from 'react';
11
+
19
12
  import type { FooterSocialLinks } from './types';
20
13
 
21
14
  export interface FooterSocialLinksProps {
@@ -7,12 +7,15 @@
7
7
 
8
8
  'use client';
9
9
 
10
- import React from 'react';
11
10
  import Link from 'next/link';
11
+ import React from 'react';
12
+
12
13
  import { useIsMobile } from '@djangocfg/ui-nextjs/hooks';
13
- import { FooterProjectInfo } from './FooterProjectInfo';
14
- import { FooterMenuSections } from './FooterMenuSections';
14
+
15
15
  import { FooterBottom } from './FooterBottom';
16
+ import { FooterMenuSections } from './FooterMenuSections';
17
+ import { FooterProjectInfo } from './FooterProjectInfo';
18
+
16
19
  import type { PublicFooterProps } from './types';
17
20
 
18
21
  export function PublicFooter({