Skip to content

Commit

Permalink
Merge pull request #141 from xi-effect/staging
Browse files Browse the repository at this point in the history
Frontend Prod update №6 (22.10.24) #141
  • Loading branch information
unknownproperty authored Oct 22, 2024
2 parents 2b367f6 + caf29ab commit 88bf28a
Show file tree
Hide file tree
Showing 112 changed files with 6,290 additions and 4,975 deletions.
20 changes: 20 additions & 0 deletions apps/xi.front/app/(common)/confirm-email/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import dynamic from 'next/dynamic';
import { EmailConfirmation } from 'pkg.email-confirmation';
import React from 'react';

const Logo = dynamic(() => import('pkg.logo').then((mod) => mod.Logo), { ssr: false });

export default function ConfirmEmailPage() {
return (
<div className="flex flex-wrap flex-col justify-center content-center w-screen h-[100dvh] xs:h-screen p-1">
<div className="flex flex-col py-12 xl:py-24 h-full px-6 w-full">
<div className="flex justify-center items-center h-8 p-1">
<Logo width={134} height={16} logoSize="default" logoVariant="navigation" />
</div>
<div className="shrink-0 h-full flex flex-col justify-center items-center">
<EmailConfirmation />
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React from 'react';
import dynamic from 'next/dynamic';

const Board = dynamic(() => import('pkg.module.board').then((mod) => mod.Board), {
const BoardProvider = dynamic(() => import('pkg.module.board').then((mod) => mod.BoardProvider), {
ssr: false,
});

Expand All @@ -13,7 +13,7 @@ export default function BoardPage() {
id="whiteboard-container"
className="w-full md:w-[calc(100vw-350px)] md:min-h-screen md:h-screen md:overflow-auto bg-gray-0"
>
<Board />
<BoardProvider />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import React from 'react';
import dynamic from 'next/dynamic';

export default function Chats() {
const Chat = dynamic(() => import('pkg.module.chat').then((mod) => mod.Chat));

export default function ChatPage() {
return (
<div className="w-full md:w-[calc(100vw-350px)] md:min-h-screen md:h-screen md:overflow-auto bg-gray-0">
chat
<div
id="chat-container"
className="w-full md:w-[calc(100vw-350px)] md:min-h-screen md:h-screen md:overflow-auto bg-gray-0 overflow-x-hidden"
>
<Chat />
</div>
);
}
109 changes: 80 additions & 29 deletions apps/xi.front/app/(protected)/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { ReactNode, useEffect, useState } from 'react';
import { redirect, useParams, usePathname, useRouter } from 'next/navigation';
import { useGetUrlWithParams } from 'pkg.utils.client';
import { useMainSt } from 'pkg.stores';
import { toast } from 'sonner';

import Error404 from 'app/not-found';
import Forbidden403 from 'app/forbidden';
Expand All @@ -15,6 +16,7 @@ type ProtectedProviderPropsT = {

const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
const [errorCode, setErrorCode] = useState<number | null>(null);
const [redirecting, setRedirecting] = useState<boolean>(false);

const params = useParams<{ 'community-id': string }>();

Expand All @@ -23,6 +25,7 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
const updateCommunityMeta = useMainSt((state) => state.updateCommunityMeta);
const communityMeta = useMainSt((state) => state.communityMeta);
const onboardingStage = useMainSt((state) => state.user.onboardingStage);
const communities = useMainSt((state) => state.communities);
const channels = useMainSt((state) => state.channels);

const isLogin = useMainSt((state) => state.isLogin);
Expand All @@ -32,25 +35,34 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
const getUrlWithParams = useGetUrlWithParams();

useEffect(() => {
if (channels === null) return;

const channelIds = channels?.map(({ id }) => id);
if (params['channel-id'] && !channelIds?.includes(Number(params['channel-id']))) {
console.log('403');
setErrorCode(403);
}
}, [params, channels]);

useEffect(() => {
if (onboardingStage !== 'completed') return;

// Если 403 ошибка, не перенапрвляем сразу на страницу доступного сообщества
// Если ошибка, не перенаправляем сразу на страницу доступного сообщества.
if (errorCode !== null) return;

if (communities?.length === 0 && communityMeta.id === null && !pathname.includes('/empty')) {
toast('Вы не состоите ни в одном сообществе');
setRedirecting(true);
router.replace(getUrlWithParams('/empty'));
return;
}

if (socket?.connected === false && typeof params['community-id'] !== 'string') {
// Если мы не знаем id текущего сообщества, мы получаем любое и редиректим туда пользователя
socket?.on('connect', () => {
socket.emit(
'retrieve-any-community',
(status: number, { community, participant }: { community: any; participant: any }) => {
console.log('11', community, participant);
if (status === 200) {
updateCommunityMeta({
id: community.id,
Expand Down Expand Up @@ -81,31 +93,6 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
return;
}

// Если мы не знаем id текущего сообщества, но соединение сокета уже установлено
if (socket?.connected === true && communityMeta.id === null) {
socket.emit(
'retrieve-any-community',
(status: number, { community, participant }: { community: any; participant: any }) => {
if (status === 200) {
updateCommunityMeta({
id: community.id,
isOwner: participant.is_owner,
name: community.name,
description: community.description,
});
}

if (community && community.id) {
router.push(getUrlWithParams(`/communities/${community.id}/home`));
}

return null;
},
);

return;
}

// Если мы уже знаем из url id сообщества, то нам нужно запросить данные по нему
if (socket?.connected === false && typeof params['community-id'] === 'string') {
socket?.on('connect', () => {
Expand Down Expand Up @@ -137,6 +124,42 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
return;
}

// Если мы не знаем id текущего сообщества, но соединение сокета уже установлено
if (socket?.connected === true && communityMeta.id === null) {
socket.emit(
'retrieve-any-community',
(status: number, { community, participant }: { community: any; participant: any }) => {
if (status === 200) {
updateCommunityMeta({
id: community.id,
isOwner: participant.is_owner,
name: community.name,
description: community.description,
});
} else if (status === 404) {
router.replace(getUrlWithParams('/empty'));
}

const pathnameArr = pathname.split('/');
if (pathnameArr.includes('channels') && community.id) {
const betweenChannels = pathname.split('channels');

return router.push(
getUrlWithParams(`/communities/${community.id}/channels${betweenChannels[1]}`),
);
}

if (community && community.id) {
router.push(getUrlWithParams(`/communities/${community.id}/home`));
}

return null;
},
);

return;
}

// Если мы знаем id текущего сообщества из url, но соединение сокета уже установлено
if (socket?.connected === true && communityMeta.id === null) {
socket.emit(
Expand All @@ -161,6 +184,34 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {
}
}, [socket?.connected]);

useEffect(() => {
if (socket?.connected) {
socket.on('delete-community', (deletedCommunity) => {
if (deletedCommunity.community_id === communityMeta.id) {
updateCommunityMeta({
id: null,
isOwner: false,
name: '',
description: '',
});
toast('Сообщество удалено');
router.replace(getUrlWithParams('/communities'));
window.location.reload();
}
});
}

if (socket?.connected) {
socket.on('kicked-from-community', (kickedCommunity) => {
if (kickedCommunity.community_id === communityMeta.id) {
toast(`Вы исключены из сообщества ${communityMeta.name}`);
router.replace(getUrlWithParams('/communities'));
window.location.reload();
}
});
}
}, [socket?.connected, communityMeta.id]);

useEffect(() => {
if (pathname !== '/communities' || (pathname === '/communities' && isLogin === null)) {
if (isLogin === false) {
Expand All @@ -184,11 +235,11 @@ const ProtectedProvider = ({ children }: ProtectedProviderPropsT) => {

if (isLogin === null) return <Load />;

if (errorCode === 403) {
if (!redirecting && errorCode === 403) {
return <Forbidden403 />;
}

if (errorCode === 404) {
if (!redirecting && errorCode === 404) {
return <Error404 />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,6 @@ export default function WelcomeCommunityCreate() {
const { status } = await put<RequestBody, ResponseBody>({
service: 'auth',
path: '/api/onboarding/stages/completed/',
body: {},
config: {
headers: {
'Content-Type': 'application/json',
},
},
});

updateCommunityMeta({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ export default function WelcomeCommunityInvite() {
const { status } = await put<RequestBody, ResponseBody>({
service: 'auth',
path: '/api/onboarding/stages/completed/',
body: {},
config: {
headers: {
'Content-Type': 'application/json',
},
},
});

updateCommunityMeta({
Expand Down
18 changes: 0 additions & 18 deletions apps/xi.front/app/(protected)/welcome/community/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ export default function WelcomeCommunity() {
const { status } = await put<RequestBody, ResponseBody>({
service: 'auth',
path: '/api/onboarding/stages/community-create/',
body: {},
config: {
headers: {
'Content-Type': 'application/json',
},
},
});

if (status === 204) {
Expand All @@ -55,12 +49,6 @@ export default function WelcomeCommunity() {
const { status } = await put<RequestBody, ResponseBody>({
service: 'auth',
path: '/api/onboarding/stages/community-invite/',
body: {},
config: {
headers: {
'Content-Type': 'application/json',
},
},
});

if (status === 204) {
Expand All @@ -75,12 +63,6 @@ export default function WelcomeCommunity() {
const { status } = await put<RequestBody, ResponseBody>({
service: 'auth',
path: '/api/onboarding/stages/community-invite/',
body: {},
config: {
headers: {
'Content-Type': 'application/json',
},
},
});

if (status === 204) {
Expand Down
12 changes: 0 additions & 12 deletions apps/xi.front/app/(public)/confirm-email/[id]/page.tsx

This file was deleted.

12 changes: 11 additions & 1 deletion apps/xi.front/app/(public)/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { ReactNode, useEffect } from 'react';

import { redirect } from 'next/navigation';
import { useMainSt } from 'pkg.stores';
import { useTheme } from 'next-themes';
import Load from '../load';

type PublicProviderPropsT = {
Expand All @@ -13,9 +14,18 @@ type PublicProviderPropsT = {
const PublicProvider = ({ children }: PublicProviderPropsT) => {
const getUser = useMainSt((state) => state.getUser);
const isLogin = useMainSt((state) => state.isLogin);
const { setTheme } = useTheme();

useEffect(() => {
getUser();
const fetchUserData = async () => {
const get = await getUser();

if (get.theme !== null) {
setTheme(get.theme);
}
};

fetchUserData();
}, []);

useEffect(() => {
Expand Down
9 changes: 7 additions & 2 deletions apps/xi.front/app/forbidden.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { useRouter } from 'next/navigation';
export default function Forbidden403() {
const router = useRouter();

const handleBack = () => {
router.back();
router.refresh();
};

return (
<ErrorPage
title="Доступ запрещён"
Expand All @@ -18,12 +23,12 @@ export default function Forbidden403() {
<button
type="button"
className="decoration-brand-20 hover:decoration-brand-100 text-brand-80 hover:text-brand-100 underline underline-offset-4 bg-transparent"
onClick={() => router.back()}
onClick={handleBack}
>
назад
</button>
&nbsp;или&nbsp;
<Link theme="brand" size="l" href="/" target="_blank">
<Link theme="brand" size="l" href="/">
на главную
</Link>
</p>
Expand Down
4 changes: 2 additions & 2 deletions apps/xi.front/app/global-error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import { ErrorPage } from 'pkg.error-page';
import * as Sentry from '@sentry/nextjs';
import Error from 'next/error';
import { useEffect } from 'react';
import React from 'react';

export default function Error500({ error }: { error: Error }) {
useEffect(() => {
React.useEffect(() => {
Sentry.captureException(error);
}, [error]);

Expand Down
Loading

0 comments on commit 88bf28a

Please sign in to comment.