diff --git a/package-lock.json b/package-lock.json index 05184172..73ef6675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16031,6 +16031,126 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.9.tgz", + "integrity": "sha512-/kfQifl3uLYi3DlwFlzCkgxe6fprJNLzzTUFknq3M5wGYicDIbdGlxUl6oHpVLJpBB/CBY3Y//gO6alz/K4NWA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.9.tgz", + "integrity": "sha512-tK/RyhCmOCiXQ9IVdFrBbZOf4/1+0RSuJkebXU2uMEsusS51TjIJO4l8ZmEijH9gZa0pJClvmApRHi7JuBqsRw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.9.tgz", + "integrity": "sha512-tS5eqwsp2nO7mzywRUuFYmefNZsUKM/mTG3exK2jIHv9TEVklE1SByB1KMhFkqlit1PxS9YK1tV8BOV90Wpbrw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.9.tgz", + "integrity": "sha512-8svpeTFNAMTUMKQbEzE8qRAwl9o7mNBv7LR1bmSkQvo1oy4WrNyZbhWsldOiKrc4mZ5dfQkGYsI9T75mIFMfeA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.9.tgz", + "integrity": "sha512-0HNulLWpKTB7H5BhHCkEhcRAnWUHeAYCftrrGw3QC18+ZywTdAoPv/zEqKy/0adqt+ks4JDdlgSQ1lNKOKjo0A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.9.tgz", + "integrity": "sha512-hhVFViPHLAVUJRNtwwm609p9ozWajOmRvzOZzzKXgiVGwx/CALxlMUeh+M+e0Zj6orENhWLZeilOPHpptuENsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.9.tgz", + "integrity": "sha512-p/v6XlOdrk06xfN9z4evLNBqftVQUWiyduQczCwSj7hNh8fWTbzdVxsEiNOcajMXJbQiaX/ZzZdFgKVmmJnnGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.9.tgz", + "integrity": "sha512-IcW9dynWDjMK/0M05E3zopbRen7v0/yEaMZbHFOSS1J/w+8YG3jKywOGZWNp/eCUVtUUXs0PW+7Lpz8uLu+KQA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/package.json b/package.json index 4e82c51d..fe1dfefc 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dependencies": { "@hookform/resolvers": "^3.9.1", "@radix-ui/react-accordion": "^1.2.1", - "@radix-ui/react-alert-dialog": "^1.1.4", + "@radix-ui/react-alert-dialog": "^1.1.5", "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-avatar": "^1.1.1", "@radix-ui/react-checkbox": "^1.1.2", diff --git a/src/actions/profile.actions.ts b/src/actions/profile.actions.ts index 6656bd59..0ead43c1 100644 --- a/src/actions/profile.actions.ts +++ b/src/actions/profile.actions.ts @@ -4,6 +4,7 @@ import { Contact, ContactType } from '@/types/contact'; import { campusFetch } from '@/lib/client'; import { revalidatePath } from 'next/cache'; import { getUserDetails } from '@/actions/auth.actions'; +import { redirect } from 'next/navigation'; export async function getContacts() { try { @@ -101,8 +102,8 @@ export async function acceptCodeOfHonor() { await campusFetch('profile/code-of-honor', { method: 'PUT', }); - return getUserDetails(); } catch (error) { throw new Error('Error while accepting code of honor'); } + redirect('/'); } diff --git a/src/app/[locale]/(private)/accept-code-of-honor/page.tsx b/src/app/[locale]/(private)/accept-code-of-honor/page.tsx new file mode 100644 index 00000000..3dcb5cf4 --- /dev/null +++ b/src/app/[locale]/(private)/accept-code-of-honor/page.tsx @@ -0,0 +1,45 @@ +'use client'; + +import { useTranslations } from 'next-intl'; +import React from 'react'; +import { acceptCodeOfHonor } from '@/actions/profile.actions'; +import { + AlertDialog, + AlertDialogAction, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog'; +import { Link } from '@/i18n/routing'; +import { Paragraph } from '@/components/typography/paragraph'; + +export default function CodeOfHonorAlert() { + const t = useTranslations('private.profile'); + + const handleAcceptCodeOfHonor = async () => { + await acceptCodeOfHonor(); + }; + + return ( + + + + {t('codeOfHonor.title')} + + {t.rich('codeOfHonor.content', { + documentsLink: (chunks) => {chunks}, + paragraph: (chunks) => {chunks}, + })} + + + + + {t('button.agree')} + + + + + ); +} diff --git a/src/app/[locale]/(private)/profile/components/code-of-honor.tsx b/src/app/[locale]/(private)/profile/components/code-of-honor.tsx index c203ff69..fccae710 100644 --- a/src/app/[locale]/(private)/profile/components/code-of-honor.tsx +++ b/src/app/[locale]/(private)/profile/components/code-of-honor.tsx @@ -3,40 +3,15 @@ import { Heading6 } from '@/components/typography/headers'; import { Separator } from '@/components/ui/separator'; import { Paragraph } from '@/components/typography/paragraph'; -import { Button } from '@/components/ui/button'; -import { useIsMobile } from '@/hooks/use-mobile'; import { useLocalStorage } from '@/hooks/use-storage'; import { User } from '@/types/user'; -import { acceptCodeOfHonor } from '@/actions/profile.actions'; -import React, { useState } from 'react'; +import React from 'react'; import { useTranslations } from 'next-intl'; -import { Check } from '@/app/images'; -import { useServerErrorToast } from '@/hooks/use-server-error-toast'; import { Link } from '@/i18n/routing'; export function CodeOfHonor() { - const { errorToast } = useServerErrorToast(); - - const isMobile = useIsMobile(); - - const [user, setUser] = useLocalStorage('user'); - - const [loading, setLoading] = useState(false); - const t = useTranslations('private.profile'); - - const handleAcceptCodeOfHonor = async () => { - setLoading(true); - const res = await acceptCodeOfHonor(); - setLoading(false); - - if (!res) { - errorToast(); - return; - } - setUser(res); - }; - + const [user] = useLocalStorage('user'); return (
{t('codeOfHonor.title')} @@ -45,22 +20,11 @@ export function CodeOfHonor() { documentsLink: (chunks) => {chunks}, paragraph: (chunks) => {chunks}, })} - {user?.codeOfHonorSignDate ? ( + {user?.codeOfHonorSignDate && (
{t('codeOfHonor.agreement')} {user?.codeOfHonorSignDate}
- ) : ( - )}
); diff --git a/src/app/[locale]/(private)/profile/page.tsx b/src/app/[locale]/(private)/profile/page.tsx index a00448d6..6f6c6998 100644 --- a/src/app/[locale]/(private)/profile/page.tsx +++ b/src/app/[locale]/(private)/profile/page.tsx @@ -1,9 +1,21 @@ import { getContacts, getContactTypes } from '@/actions/profile.actions'; -import { Profile } from '@/app/[locale]/(private)/profile/profile'; import { getTranslations } from 'next-intl/server'; +import { SubLayout } from '@/app/[locale]/(private)/sub-layout'; +import { getUserDetails } from '@/actions/auth.actions'; +import { Heading1 } from '@/components/typography/headers'; +import { Paragraph } from '@/components/typography/paragraph'; +import { InfoBlock } from '@/app/[locale]/(private)/profile/components/info-block'; +import { Card, CardContent } from '@/components/ui/card'; +import { Contacts } from '@/app/[locale]/(private)/profile/components/contacts'; +import { Show } from '@/components/utils/show'; +import { IntellectAgreement } from '@/app/[locale]/(private)/profile/components/intellect-agreement'; +import { IntellectPublicationInfo } from '@/app/[locale]/(private)/profile/components/intellect-publication-info'; +import { CodeOfHonor } from '@/app/[locale]/(private)/profile/components/code-of-honor'; + +const INTL_NAMESPACE = 'private.profile'; export async function generateMetadata() { - const t = await getTranslations({ namespace: 'private.profile' }); + const t = await getTranslations(INTL_NAMESPACE); return { title: t('title'), @@ -11,8 +23,34 @@ export async function generateMetadata() { } export default async function Page() { + const t = await getTranslations(INTL_NAMESPACE); + + const user = await getUserDetails(); + const contacts = await getContacts(); const contactTypes = await getContactTypes(); - return ; + const isEmployee = !!user?.employeeProfile; + + return ( + +
+ {t('title')} + {t('subtitle')} +
+ + + + + + + + + + + +
+
+
+ ); } diff --git a/src/app/[locale]/(private)/sub-layout.tsx b/src/app/[locale]/(private)/sub-layout.tsx index 7347fe87..e01934c2 100644 --- a/src/app/[locale]/(private)/sub-layout.tsx +++ b/src/app/[locale]/(private)/sub-layout.tsx @@ -7,6 +7,7 @@ import { BreadcrumbSeparator, } from '@/components/ui/breadcrumb'; import { cn } from '@/lib/utils'; +import React from 'react'; import { useTranslations } from 'next-intl'; interface SubLayoutProps { diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx index 1f6dce21..1eaec4f2 100644 --- a/src/components/ui/alert-dialog.tsx +++ b/src/components/ui/alert-dialog.tsx @@ -25,10 +25,14 @@ const AlertDialogOverlay = React.forwardRef< )); AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; +interface AlertDialogContentProps extends React.ComponentPropsWithoutRef { + closable?: boolean; +} + const AlertDialogContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( + AlertDialogContentProps +>(({ className, closable = true, ...props }, ref) => ( - -