+
+
-
-
-
-
-
- Open Source Task Tracker
-
-
-
-
- Войти
-
-
- Регистрация
-
-
-
-
-
-
- Планируйте спринты и держите фокус команды в одной команде
-
-
- Один трекер для продукта, разработки и QA. Все статусы и приоритеты прозрачны в
- реальном времени.
-
-
-
-
-
-
-
-
-
- С чего начать
-
-
- Три шага до первого спринта
-
-
-
- Создать аккаунт
-
-
- У меня уже есть аккаунт
-
-
-
-
-
-
- 01. Создайте проект
-
-
- 02. Добавьте команду
-
-
- 03. Запустите спринт
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/pages/profile/api/useConnectedAccounts.ts b/src/pages/profile/api/useConnectedAccounts.ts
deleted file mode 100644
index 8518a9d..0000000
--- a/src/pages/profile/api/useConnectedAccounts.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-'use client';
-import { useQuery } from '@tanstack/react-query';
-import { AuthQueries } from 'entities/auth';
-import { useMemo } from 'react';
-
-export function useConnectedAccounts() {
- const available = useQuery(AuthQueries.getOAuthProviders());
- const connected = useQuery(AuthQueries.getConnectedOAuthProviders());
-
- const providers = useMemo(() => {
- if (!available.data) return [];
-
- const connectedSet = new Set(connected.data?.map((v) => v.provider));
-
- return available.data.map((item) => ({
- ...item,
- isConnected: connectedSet.has(item.value),
- }));
- }, [available.data, connected.data]);
-
- return { providers };
-}
diff --git a/src/pages/profile/config/tabs.ts b/src/pages/profile/config/tabs.ts
deleted file mode 100644
index 1ae5728..0000000
--- a/src/pages/profile/config/tabs.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { routes } from 'shared/config';
-
-export const profileTabs = [
- { key: routes.user.profile(), label: 'Мой профиль' },
- { key: routes.user.security(), label: 'Безопасность' },
- { key: routes.user.notifications(), label: 'Уведомления' },
-];
diff --git a/src/pages/profile/index.ts b/src/pages/profile/index.ts
deleted file mode 100644
index 8922138..0000000
--- a/src/pages/profile/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { profileTabs } from './config/tabs';
-export { MePage } from './ui/me-page/MePage';
-export { NotificationsPage } from './ui/notifications-page/NotificationsPage';
-export { SecurityPage } from './ui/security-page/SecurityPage';
diff --git a/src/pages/profile/ui/me-page/IdentityItem.tsx b/src/pages/profile/ui/me-page/IdentityItem.tsx
deleted file mode 100644
index e7475c0..0000000
--- a/src/pages/profile/ui/me-page/IdentityItem.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-'use client';
-
-import { Item, ItemActions, ItemContent, ItemMedia } from 'shared/ui';
-import { UploadAvatar } from 'features/upload-avatar';
-import { SignOut } from 'features/auth/sign-out';
-import { type TUser, UserAvatar } from 'entities/user';
-
-type AccountIdentityItemProps = {
- profile: TUser.UserResponse['profile'];
- email: string;
-};
-
-function IdentityItem({ profile, email }: AccountIdentityItemProps) {
- const fullName = `${profile.firstName} ${profile.lastName}`;
-
- return (
-
-
-
-
- }
- />
-
-
-
-
{fullName}
-
{email}
-
- {profile.bio?.trim() || 'Добавьте информацию о себе в профиле'}
-
-
-
-
-
-
-
- );
-}
-
-export { IdentityItem };
diff --git a/src/pages/profile/ui/me-page/MePage.tsx b/src/pages/profile/ui/me-page/MePage.tsx
deleted file mode 100644
index 97952ff..0000000
--- a/src/pages/profile/ui/me-page/MePage.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-'use client';
-
-import {
- Card,
- CardDescription,
- CardHeader,
- CardSection,
- CardTitle,
- FloatingSaveBar,
- Separator,
-} from 'shared/ui';
-import { IdentityItem } from './IdentityItem';
-import { ProfileForm } from './ProfileForm';
-import { useMePage } from '../../model/useMePage';
-import { AccountSection } from './account-section/AccountsSection';
-import { Suspense } from 'react';
-import { QueryParamsHandler } from 'features/handle-query-params';
-
-function MePage() {
- const { form, profile, email, isDirty, isPending, onSubmit, onDiscard } = useMePage();
-
- if (!profile || !email) {
- return (
-
-
- Профиль
- Данные профиля пока недоступны.
-
-
- );
- }
-
- return (
- <>
-
-
-
-
- >
- );
-}
-
-export { MePage };
diff --git a/src/pages/profile/ui/me-page/account-section/AccountsSection.tsx b/src/pages/profile/ui/me-page/account-section/AccountsSection.tsx
deleted file mode 100644
index 1744497..0000000
--- a/src/pages/profile/ui/me-page/account-section/AccountsSection.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { OAuthManageButton } from './OAuthManageButton';
-import { useConnectedAccounts } from '../../../api/useConnectedAccounts';
-import { CardSection } from 'shared/ui';
-
-export function AccountSection() {
- const { providers } = useConnectedAccounts();
-
- return (
-
- {providers?.map((provider) => {
- return (
-
- );
- })}
-
- );
-}
diff --git a/src/pages/profile/ui/me-page/account-section/OAuthManageButton.tsx b/src/pages/profile/ui/me-page/account-section/OAuthManageButton.tsx
deleted file mode 100644
index d2a3d4f..0000000
--- a/src/pages/profile/ui/me-page/account-section/OAuthManageButton.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import { authFabricKeys, OAUTH_PROVIDERS, type TAuth } from 'entities/auth';
-import { type ComponentProps, useCallback } from 'react';
-import { Button } from 'shared/ui';
-import { useConnectOAuthProvider } from '../../../api/useConnectOauthProvider';
-import { useDisconnectOAuthProvider } from '../../../api/useDisconnectOauthProvider';
-import { env } from 'shared/config';
-import { toast } from 'sonner';
-import Image from 'next/image';
-
-type OAuthManageButtonProps = ComponentProps
& {
- provider: TAuth.OAuthProvider;
- label: string;
- isLinked: boolean;
-};
-
-export function OAuthManageButton({ provider, label, isLinked, ...props }: OAuthManageButtonProps) {
- const connect = useConnectOAuthProvider();
- const disconnect = useDisconnectOAuthProvider();
-
- const isLoading = connect.isPending || disconnect.isPending;
-
- const handleToggleConnect = useCallback(() => {
- if (isLinked) {
- disconnect.mutate(provider, {
- onSuccess: (data, _v, _m, context) => {
- context.client.invalidateQueries({ queryKey: authFabricKeys.connectedProviders() });
- toast.success(data.message);
- },
- });
- } else {
- connect.mutate(provider, {
- onSuccess: (data) => {
- const url = data.url.startsWith('http')
- ? data.url
- : new URL(data.url, env.NEXT_PUBLIC_API_BASE_URL).toString();
- window.location.href = url;
- },
- });
- }
- }, [connect, disconnect, isLinked, provider]);
-
- const meta = OAUTH_PROVIDERS[provider];
-
- return (
-
-
-
-
-
- {isLinked ? 'Отвязать' : 'Привязать'} {label} аккаунт
-
-
- );
-}
diff --git a/src/pages/profile/ui/security-page/SecurityPage.tsx b/src/pages/profile/ui/security-page/SecurityPage.tsx
deleted file mode 100644
index bb2f9f5..0000000
--- a/src/pages/profile/ui/security-page/SecurityPage.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-'use client';
-
-import { CardSection, OptionItem, Separator, Switch } from 'shared/ui';
-import { formatDate } from 'shared/lib/utils';
-import { useQuery } from '@tanstack/react-query';
-import { UserQueries } from 'entities/user';
-
-function SecurityPage() {
- const query = useQuery(UserQueries.getMe());
- const is2faEnabled = query.data?.security.is2faEnabled ?? false;
- const lastPasswordChange = formatDate(query.data?.security.lastPasswordChange ?? '');
-
- return (
-
- (
-
- )}
- />
-
-
- Последняя смена пароля
- {lastPasswordChange}
-
-
- );
-}
-
-export { SecurityPage };
diff --git a/src/pages/profile/ui/teams-page/TeamList.tsx b/src/pages/profile/ui/teams-page/TeamList.tsx
deleted file mode 100644
index fbf5b00..0000000
--- a/src/pages/profile/ui/teams-page/TeamList.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { useQuery } from '@tanstack/react-query';
-import { TeamAvatar, useTeamStore } from 'entities/team';
-import { UserQueries } from 'entities/user';
-import { RemoveTeamDialog } from 'features/teams/remove';
-import { Trash2Icon } from 'lucide-react';
-import {
- Badge,
- Button,
- Item,
- ItemActions,
- ItemContent,
- ItemDescription,
- ItemMedia,
- ItemTitle,
-} from 'shared/ui';
-import { useSwitchTeam } from 'features/teams/active-team';
-
-export function TeamsList() {
- const teamsQuery = useQuery(UserQueries.getMyTeams());
- const teamId = useTeamStore.use.teamId();
-
- const { switchTeam } = useSwitchTeam({
- teams: teamsQuery.data,
- defaultOptions: { redirect: true },
- });
-
- if (teamsQuery.isError) {
- return (
-
- {teamsQuery.error.message}
-
- );
- }
-
- const teams = teamsQuery.data ?? [];
-
- return (
-
- {teams.map((team) => (
-
- -
- {team.permissions.isOwner ? (
-
- Owner
-
- ) : null}
-
-
-
-
- {team.name}
- {team.description}
-
-
-
-
-
-
-
-
- switchTeam(team.id)}
- disabled={teamId === team.id}
- >
- {teamId === team.id ? 'Текущая' : 'Перейти'}
-
-
-
-
-
- ))}
-
- );
-}
diff --git a/src/pages/project/boards/ui/column/ColumnHeaderActions.tsx b/src/pages/project/boards/ui/column/ColumnHeaderActions.tsx
index e080aef..aa15462 100644
--- a/src/pages/project/boards/ui/column/ColumnHeaderActions.tsx
+++ b/src/pages/project/boards/ui/column/ColumnHeaderActions.tsx
@@ -30,7 +30,7 @@ export function ColumnHeaderActions({
return (
-
+
diff --git a/src/pages/project/boards/ui/task/TaskCard.tsx b/src/pages/project/boards/ui/task/TaskCard.tsx
index 8036629..7479004 100644
--- a/src/pages/project/boards/ui/task/TaskCard.tsx
+++ b/src/pages/project/boards/ui/task/TaskCard.tsx
@@ -40,7 +40,6 @@ export function TaskCard({ task, onClick }: TaskCardProps) {