Skip to content

Commit

Permalink
added users pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Andcool-Systems committed Jul 28, 2024
1 parent 345b785 commit 2d3911b
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const Admin = () => {
}, [logged]);

useEffect(() => {
authApi.get('users/me').then((response) => {
authApi.get('user/me').then((response) => {
if (response.status === 200) {
const data = response.data as Query;
if (!data.permissions.includes('admin')) {
Expand Down
12 changes: 6 additions & 6 deletions src/app/me/connections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const Main = () => {
queryKey: ["userConnections"],
retry: false,
queryFn: async () => {
const res = await authApi.get("users/me/connections", { withCredentials: true, validateStatus: () => true });
const res = await authApi.get("user/me/connections", { withCredentials: true, validateStatus: () => true });
const data = res.data as ConnectionResponse;

setConnected(data.minecraft !== null);
Expand Down Expand Up @@ -105,7 +105,7 @@ const Main = () => {
</div>
<div className={Style.checkboxes}>
<SlideButton value={valid} strict={true} onChange={(val) => {
authApi.put('users/me/connections/minecraft/set_valid', {}, {
authApi.put('user/me/connections/minecraft/set_valid', {}, {
params: {
state: val
}
Expand All @@ -116,7 +116,7 @@ const Main = () => {
})
}} label='Отображать ник в поиске' />
<SlideButton value={autoload} strict={true} onChange={(val) => {
authApi.put('users/me/connections/minecraft/set_autoload', {}, {
authApi.put('user/me/connections/minecraft/set_autoload', {}, {
params: {
state: val
}
Expand All @@ -133,7 +133,7 @@ const Main = () => {
<button className={Style.unlink} onClick={() => {
const load_icon = document.getElementById('refresh');
load_icon.style.animation = `${Style.loading} infinite 1s linear`;
authApi.post("users/me/connections/minecraft/cache/purge").then((response) => {
authApi.post("user/me/connections/minecraft/cache/purge").then((response) => {
if (response.status === 200) {
refetch();
return;
Expand All @@ -147,7 +147,7 @@ const Main = () => {
<button className={Style.unlink} onClick={() => {
const confirmed = confirm("Отвязать учётную запись Minecraft? Вы сможете в любое время привязать ее обратно.");
if (confirmed) {
authApi.delete('users/me/connections/minecraft').then((response) => {
authApi.delete('user/me/connections/minecraft').then((response) => {
if (response.status === 200) {
refetch();
return;
Expand All @@ -174,7 +174,7 @@ const Main = () => {
const target = document.getElementById('code') as HTMLInputElement;
if (target.value.length != 6) return;

authApi.post(`users/me/connections/minecraft/connect/${target.value}`).then((response) => {
authApi.post(`user/me/connections/minecraft/connect/${target.value}`).then((response) => {
if (response.status === 200) {
refetch();
return;
Expand Down
2 changes: 1 addition & 1 deletion src/app/me/notifications/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const Main = () => {

useEffect(() => {
if (page < 0) return;
authApi.get('users/me/notifications', { params: { page: page } }).then((response) => {
authApi.get('user/me/notifications', { params: { page: page } }).then((response) => {
if (response.status === 200) {
setNotifications(response.data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/me/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const Main = () => {

useEffect(() => {
if (isLogged) {
authApi.get("users/me/works").then((response) => {
authApi.get("user/me/works").then((response) => {
if (response.status === 200) {
setData(response.data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/me/stars/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Main = () => {
}

useEffect(() => {
authApi.get("users/me/stars").then((response) => {
authApi.get("user/me/stars").then((response) => {
if (response.status === 200) {
setData(response.data as Bandage[]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/card.module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const Card = ({ el, base64, className }: { el: Bandage, base64: string, c
<p className={Style.description}>{el.description}</p>
<div className={Style.categories}>{categories}</div>

<p className={Style.username}><img alt="" src="/static/icons/user.svg" style={{ width: "1.5rem" }} />{el.author.name || "Unknown"}</p>
<Link className={Style.username} href={`/users/${el.author.username}`}><img alt="" src="/static/icons/user.svg" style={{ width: "1.5rem" }} />{el.author.name || "Unknown"}</Link>
<p className={Style.creation_date}>{formatDate(new Date(el.creation_date))}</p>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/app/modules/header.module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const Header = (): JSX.Element => {
retry: 5,
refetchOnWindowFocus: false,
queryFn: async () => {
const res = await authApi.get("/users/me");
const res = await authApi.get("/user/me");
return res.data as Query;
},
});
Expand Down Expand Up @@ -103,7 +103,7 @@ const Header = (): JSX.Element => {
{islogged &&
<a className={Styles.menu_element}
onClick={() => {
authApi.delete("users/me").then(() => {
authApi.delete("user/me").then(() => {
deleteCookie("sessionId");
router.replace('/');
setIsLogged(false);
Expand Down
84 changes: 47 additions & 37 deletions src/app/modules/me.module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { timeStamp } from "./time.module";
import Footer from "./footer.module";
import { useCookies } from 'next-client-cookies';
import Menu from "./theme_select.module";
import { Users } from "../users/[name]/page";

const Default = ({ data, islogged, color }: { data: Query, islogged: boolean, color?: string }) => {
return (
Expand Down Expand Up @@ -50,7 +51,7 @@ const ImprovedTheme = ({ data, islogged }: { data: Query, islogged: boolean }) =
);
}

export const Me = ({ children }: { children: JSX.Element }) => {
export const Me = ({ children, user_data }: { children: JSX.Element, user_data?: Users }) => {
const [islogged, setIsLogged] = useState<boolean>(false);
const pathname = usePathname();
const path = pathname.split('/')[pathname.split('/').length - 1];
Expand All @@ -59,15 +60,18 @@ export const Me = ({ children }: { children: JSX.Element }) => {
const [theme, setTheme] = useState<number>(initial_theme);

const { data, isLoading, isError } = useQuery({
queryKey: ["userProfile"],
queryKey: [`user_${user_data?.username}`],
retry: 5,
queryFn: async () => {
const res = await authApi.get("/users/me", { withCredentials: true });
return res.data as Query;
if (!user_data) {
const res = await authApi.get("/user/me", { withCredentials: true });
return res.data as Query;
} else {
return user_data;
}

},
});

if (!isLoading && !isError && !islogged && data) {
setIsLogged(true);
}
Expand All @@ -79,53 +83,59 @@ export const Me = ({ children }: { children: JSX.Element }) => {
let background;
switch (theme) {
case 1:
background = <ImprovedTheme data={data} islogged={islogged} />;
background = <ImprovedTheme data={data as Query} islogged={islogged} />;
break;
case 2:
background = <Default data={data} islogged={islogged} color={data?.banner_color} />;
background = <Default data={data as Query} islogged={islogged} color={data?.banner_color} />;
break;
default:
background = <Default data={data} islogged={islogged} />;
background = <Default data={data as Query} islogged={islogged} />;
break;
}

if (!!user_data) {
background = <Default data={data as Query} islogged={islogged} />;
}

return (
<div className={style_sidebar.main_container}>
<div style={islogged ? { opacity: "1", transform: "translateY(0)" } : {}} className={style_sidebar.hidable}>
<div className={style_sidebar.main}>
<div className={style_sidebar.side}>
<div style={{ position: 'relative' }}>
{background}
<Menu initialValue={initial_theme} color_available={!!data?.banner_color} onChange={setTheme} />
</div>
<div className={style_sidebar.card} style={{ alignItems: "stretch", gap: ".5rem" }}>
<Link href="/me" className={`${style_sidebar.side_butt} ${path == 'me' && style_sidebar.active}`}>
<Image src="/static/icons/list.svg" alt="" width={24} height={24} />
Мои работы
</Link>
<Link href="/me/stars" className={`${style_sidebar.side_butt} ${path == 'stars' && style_sidebar.active}`}>
<Image src="/static/icons/star_bw.svg" alt="" width={24} height={24} />
Избранное
</Link>
<Link href="/me/notifications" className={`${style_sidebar.side_butt} ${path == 'notifications' && style_sidebar.active}`}>
<Image src="/static/icons/bell.svg" alt="" width={24} height={24} />
Уведомления
{data?.has_unreaded_notifications &&
<span style={{
backgroundColor: '#1bd96a',
width: '8px',
height: '8px',
marginLeft: '5px',
marginTop: '2px',
borderRadius: '50%'
}} />
}
</Link>
<Link href="/me/connections" className={`${style_sidebar.side_butt} ${path == 'connections' && style_sidebar.active}`}>
<Image src="/static/icons/block.svg" alt="" width={24} height={24} />
Интеграции
</Link>
{!user_data && <Menu initialValue={initial_theme} color_available={!!data?.banner_color} onChange={setTheme} />}
</div>
{!user_data &&
<div className={style_sidebar.card} style={{ alignItems: "stretch", gap: ".5rem" }}>
<Link href="/me" className={`${style_sidebar.side_butt} ${path == 'me' && style_sidebar.active}`}>
<Image src="/static/icons/list.svg" alt="" width={24} height={24} />
Мои работы
</Link>
<Link href="/me/stars" className={`${style_sidebar.side_butt} ${path == 'stars' && style_sidebar.active}`}>
<Image src="/static/icons/star_bw.svg" alt="" width={24} height={24} />
Избранное
</Link>
<Link href="/me/notifications" className={`${style_sidebar.side_butt} ${path == 'notifications' && style_sidebar.active}`}>
<Image src="/static/icons/bell.svg" alt="" width={24} height={24} />
Уведомления
{(data as Query)?.has_unreaded_notifications &&
<span style={{
backgroundColor: '#1bd96a',
width: '8px',
height: '8px',
marginLeft: '5px',
marginTop: '2px',
borderRadius: '50%'
}} />
}
</Link>
<Link href="/me/connections" className={`${style_sidebar.side_butt} ${path == 'connections' && style_sidebar.active}`}>
<Image src="/static/icons/block.svg" alt="" width={24} height={24} />
Интеграции
</Link>
</div>
}
</div>
{children}
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/app/styles/workshop/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@
align-items: center;
margin-bottom: 0;
color: var(--main-text-color);
margin-top: 1rem;
text-decoration: none;
}

.username:hover {
text-decoration: underline;
}

.description {
Expand Down
70 changes: 70 additions & 0 deletions src/app/users/[name]/client_code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";

import Header from "@/app/modules/header.module";
import { Users } from "./page";
import style_sidebar from "@/app/styles/me/sidebar.module.css";
import { useEffect, useRef, useState } from "react";
import { Bandage } from "@/app/interfaces";
import { SkinViewer } from "skinview3d";
import { Card, generateSkin } from "@/app/modules/card.module";
import styles from "@/app/styles/me/me.module.css";
import { Me } from "@/app/modules/me.module";
import Link from "next/link";

const UsersClient = ({ user }: { user: Users }) => {
const [elements, setElements] = useState<JSX.Element[]>(null);

useEffect(() => {
if (user.works) {
const skinViewer = new SkinViewer({
width: 300,
height: 300,
renderPaused: true
});
skinViewer.camera.rotation.x = -0.4;
skinViewer.camera.rotation.y = 0.8;
skinViewer.camera.rotation.z = 0.29;
skinViewer.camera.position.x = 17;
skinViewer.camera.position.y = 6.5;
skinViewer.camera.position.z = 11;
skinViewer.loadBackground("/static/background.png").then(() => {
Promise.all(user?.works.map(async (el) => {
try {
console.log(el.base64)
const result = await generateSkin(el.base64, Object.values(el.categories).some(val => val.id == 3));
console.log(result)
await skinViewer.loadSkin(result);
skinViewer.render();
const image = skinViewer.canvas.toDataURL();
return <Card el={el} base64={image} key={el.id} className={styles} />
} catch (e) {
console.error(e)
return;
}
}))
.then(results => setElements(results))
.catch(error => console.error('Error generating skins', error))
.finally(() => skinViewer.dispose());
});
}
}, []);

return (
<body>
<title>{`${user.name} · Повязки Pepeland`}</title>
<Header />
<Me user_data={user}>
<div style={elements ? { opacity: "1", transform: "translateY(0)" } : { opacity: "0", transform: "translateY(50px)" }} className={styles.cont}>
<div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
<div className={style_sidebar.skins_container}>
{elements}
</div>
</div>
</div>
</Me>

</body>
);
}

export default UsersClient;
48 changes: 48 additions & 0 deletions src/app/users/[name]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Bandage } from "@/app/interfaces";
import NotFound from "@/app/not-found";
import axios from "axios";
import { redirect } from "next/navigation";
import UsersClient from "./client_code";
import { headers } from "next/headers";

export interface Users {
userID: number,
discordID: number,
username: string,
name: string,
joined_at: Date,
avatar: string,
banner_color: string,
works: Bandage[],
is_self: boolean
}

const Users = async ({ params }: { params: { name: string } }) => {
const headersList = headers()
const cookie = headersList.get('Cookie');
const userAgent = headersList.get('User-Agent');

const data_request = await axios.get(`${process.env.NEXT_PUBLIC_GLOBAL_API_URL}users/${params.name}`, {
withCredentials: true,
validateStatus: () => true,
headers: {
"Cookie": cookie,
"User-Agent": userAgent,
"Unique-Access": process.env.TOKEN
}
});

if (data_request.status !== 200) {
return <NotFound />
}

const data = data_request.data as Users;
if (data.is_self) {
redirect('/me');
}

return <UsersClient user={data} />

}

export default Users;
7 changes: 7 additions & 0 deletions src/app/users/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { redirect } from "next/navigation";

const Users = () => {
redirect('/');
}

export default Users;
Loading

0 comments on commit 2d3911b

Please sign in to comment.