diff --git a/.gitignore b/.gitignore
index 1cea65a..c50ca70 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,5 +43,6 @@ yarn-error.log*
next-env.d.ts
certificates
certbot
+bun.lock
/.idea
diff --git a/package.json b/package.json
index d22ea42..f1caf5c 100644
--- a/package.json
+++ b/package.json
@@ -1,84 +1,84 @@
{
- "name": "setka-frontend",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "dev": "next dev --turbopack --experimental-https",
- "build": "next build",
- "start": "next start",
- "api:code-gen": "openapi-generator-cli generate --generator-key api && openapi-generator-cli generate --generator-key admin-api",
- "api-dev:code-gen": "openapi-generator-cli generate --generator-key api-dev",
- "lint": "next lint"
- },
- "dependencies": {
- "@editorjs/editorjs": "^2.30.8",
- "@editorjs/paragraph": "^2.11.7",
- "@editorjs/underline": "^1.2.1",
- "@hookform/resolvers": "^5.2.1",
- "@radix-ui/react-checkbox": "^1.3.3",
- "@radix-ui/react-dialog": "^1.1.15",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@radix-ui/react-popover": "^1.1.15",
- "@radix-ui/react-select": "^2.2.6",
- "@radix-ui/react-slot": "^1.2.3",
- "@tailwindcss/postcss": "^4.1.12",
- "@tanstack/react-query": "^5.85.5",
- "@uidotdev/usehooks": "^2.4.1",
- "axios": "^1.11.0",
- "class-variance-authority": "^0.7.1",
- "clsx": "^2.1.1",
- "date-fns": "^4.1.0",
- "framer-motion": "^12.23.12",
- "jose": "^6.0.13",
- "js-cookie": "^3.0.5",
- "lucide-react": "^0.542.0",
- "next": "15.5.2",
- "next-themes": "^0.4.6",
- "path-to-regexp": "^8.2.0",
- "prettier-plugin-tailwindcss": "^0.6.14",
- "react": "^19.1.1",
- "react-click-away-listener": "^2.4.0",
- "react-day-picker": "9.9.0",
- "react-dom": "^19.1.1",
- "react-hook-form": "^7.62.0",
- "react-hot-toast": "^2.6.0",
- "react-icons": "^5.5.0",
- "react-intersection-observer": "^9.16.0",
- "react-mobile-cropper": "^0.10.0",
- "swiper": "^11.2.10",
- "tailwind-merge": "^3.3.1",
- "tw-animate-css": "^1.3.7",
- "use-debounce": "^10.0.5",
- "vaul": "^1.1.2",
- "zod": "^4.1.3",
- "zustand": "^5.0.8"
- },
- "devDependencies": {
- "@eslint/eslintrc": "^3.3.1",
- "@next/eslint-plugin-next": "^15.5.2",
- "@openapitools/openapi-generator-cli": "^2.23.1",
- "@tanstack/eslint-plugin-query": "^5.83.1",
- "@trivago/prettier-plugin-sort-imports": "^5.2.2",
- "@types/js-cookie": "^3.0.6",
- "@types/node": "^24.3.0",
- "@types/react": "^19.1.11",
- "@types/react-dom": "^19.1.8",
- "eslint": "^9.34.0",
- "eslint-config-next": "15.5.2",
- "eslint-plugin-react": "^7.37.5",
- "eslint-plugin-react-hooks": "^5.2.0",
- "postcss": "^8.5.6",
- "prettier": "^3.6.2",
- "sass": "^1.91.0",
- "tailwindcss": "^4.1.12",
- "typescript": "5.9.2"
- },
- "packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad",
- "trustedDependencies": [
- "@nestjs/core",
- "@openapitools/openapi-generator-cli",
- "@parcel/watcher",
- "@tailwindcss/oxide",
- "unrs-resolver"
- ]
+ "name": "setka-frontend",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev --turbopack --experimental-https",
+ "build": "next build",
+ "start": "next start",
+ "api:code-gen": "openapi-generator-cli generate --generator-key api && openapi-generator-cli generate --generator-key admin-api",
+ "api-dev:code-gen": "openapi-generator-cli generate --generator-key api-dev",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "@editorjs/editorjs": "^2.30.8",
+ "@editorjs/paragraph": "^2.11.7",
+ "@editorjs/underline": "^1.2.1",
+ "@hookform/resolvers": "^5.2.1",
+ "@radix-ui/react-checkbox": "^1.3.3",
+ "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-slot": "^1.2.3",
+ "@tailwindcss/postcss": "^4.1.12",
+ "@tanstack/react-query": "^5.85.5",
+ "@uidotdev/usehooks": "^2.4.1",
+ "axios": "^1.11.0",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "date-fns": "^4.1.0",
+ "framer-motion": "^12.23.12",
+ "jose": "^6.0.13",
+ "js-cookie": "^3.0.5",
+ "lucide-react": "^0.542.0",
+ "next": "15.5.2",
+ "next-themes": "^0.4.6",
+ "path-to-regexp": "^8.2.0",
+ "react": "^19.1.1",
+ "react-click-away-listener": "^2.4.0",
+ "react-day-picker": "9.9.0",
+ "react-dom": "^19.1.1",
+ "react-hook-form": "^7.62.0",
+ "react-hot-toast": "^2.6.0",
+ "react-icons": "^5.5.0",
+ "react-intersection-observer": "^9.16.0",
+ "react-mobile-cropper": "^0.10.0",
+ "swiper": "^11.2.10",
+ "tailwind-merge": "^3.3.1",
+ "tw-animate-css": "^1.3.7",
+ "use-debounce": "^10.0.5",
+ "vaul": "^1.1.2",
+ "zod": "^4.1.3",
+ "zustand": "^5.0.8"
+ },
+ "devDependencies": {
+ "@eslint/eslintrc": "^3.3.1",
+ "@next/eslint-plugin-next": "^15.5.2",
+ "@openapitools/openapi-generator-cli": "^2.23.1",
+ "@tanstack/eslint-plugin-query": "^5.83.1",
+ "@trivago/prettier-plugin-sort-imports": "^5.2.2",
+ "prettier-plugin-tailwindcss": "^0.6.14",
+ "@types/js-cookie": "^3.0.6",
+ "@types/node": "^24.3.0",
+ "@types/react": "^19.1.11",
+ "@types/react-dom": "^19.1.8",
+ "eslint": "^9.34.0",
+ "eslint-config-next": "15.5.2",
+ "eslint-plugin-react": "^7.37.5",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "postcss": "^8.5.6",
+ "prettier": "^3.6.2",
+ "sass": "^1.91.0",
+ "tailwindcss": "^4.1.12",
+ "typescript": "5.9.2"
+ },
+ "packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad",
+ "trustedDependencies": [
+ "@nestjs/core",
+ "@openapitools/openapi-generator-cli",
+ "@parcel/watcher",
+ "@tailwindcss/oxide",
+ "unrs-resolver"
+ ]
}
diff --git a/src/app/(auth)/(withMenuNavigation)/(home)/Home.tsx b/src/app/(auth)/(withMenuNavigation)/(home)/Home.tsx
index d49a58b..aad22ba 100644
--- a/src/app/(auth)/(withMenuNavigation)/(home)/Home.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/(home)/Home.tsx
@@ -1,33 +1,15 @@
-'use client';
+import { Suspense } from 'react';
-import dynamic from 'next/dynamic';
-
-import Loader from '@/components/Loader';
import { Page } from '@/components/Page';
-import { Skeleton } from '@/components/ui/skeleton';
-
-import { useInfinityScroll } from '@/hooks/useInfinityScroll';
-
-import { feedApi } from '@/api/api';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
+import HomeFeed from '@/app/(auth)/(withMenuNavigation)/(home)/HomeFeed';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
import { parseLocalTime } from '@/lib/utils/time.util';
-const PostCardDynamic = dynamic(() => import('@/components/PostCard/PostCard').then((mod) => mod.PostCard), {
- loading: () => ,
-});
+export const dynamic = 'force-static';
export default function Home({ timeBasedGreeting }: { timeBasedGreeting: string }) {
- const {
- ref,
- infiniteQuery: { data, isLoading, isFetchingNextPage, hasNextPage, error },
- } = useInfinityScroll({
- queryKey: ['fetch-feed-posts'],
- queryFn: async ({ pageParam = 0 }) => (await feedApi.feedGetFeedPosts(pageParam, 10)).data,
- pageSize: 10,
- });
-
return (
@@ -36,22 +18,10 @@ export default function Home({ timeBasedGreeting }: { timeBasedGreeting: string
{parseLocalTime(Date(), { day: 'numeric', month: 'short' })}
-
-
- {data &&
- data.pages.flatMap((page) => page).map((post) =>
)}
- {(isFetchingNextPage || isLoading) &&
}
- {!hasNextPage && !isLoading && (
-
Ваша лента закончилась
- )}
- {error && (
-
- Не удалось выполнить загрузку постов. Пожалуйста, повторите позже.
-
- )}
-
-
+
+
+
);
diff --git a/src/app/(auth)/(withMenuNavigation)/(home)/HomeFeed.tsx b/src/app/(auth)/(withMenuNavigation)/(home)/HomeFeed.tsx
new file mode 100644
index 0000000..39d1dfd
--- /dev/null
+++ b/src/app/(auth)/(withMenuNavigation)/(home)/HomeFeed.tsx
@@ -0,0 +1,42 @@
+'use client';
+
+import dynamic from 'next/dynamic';
+
+import Loader from '@/components/Loader';
+import { Skeleton } from '@/components/ui/skeleton';
+
+import { useInfinityScroll } from '@/hooks/useInfinityScroll';
+
+import { feedApi } from '@/api/api';
+
+const PostCardDynamic = dynamic(() => import('@/components/PostCard/PostCard').then((mod) => mod.PostCard), {
+ loading: () => ,
+ ssr: false,
+});
+
+export default function HomeFeed() {
+ const {
+ ref,
+ infiniteQuery: { data, isLoading, isFetchingNextPage, hasNextPage, error },
+ } = useInfinityScroll({
+ queryKey: ['fetch-feed-posts'],
+ queryFn: async ({ pageParam = 0 }) => (await feedApi.feedGetFeedPosts(pageParam, 10)).data,
+ pageSize: 10,
+ });
+
+ return (
+
+ {data && data.pages.flatMap((page) => page).map((post) =>
)}
+ {(isFetchingNextPage || isLoading) &&
}
+ {!hasNextPage && !isLoading && (
+
Ваша лента закончилась
+ )}
+ {error && (
+
+ Не удалось выполнить загрузку постов. Пожалуйста, повторите позже.
+
+ )}
+
+
+ );
+}
diff --git a/src/app/(auth)/(withMenuNavigation)/(home)/page.tsx b/src/app/(auth)/(withMenuNavigation)/(home)/page.tsx
index 221d094..9879456 100644
--- a/src/app/(auth)/(withMenuNavigation)/(home)/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/(home)/page.tsx
@@ -7,20 +7,20 @@ export const metadata: Metadata = {
description: 'Главная страница',
};
-export default async function HomePage() {
- const getTimeBasedGreeting = (): string => {
- const currentHour = new Date().getHours();
+const getTimeBasedGreeting = (): string => {
+ const currentHour = new Date().getHours();
- if (currentHour >= 5 && currentHour < 12) {
- return 'Доброе утро';
- } else if (currentHour >= 12 && currentHour < 18) {
- return 'Добрый день';
- } else if (currentHour >= 18 && currentHour < 23) {
- return 'Добрый вечер';
- }
+ if (currentHour >= 5 && currentHour < 12) {
+ return 'Доброе утро';
+ } else if (currentHour >= 12 && currentHour < 18) {
+ return 'Добрый день';
+ } else if (currentHour >= 18 && currentHour < 23) {
+ return 'Добрый вечер';
+ }
- return 'Доброй ночи';
- };
+ return 'Доброй ночи';
+};
+export default function HomePage() {
return ;
}
diff --git a/src/app/(auth)/(withMenuNavigation)/clubs/Clubs.tsx b/src/app/(auth)/(withMenuNavigation)/clubs/Clubs.tsx
index 251da76..7cd141c 100644
--- a/src/app/(auth)/(withMenuNavigation)/clubs/Clubs.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/clubs/Clubs.tsx
@@ -1,6 +1,5 @@
'use client';
-import { m } from 'framer-motion';
import { useState } from 'react';
import { useDebounce } from 'use-debounce';
@@ -13,8 +12,8 @@ import { useInfinityScroll } from '@/hooks/useInfinityScroll';
import { clubsApi } from '@/api/api';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
export function Clubs() {
const [searchQuery, setSearchQuery] = useState('');
@@ -52,15 +51,8 @@ export function Clubs() {
{isLoading && }
{clubs?.pages
.flatMap((page) => page)
- .map((club, index) => (
-
-
-
+ .map((club) => (
+
))}
diff --git a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/Club.tsx b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/Club.tsx
index 887a9ae..f1267d1 100644
--- a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/Club.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/Club.tsx
@@ -1,25 +1,20 @@
-'use client';
-
-import dynamic from 'next/dynamic';
-
import { ClubFeed } from '@/components/ClubComponents/ClubFeed';
import { ClubHeader } from '@/components/ClubComponents/ClubHeader';
+import ClubInfo from '@/components/ClubComponents/ClubInfo';
+import ClubReportDialog from '@/components/ClubComponents/ClubReportDialog';
import { Page } from '@/components/Page';
import type { ClubDetailDTO } from '@/api/axios-client/models/club-detail-dto';
-const ClubReportDialogDynamic = dynamic(() => import('@/components/ClubComponents/ClubReportDialog'), {
- ssr: false,
-});
-
export function Club({ club }: { club: ClubDetailDTO }) {
return (
);
}
diff --git a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/ClubNotFound.tsx b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/ClubNotFound.tsx
index ca4c26e..2d19f14 100644
--- a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/ClubNotFound.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/ClubNotFound.tsx
@@ -1,16 +1,23 @@
-'use client';
-
-import { useRouter } from 'next/navigation';
+import Link from 'next/link';
+import { MdOutlineWifiTetheringError } from 'react-icons/md';
import { Button } from '@/components/ui/button';
export default function ClubNotFound() {
- const router = useRouter();
return (
-
- 404
- Клуб не найден
-
+
+
+
+
+
Клуб не найден
+
+ Проверьте, что ID клуба в адресе указан верно. В другом случае, его могло и не существовать.
+
+
+
+
+
+
);
}
diff --git a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/page.tsx b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/page.tsx
index af6e132..6fb82ca 100644
--- a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/page.tsx
@@ -1,7 +1,11 @@
+import type { ClubDetailDTO } from '@/api/axios-client';
+
import { Club } from './Club';
-import ClubNotFound from './ClubNotFound';
+import ClubNotFound from '@/app/(auth)/(withMenuNavigation)/clubs/[id]/ClubNotFound';
import { getClubGetByIdAction } from '@/server-actions/actions/clubs.action';
+export const revalidate = 60;
+
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) {
try {
const id = (await params).id;
@@ -20,9 +24,9 @@ export async function generateMetadata({ params }: { params: Promise<{ id: strin
export default async function Page(props: { params: Promise<{ id: string }> }) {
const id = (await props.params).id;
-
try {
- const club = await getClubGetByIdAction(id);
+ const club: ClubDetailDTO = await getClubGetByIdAction(id);
+ console.log(club);
return ;
} catch {
return ;
diff --git a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/subscribers/Subscribers.tsx b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/subscribers/Subscribers.tsx
index 84d2075..c3eb720 100644
--- a/src/app/(auth)/(withMenuNavigation)/clubs/[id]/subscribers/Subscribers.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/clubs/[id]/subscribers/Subscribers.tsx
@@ -4,7 +4,7 @@ import Link from 'next/link';
import Loader from '@/components/Loader';
import { Page } from '@/components/Page';
-import { SubscriberCard } from '@/components/SubscriberCard/SubscriberCard';
+import { SubscriberCard } from '@/components/SubscriberCard';
import { BackButton } from '@/components/ui/BackButton';
import { AUTH_PAGE } from '@/lib/config/routes.config';
@@ -13,7 +13,7 @@ import { useInfinityScroll } from '@/hooks/useInfinityScroll';
import { clubsApi } from '@/api/api';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
+import { Header, HeaderTitle } from '@/hoc/Header';
export function Subscribers({ id }: { id: string }) {
const {
diff --git a/src/app/(auth)/(withMenuNavigation)/events/Events.tsx b/src/app/(auth)/(withMenuNavigation)/events/Events.tsx
deleted file mode 100644
index 5c5b945..0000000
--- a/src/app/(auth)/(withMenuNavigation)/events/Events.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-'use client';
-
-import { m } from 'framer-motion';
-import { useRouter } from 'next/navigation';
-
-import { CalendarBadge } from '@/components/Badges';
-import { EventCard } from '@/components/EventCard/EventCard';
-import { Page } from '@/components/Page';
-
-import { AUTH_PAGE } from '@/lib/config/routes.config';
-
-import type { EventDetailDTO } from '@/api/axios-client';
-
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
-
-export function Events({ events }: { events: EventDetailDTO[] }) {
- const router = useRouter();
-
- return (
-
-
- События
- router.push(AUTH_PAGE.EVENTS_CALENDAR())} />
-
-
- {events &&
- events.map((event, index) => (
-
-
-
- ))}
-
-
- );
-}
diff --git a/src/app/(auth)/(withMenuNavigation)/events/[id]/EventNotFound.tsx b/src/app/(auth)/(withMenuNavigation)/events/[id]/EventNotFound.tsx
index 3f1be10..0718ef0 100644
--- a/src/app/(auth)/(withMenuNavigation)/events/[id]/EventNotFound.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/events/[id]/EventNotFound.tsx
@@ -1,16 +1,11 @@
-'use client';
-
-import { useRouter } from 'next/navigation';
-
-import { Button } from '@/components/ui/button';
+import { BackButton } from '@/components/ui/BackButton';
export default function EventNotFound() {
- const router = useRouter();
return (
-
+
404
Событие не найдено
-
+
);
}
diff --git a/src/app/(auth)/(withMenuNavigation)/events/[id]/EventView.tsx b/src/app/(auth)/(withMenuNavigation)/events/[id]/EventView.tsx
deleted file mode 100644
index d3697ca..0000000
--- a/src/app/(auth)/(withMenuNavigation)/events/[id]/EventView.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-'use client';
-
-import { EllipsisVertical } from 'lucide-react';
-import Image from 'next/image';
-import { FaCalendar, FaCompass } from 'react-icons/fa';
-import { IoAlertCircle, IoCopy } from 'react-icons/io5';
-
-import { Page } from '@/components/Page';
-import { BackButton } from '@/components/ui/BackButton';
-import { Button } from '@/components/ui/button';
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from '@/components/ui/dropdown-menu';
-
-import type { EventDetailDTO } from '@/api/axios-client';
-
-import { getStaticImg } from '@/lib/helpers/getStaticImg.helper';
-import { parseLocalTime } from '@/lib/utils/time.util';
-
-export default function EventView({ event }: { event: EventDetailDTO }) {
- return (
-
-
-
-
- {/*
*/}
- {/* Подробности */}
- {/*
*/}
-
-
-
-
-
-
- {
- navigator.clipboard.writeText(window.location.href);
- const { toast } = await import('react-hot-toast');
- toast.success('Ссылка скопирована');
- }}
- >
-
- Скопировать ссылку
-
-
-
- Пожаловаться
-
-
-
-
-
-
0 && getStaticImg(event.eventImages[0])) ||
- '/img/default-club-banner.jpg'
- }
- fill
- alt={event.title || 'Event banner'}
- className="object-cover"
- priority
- />
-
-
-
-
{event.title}
-
{event.description}
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/app/(auth)/(withMenuNavigation)/events/[id]/page.tsx b/src/app/(auth)/(withMenuNavigation)/events/[id]/page.tsx
index 092bc04..a6a7aa2 100644
--- a/src/app/(auth)/(withMenuNavigation)/events/[id]/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/events/[id]/page.tsx
@@ -1,7 +1,23 @@
+import { EllipsisVertical } from 'lucide-react';
+import Image from 'next/image';
+import { FaCalendar, FaCompass } from 'react-icons/fa';
+import { IoAlertCircle, IoCopy } from 'react-icons/io5';
+
+import { Page } from '@/components/Page';
+import { BackButton } from '@/components/ui/BackButton';
+import { Button } from '@/components/ui/button';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+
import { eventsApi } from '@/api/api';
import EventNotFound from './EventNotFound';
-import EventView from './EventView';
+import { getStaticImg } from '@/lib/helpers/getStaticImg.helper';
+import { parseLocalTime } from '@/lib/utils/time.util';
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) {
const id = (await params).id;
@@ -10,21 +26,88 @@ export async function generateMetadata({ params }: { params: Promise<{ id: strin
if (!event) {
return {
title: 'Событие не найдено',
- description: '',
+ description: 'Проверьте правильность ссылки на событие.',
};
}
return {
- title: `${event.title} - Событие`,
+ title: `Событие "${event.title}"`,
description: event.description,
};
}
export const revalidate = 100;
-export default async function Page({ params }: { params: Promise<{ id: string }> }) {
+export default async function EventViewPage({ params }: { params: Promise<{ id: string }> }) {
const id = (await params).id;
const event = (await eventsApi.eventsGetById(Number(id))).data;
- return event ? : ;
+ if (!event) {
+ return ;
+ }
+
+ return (
+
+
+
+
+ {/*
*/}
+ {/* Подробности */}
+ {/*
*/}
+
+
+
+
+
+
+ {
+ navigator.clipboard.writeText(window.location.href);
+ const { toast } = await import('react-hot-toast');
+ toast.success('Ссылка скопирована');
+ }}
+ >
+
+ Скопировать ссылку
+
+
+
+ Пожаловаться
+
+
+
+
+
+
0 && getStaticImg(event.eventImages[0])) ||
+ '/img/default-club-banner.jpg'
+ }
+ fill
+ alt={event.title || 'Event banner'}
+ className="object-cover"
+ priority
+ />
+
+
+
+
{event.title}
+
{event.description}
+
+
+
+
+
+
+
+
+
+ );
}
diff --git a/src/app/(auth)/(withMenuNavigation)/events/calendar/Calendar.tsx b/src/app/(auth)/(withMenuNavigation)/events/calendar/Calendar.tsx
index 3982969..e4119dc 100644
--- a/src/app/(auth)/(withMenuNavigation)/events/calendar/Calendar.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/events/calendar/Calendar.tsx
@@ -2,11 +2,10 @@
import { useQuery } from '@tanstack/react-query';
import { format, parseISO } from 'date-fns';
-import { m } from 'framer-motion';
import { useMemo, useState } from 'react';
-import EventCalendar from '@/components/EventCalendar/EventCalendar';
-import { EventCard } from '@/components/EventCard/EventCard';
+import EventCalendar from '@/components/EventCalendar';
+import { EventCard } from '@/components/EventCard';
import { Page } from '@/components/Page';
import { BackButton } from '@/components/ui/BackButton';
@@ -15,8 +14,8 @@ import { useInfinityScroll } from '@/hooks/useInfinityScroll';
import { eventsApi } from '@/api/api';
import type { EventDetailDTO } from '@/api/axios-client';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
import { toUTCDate } from '@/lib/utils/time.util';
export function Calendar() {
@@ -70,16 +69,10 @@ export function Calendar() {
{hasEvents
? eventsPages?.pages
.flatMap((page) => page)
- .map((event, index) => (
-
+ .map((event) => (
+
-
+
))
: !isLoading && (
diff --git a/src/app/(auth)/(withMenuNavigation)/events/calendar/page.tsx b/src/app/(auth)/(withMenuNavigation)/events/calendar/page.tsx
index 1a91e74..8650bbe 100644
--- a/src/app/(auth)/(withMenuNavigation)/events/calendar/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/events/calendar/page.tsx
@@ -4,7 +4,7 @@ import { Calendar } from './Calendar';
export const metadata: Metadata = {
title: 'Календарь событий',
- description: '',
+ description: 'Календарь со всеми событиями',
};
export default async function Page() {
diff --git a/src/app/(auth)/(withMenuNavigation)/events/page.tsx b/src/app/(auth)/(withMenuNavigation)/events/page.tsx
index 70cc495..1111f0c 100644
--- a/src/app/(auth)/(withMenuNavigation)/events/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/events/page.tsx
@@ -1,16 +1,44 @@
import type { Metadata } from 'next';
+import Link from 'next/link';
+
+import { CalendarBadge } from '@/components/Badges';
+import { EventCard } from '@/components/EventCard';
+import { Page } from '@/components/Page';
+
+import { AUTH_PAGE } from '@/lib/config/routes.config';
import { eventsApi } from '@/api/api';
-import { Events } from './Events';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
export const metadata: Metadata = {
title: 'События',
description: '',
};
-export default async function Page() {
+export const dynamic = 'force-dynamic';
+export const revalidate = 60;
+
+export default async function EventsPage() {
const events = (await eventsApi.eventsGetAll()).data;
- return
;
+ return (
+
+
+
+ {events &&
+ events.map((event) => (
+
+
+
+ ))}
+
+
+ );
}
diff --git a/src/app/(auth)/(withMenuNavigation)/finder/Finder.tsx b/src/app/(auth)/(withMenuNavigation)/finder/Finder.tsx
index 759ed10..dc301bf 100644
--- a/src/app/(auth)/(withMenuNavigation)/finder/Finder.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/finder/Finder.tsx
@@ -1,4 +1,4 @@
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
+import { Header, HeaderTitle } from '@/hoc/Header';
export function Finder() {
return (
diff --git a/src/app/(auth)/(withMenuNavigation)/loading.tsx b/src/app/(auth)/(withMenuNavigation)/loading.tsx
index 24b250d..d3527cc 100644
--- a/src/app/(auth)/(withMenuNavigation)/loading.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/loading.tsx
@@ -1,4 +1,4 @@
-import { MainLoader } from '@/components/MainLoader/MainLoader';
+import { MainLoader } from '@/components/MainLoader';
export default function Loading() {
return
;
diff --git a/src/app/(auth)/(withMenuNavigation)/not-found.tsx b/src/app/(auth)/(withMenuNavigation)/not-found.tsx
new file mode 100644
index 0000000..fbc9ec2
--- /dev/null
+++ b/src/app/(auth)/(withMenuNavigation)/not-found.tsx
@@ -0,0 +1,23 @@
+import Link from 'next/link';
+import { MdOutlineWifiTetheringError } from 'react-icons/md';
+
+import { Button } from '@/components/ui/button';
+
+export default async function NotFound() {
+ return (
+
+
+
+
+
Страница не найдена
+
+ Страница которую вы искали к сожаления не найдена. Проверьте правильность адреса.
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/UserProfile.tsx b/src/app/(auth)/(withMenuNavigation)/profile/UserProfile.tsx
deleted file mode 100644
index 98fba34..0000000
--- a/src/app/(auth)/(withMenuNavigation)/profile/UserProfile.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-'use client';
-
-import { useQuery } from '@tanstack/react-query';
-import Link from 'next/link';
-import { BiMessageSquare, BiSolidIdCard } from 'react-icons/bi';
-
-import { SettingBadge } from '@/components/Badges';
-import { ClubCard } from '@/components/ClubComponents/ClubCard';
-import { Page } from '@/components/Page';
-import { Avatar } from '@/components/ui/Avatar';
-import { SkeletonList } from '@/components/ui/skeleton';
-
-import { AUTH_PAGE } from '@/lib/config/routes.config';
-
-import { useProfile } from '@/hooks/useProfile';
-
-import { userApi } from '@/api/api';
-
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
-
-export default function UserProfile() {
- const {
- data: userClubs,
- isLoading,
- error,
- } = useQuery({
- queryKey: ['fetch-profile-user-clubs'],
- queryFn: async () => (await userApi.userGetSubscribedClubs(0, 3)).data,
- });
- const { data: user } = useProfile();
-
- return (
-
-
-
-
-
-
-
-
-
- {user?.firstName} {user?.lastName}
-
-
был недавно
-
-
-
-
-
-
- {user?.about || '...'}
-
-
-
-
-
- {user?.institute?.name || 'Нет института'}
-
-
-
-
-
-
-
Подписки
-
- Показать все
-
-
- {isLoading &&
}
- {!isLoading &&
- userClubs &&
- userClubs.length > 0 &&
- userClubs.map((club) =>
)}
- {error &&
Не удалось загрузить ваши подписки
}
-
-
-
- );
-}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/[id]/Profile.tsx b/src/app/(auth)/(withMenuNavigation)/profile/[id]/Profile.tsx
index ffcf35a..8846501 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/[id]/Profile.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/[id]/Profile.tsx
@@ -1,13 +1,8 @@
-'use client';
-
-import { useQuery } from '@tanstack/react-query';
import { Copy, EllipsisVertical, OctagonAlert } from 'lucide-react';
import Link from 'next/link';
-import { usePathname } from 'next/navigation';
-import toast from 'react-hot-toast';
import { BiMessageSquare, BiSolidIdCard } from 'react-icons/bi';
+import { IoSettingsSharp } from 'react-icons/io5';
-import { ClubCard } from '@/components/ClubComponents/ClubCard';
import { Page } from '@/components/Page';
import { Avatar } from '@/components/ui/Avatar';
import { BackButton } from '@/components/ui/BackButton';
@@ -18,36 +13,37 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
-import { SkeletonList } from '@/components/ui/skeleton';
import { AUTH_PAGE } from '@/lib/config/routes.config';
-import { clubsApi } from '@/api/api';
import type { PersonDetailDTO } from '@/api/axios-client/models';
-import { Header } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
+import UserProfileClubs from '@/app/(auth)/(withMenuNavigation)/profile/[id]/UserProfileClubs';
+import { Header } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
type Props = {
user: PersonDetailDTO;
+ isCurrent: boolean;
};
-export default function Profile({ user }: Props) {
- const {
- data: userClubs,
- isLoading,
- error,
- } = useQuery({
- queryKey: [user.id, 'fetch-profile-user-clubs'],
- queryFn: async () => (await clubsApi.clubsGetByPersonId(user.id, 0, 3)).data,
- });
-
- const pathname = usePathname();
+export const dynamic = 'force-dynamic';
+export const revalidate = 60;
+export default function Profile({ user, isCurrent }: Props) {
return (
-
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/[id]/UserProfileClubs.tsx b/src/app/(auth)/(withMenuNavigation)/profile/[id]/UserProfileClubs.tsx
new file mode 100644
index 0000000..ab959c3
--- /dev/null
+++ b/src/app/(auth)/(withMenuNavigation)/profile/[id]/UserProfileClubs.tsx
@@ -0,0 +1,35 @@
+'use client';
+
+import { useQuery } from '@tanstack/react-query';
+import dynamic from 'next/dynamic';
+import { Fragment } from 'react';
+
+import { SkeletonList } from '@/components/ui/skeleton';
+
+import { clubsApi } from '@/api/api';
+
+const ClubCardDynamic = dynamic(() => import('@/components/ClubComponents/ClubCard').then((mod) => mod.ClubCard), {
+ ssr: false,
+});
+
+export default function UserProfileClubs({ id }: { id: number }) {
+ const {
+ data: userClubs,
+ isLoading,
+ error,
+ } = useQuery({
+ queryKey: [id, 'fetch-profile-user-clubs'],
+ queryFn: async () => (await clubsApi.clubsGetByPersonId(id, 0, 3)).data,
+ });
+
+ return (
+
+ {isLoading && }
+ {!isLoading &&
+ userClubs &&
+ userClubs.length > 0 &&
+ userClubs.map((club) => )}
+ {error && Не удалось загрузить подписки пользователя
}
+
+ );
+}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/ProfileClubs.tsx b/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/ProfileClubs.tsx
index 3257f6b..a46cbd0 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/ProfileClubs.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/ProfileClubs.tsx
@@ -3,7 +3,6 @@
import { useMemo } from 'react';
import { ClubCard } from '@/components/ClubComponents/ClubCard';
-import { BackButton } from '@/components/ui/BackButton';
import { SkeletonList } from '@/components/ui/skeleton';
import { useInfinityScroll } from '@/hooks/useInfinityScroll';
@@ -11,8 +10,6 @@ import { useInfinityScroll } from '@/hooks/useInfinityScroll';
import { clubsApi } from '@/api/api';
import type { PersonDetailDTO } from '@/api/axios-client';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-
export default function ProfileClubs({ user }: { user: PersonDetailDTO }) {
const {
ref,
@@ -26,22 +23,14 @@ export default function ProfileClubs({ user }: { user: PersonDetailDTO }) {
const userClubs = useMemo(() => (clubs ? clubs.pages.flatMap((page) => page) : []), [clubs]);
return (
-
-
-
-
- {user.firstName} {user.lastName}: подписки
-
-
-
- {(isFetchingNextPage || isLoading) &&
}
- {!isLoading && userClubs.length === 0 ? (
-
Нет ни одной подписки
- ) : (
- userClubs.map((club) =>
)
- )}
-
-
+
+ {(isFetchingNextPage || isLoading) &&
}
+ {!isLoading && userClubs.length === 0 ? (
+
Нет ни одной подписки
+ ) : (
+ userClubs.map((club) =>
)
+ )}
+
);
}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/page.tsx b/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/page.tsx
index cd395f9..0b61261 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/[id]/clubs/page.tsx
@@ -1,18 +1,35 @@
import type { Metadata } from 'next';
+import { Page } from '@/components/Page';
+import { BackButton } from '@/components/ui/BackButton';
+
import { usersApi } from '@/api/api';
import type { PersonDetailDTO } from '@/api/axios-client';
import ProfileClubs from './ProfileClubs';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
export const metadata: Metadata = {
title: 'Подписки',
- description: '',
+ description: 'Подписки пользователя',
};
-export default async function Page({ params }: { params: Promise<{ id: number }> }) {
+export default async function ClubsPage({ params }: { params: Promise<{ id: number }> }) {
const { id } = await params;
const user: PersonDetailDTO = (await usersApi.usersGetById(id)).data;
- return
;
+ return (
+
+
+
+
+ {user.firstName} {user.lastName}: подписки
+
+
+
+
+
+
+ );
}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/[id]/page.tsx b/src/app/(auth)/(withMenuNavigation)/profile/[id]/page.tsx
index 302fda4..9b307c2 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/[id]/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/[id]/page.tsx
@@ -1,24 +1,33 @@
import type { Metadata } from 'next';
-import { redirect } from 'next/navigation';
+import { notFound } from 'next/navigation';
-import { AUTH_PAGE } from '@/lib/config/routes.config';
-
-import { userApi, usersApi } from '@/api/api';
+import { usersApi } from '@/api/api';
import type { PersonDetailDTO } from '@/api/axios-client';
import Profile from './Profile';
+import { getPersonIdFromToken } from '@/server-actions/actions/getPersonIdFromToken.action';
+
+export const revalidate = 60;
export const metadata: Metadata = {
title: 'Профиль',
- description: '',
+ description: 'Профиль пользователя',
};
export default async function Page({ params }: { params: Promise<{ id: number }> }) {
const { id } = await params;
- const user: PersonDetailDTO = (await usersApi.usersGetById(id)).data;
- const currentUser: PersonDetailDTO = (await userApi.userGetPersonalDetails()).data;
+ try {
+ const user: PersonDetailDTO = (await usersApi.usersGetById(id)).data;
+ let currentPerson = await getPersonIdFromToken();
+ if (!currentPerson) {
+ console.log('Не удалось получить текущего пользователя из токена');
+ currentPerson = '0';
+ }
- if (currentUser.id === user.id) redirect(AUTH_PAGE.PROFILE);
+ const isCurrent = user.id === Number(currentPerson);
- return
;
+ return
;
+ } catch (error) {
+ return notFound();
+ }
}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/clubs/UserProfileClubs.tsx b/src/app/(auth)/(withMenuNavigation)/profile/clubs/UserProfileClubs.tsx
deleted file mode 100644
index 4791aa4..0000000
--- a/src/app/(auth)/(withMenuNavigation)/profile/clubs/UserProfileClubs.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-'use client';
-
-import { useMemo } from 'react';
-
-import { ClubCard } from '@/components/ClubComponents/ClubCard';
-import { Page } from '@/components/Page';
-import { BackButton } from '@/components/ui/BackButton';
-import { SkeletonList } from '@/components/ui/skeleton';
-
-import { useInfinityScroll } from '@/hooks/useInfinityScroll';
-
-import { userApi } from '@/api/api';
-
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-
-export default function UserProfileClubs() {
- const {
- ref,
- infiniteQuery: { data: clubs, isLoading, isFetchingNextPage },
- } = useInfinityScroll({
- queryKey: ['fetch-user-clubs'],
- queryFn: async (page) => (await userApi.userGetSubscribedClubs(page.pageParam, 12)).data,
- pageSize: 12,
- });
-
- const userClubs = useMemo(() => (clubs ? clubs.pages.flatMap((page) => page) : []), [clubs]);
-
- return (
-
-
-
- {(isFetchingNextPage || isLoading) &&
}
- {!isLoading && userClubs.length === 0 ? (
-
Вы пока не подписаны ни на один клуб
- ) : (
- userClubs.map((club) =>
)
- )}
-
-
-
- );
-}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/clubs/page.tsx b/src/app/(auth)/(withMenuNavigation)/profile/clubs/page.tsx
deleted file mode 100644
index a84a105..0000000
--- a/src/app/(auth)/(withMenuNavigation)/profile/clubs/page.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import type { Metadata } from 'next';
-
-import ProfileClubs from './UserProfileClubs';
-
-export const metadata: Metadata = {
- title: 'Ваши подписки',
- description: '',
-};
-
-export default function Page() {
- return
;
-}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/page.tsx b/src/app/(auth)/(withMenuNavigation)/profile/page.tsx
index 46ccecb..8f0af9b 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/page.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/page.tsx
@@ -1,12 +1,15 @@
-import type { Metadata } from 'next';
+import { redirect } from 'next/navigation';
-import Profile from './UserProfile';
+import { AUTH_PAGE } from '@/lib/config/routes.config';
-export const metadata: Metadata = {
- title: 'Ваш профиль',
- description: '',
-};
+import { getPersonIdFromToken } from '@/server-actions/actions/getPersonIdFromToken.action';
+
+export const dynamic = 'force-dynamic';
export default async function Page() {
- return
;
+ const currentPerson = await getPersonIdFromToken();
+ if (!currentPerson) {
+ redirect('/');
+ }
+ redirect(AUTH_PAGE.USER_PROFILE(Number(currentPerson)));
}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/settings/MenuLogoutItem.tsx b/src/app/(auth)/(withMenuNavigation)/profile/settings/MenuLogoutItem.tsx
new file mode 100644
index 0000000..69dd71f
--- /dev/null
+++ b/src/app/(auth)/(withMenuNavigation)/profile/settings/MenuLogoutItem.tsx
@@ -0,0 +1,45 @@
+'use client';
+
+import { useMutation } from '@tanstack/react-query';
+import { useRouter } from 'next/navigation';
+import { startTransition } from 'react';
+import { BiExit } from 'react-icons/bi';
+
+import { MenuItem } from '@/components/ui/menu';
+
+import { PUBLIC_PAGE } from '@/lib/config/routes.config';
+
+import { authApi } from '@/api/api';
+
+export default function MenuLogoutItem() {
+ const router = useRouter();
+
+ const { mutateAsync } = useMutation({
+ mutationKey: ['logout-profile'],
+ mutationFn: async () => await authApi.authLogout(),
+ });
+
+ const logoutHandler = async () => {
+ const { toast } = await import('react-hot-toast');
+ toast.promise(
+ mutateAsync(),
+ {
+ loading: 'Выход из системы',
+ success: () => {
+ startTransition(() => {
+ router.push(PUBLIC_PAGE.AUTH('login'));
+ });
+
+ return 'Успешно!';
+ },
+ error: () => {
+ return 'Ошибка при попытке выхода из профиля';
+ },
+ },
+ {
+ id: 'error',
+ }
+ );
+ };
+ return
;
+}
diff --git a/src/app/(auth)/(withMenuNavigation)/profile/settings/Settings.tsx b/src/app/(auth)/(withMenuNavigation)/profile/settings/Settings.tsx
index 0f37115..0d54b9d 100644
--- a/src/app/(auth)/(withMenuNavigation)/profile/settings/Settings.tsx
+++ b/src/app/(auth)/(withMenuNavigation)/profile/settings/Settings.tsx
@@ -1,63 +1,15 @@
-'use client';
-
-import { useMutation } from '@tanstack/react-query';
-import { useRouter } from 'next/navigation';
-import { startTransition } from 'react';
-import { BiExit } from 'react-icons/bi';
-import { LuPlus } from 'react-icons/lu';
-
import { Page } from '@/components/Page';
-import { ProfileAvatarUploader } from '@/components/ProfileComponents/ProfileAvatar/ProfileAvatarUploader';
import { PROFILE_SETTING_SECTIONS } from '@/components/ProfileComponents/profile-section.config';
import { BackButton } from '@/components/ui/BackButton';
-import { Menu, MenuItem, MenuLink } from '@/components/ui/menu';
-import { SkeletonList } from '@/components/ui/skeleton';
-
-import { AUTH_PAGE, PUBLIC_PAGE } from '@/lib/config/routes.config';
-
-import { useProfile } from '@/hooks/useProfile';
-
-import { authApi } from '@/api/api';
-import { type PersonDetailDTO } from '@/api/axios-client';
-
-import { useOwnedClubs } from './useOwnedClubs';
-import { Header, HeaderTitle } from '@/hoc/Header/Header';
-import { MainContent } from '@/hoc/MainContent/MainContent';
-import { getStaticImg } from '@/lib/helpers/getStaticImg.helper';
+import { Menu, MenuLink } from '@/components/ui/menu';
-export default function Settings({ initUser }: { initUser: PersonDetailDTO }) {
- const router = useRouter();
- const { data: user } = useProfile(initUser);
- const { data: ownedClubs, isLoading } = useOwnedClubs();
-
- const { mutateAsync } = useMutation({
- mutationKey: ['logout-profile'],
- mutationFn: async () => await authApi.authLogout(),
- });
-
- const logoutHandler = async () => {
- const { toast } = await import('react-hot-toast');
- toast.promise(
- mutateAsync(),
- {
- loading: 'Выход из системы',
- success: () => {
- startTransition(() => {
- router.push(PUBLIC_PAGE.AUTH('login'));
- });
-
- return 'Успешно!';
- },
- error: () => {
- return 'Ошибка при попытке выхода из профиля';
- },
- },
- {
- id: 'error',
- }
- );
- };
+import MenuLogoutItem from '@/app/(auth)/(withMenuNavigation)/profile/settings/MenuLogoutItem';
+import UserCard from '@/app/(auth)/(withMenuNavigation)/profile/settings/UserCard';
+import UserClubs from '@/app/(auth)/(withMenuNavigation)/profile/settings/UserClubs';
+import { Header, HeaderTitle } from '@/hoc/Header';
+import { MainContent } from '@/hoc/MainContent';
+export default function Settings() {
return (
@@ -66,45 +18,20 @@ export default function Settings({ initUser }: { initUser: PersonDetailDTO }) {
-
-
-
- {user?.firstName} {user?.lastName}
-
-
{user?.about}
-
+
-
Основные
+
Основные
-
Ваши клубы
-
-
Прочее
+
Ваши клубы
+
+
Прочее