Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ac8cf91
feat: добавление компонента ClubInfo и рефакторинг ClubHeader для улу…
kostya-zero Sep 13, 2025
f8855be
feat: обновление логики получения ID из токена и рефакторинг вызова A…
kostya-zero Sep 13, 2025
372b69b
feat(ClubCard): не использовать useRouter и сделать серверным компоне…
kostya-zero Sep 28, 2025
6d4c813
feat(About): оптимизация страницы о приложении
kostya-zero Sep 28, 2025
11fcb43
feat(Appearance): оптимизация
kostya-zero Sep 28, 2025
52a2c74
Merge remote-tracking branch 'origin/main' into feature/ssr
kostya-zero Sep 28, 2025
09c56b0
chore(routes): добавил необходимый путь
kostya-zero Sep 28, 2025
3d954f7
refactor(PostReportDialog): убрал ненужные импорты
kostya-zero Sep 28, 2025
3f87b5e
refactor(Comments): оптимизация стилей
kostya-zero Sep 28, 2025
333d3c6
feat: SSR для профиля
kostya-zero Sep 28, 2025
571cc2a
feat: SSR для событий
kostya-zero Sep 28, 2025
a5d0063
chore: реструктуризация проекта
kostya-zero Sep 28, 2025
fec2fc4
feat(css): убрал подгрузку шрифтов с Google Fonts
kostya-zero Sep 28, 2025
416f6b0
chore(gitignore): добавил bun.lock в .gitignore
kostya-zero Sep 28, 2025
2556d4a
chore: реструктуризация проекта
kostya-zero Sep 29, 2025
21ac182
feat: новый стиль страницы 404
kostya-zero Sep 29, 2025
6703a22
fix(club): вернул SSR для ClubReportDialogDynamic
kostya-zero Sep 30, 2025
5db3b63
Update Club.tsx
kostya-zero Sep 30, 2025
20404c4
feat: загрузка ClubReportDialog без dynamic
kostya-zero Sep 30, 2025
db28cad
Merge remote-tracking branch 'origin/main' into feature/ssr
kostya-zero Sep 30, 2025
055af49
chore(loading): убрал анимацию при загрузке страницы
kostya-zero Sep 30, 2025
946444b
chore(ssr): убрал force-dynamic
kostya-zero Sep 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ yarn-error.log*
next-env.d.ts
certificates
certbot
bun.lock

/.idea
164 changes: 82 additions & 82 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Comment thread
kostya-zero marked this conversation as resolved.
"@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"
]
}
46 changes: 8 additions & 38 deletions src/app/(auth)/(withMenuNavigation)/(home)/Home.tsx
Original file line number Diff line number Diff line change
@@ -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: () => <Skeleton className="my-2 h-[400px]" />,
});
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 (
<Page>
<Header className="justify-between">
Expand All @@ -36,22 +18,10 @@ export default function Home({ timeBasedGreeting }: { timeBasedGreeting: string
{parseLocalTime(Date(), { day: 'numeric', month: 'short' })}
</p>
</Header>

<MainContent>
<div className="flex flex-col">
{data &&
data.pages.flatMap((page) => page).map((post) => <PostCardDynamic key={post.id} post={post} />)}
{(isFetchingNextPage || isLoading) && <Loader className="mx-auto mt-10" />}
{!hasNextPage && !isLoading && (
<p className="p-4 pb-5 text-center text-neutral-500">Ваша лента закончилась</p>
)}
{error && (
<p className="text-center text-neutral-500">
Не удалось выполнить загрузку постов. Пожалуйста, повторите позже.
</p>
)}
<div ref={ref}></div>
</div>
<Suspense>
<HomeFeed />
</Suspense>
</MainContent>
</Page>
);
Expand Down
42 changes: 42 additions & 0 deletions src/app/(auth)/(withMenuNavigation)/(home)/HomeFeed.tsx
Original file line number Diff line number Diff line change
@@ -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: () => <Skeleton className="my-2 h-[400px]" />,
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 (
<div className="flex flex-col">
{data && data.pages.flatMap((page) => page).map((post) => <PostCardDynamic key={post.id} post={post} />)}
{(isFetchingNextPage || isLoading) && <Loader className="mx-auto mt-10" />}
{!hasNextPage && !isLoading && (
<p className="p-4 pb-5 text-center text-neutral-500">Ваша лента закончилась</p>
)}
{error && (
<p className="text-center text-neutral-500">
Не удалось выполнить загрузку постов. Пожалуйста, повторите позже.
</p>
)}
<div ref={ref}></div>
</div>
);
}
24 changes: 12 additions & 12 deletions src/app/(auth)/(withMenuNavigation)/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Home timeBasedGreeting={getTimeBasedGreeting()} />;
}
16 changes: 4 additions & 12 deletions src/app/(auth)/(withMenuNavigation)/clubs/Clubs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use client';

import { m } from 'framer-motion';
import { useState } from 'react';
import { useDebounce } from 'use-debounce';

Expand All @@ -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('');
Expand Down Expand Up @@ -52,15 +51,8 @@ export function Clubs() {
{isLoading && <Loader className="mx-auto mt-10" />}
{clubs?.pages
.flatMap((page) => page)
.map((club, index) => (
<m.div
key={club.id}
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ delay: (index + 2.5) * 0.05, duration: 0.3, ease: 'easeOut' }}
>
<ClubCard club={club} showSubscribe />
</m.div>
.map((club) => (
<ClubCard key={club.id} club={club} showSubscribe />
))}
<div ref={ref}></div>
</div>
Expand Down
15 changes: 5 additions & 10 deletions src/app/(auth)/(withMenuNavigation)/clubs/[id]/Club.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<ClubHeader initClubData={club} />
<ClubHeader club={club} />
<ClubInfo club={club} />
<Page className="p-0">
<ClubFeed />
</Page>
<ClubReportDialogDynamic />
<ClubReportDialog />
</div>
);
}
Loading