Merge pull request #25 from gractwo/ehrmantraut
profilecards for /ja & /profil pages
This commit is contained in:
@@ -91,7 +91,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
@media screen and (max-width: 860px) {
|
||||
.nav {
|
||||
height: 3rem;
|
||||
}
|
||||
@@ -101,6 +101,12 @@
|
||||
.mobile {
|
||||
display: inherit;
|
||||
}
|
||||
.menumobile {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.logoutmobile {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* FOR TESTING MOBILE NAV WITHOUT DEVTOOLS */
|
||||
|
||||
@@ -27,7 +27,10 @@ const Navigation = () => {
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
<div tabIndex={0} className={`${styles.dropdown} ${styles.mobile}`}>
|
||||
<div
|
||||
tabIndex={0}
|
||||
className={`${styles.dropdown} ${styles.mobile} ${styles.menumobile}`}
|
||||
>
|
||||
<Icon icon="Menu" />
|
||||
{/* TUTAJ WSTAWIĆ IKONKĘ PÓŹNIEJ */}
|
||||
<div className={styles.innerdropdown}>
|
||||
@@ -68,7 +71,7 @@ const Navigation = () => {
|
||||
{!isLoading && user && (
|
||||
<Link
|
||||
href="/api/auth/logout"
|
||||
className={`${styles.link} ${styles.partprofile}`}
|
||||
className={`${styles.link} ${styles.partprofile} ${styles.logoutmobile}`}
|
||||
>
|
||||
<Icon icon="LogOut" />
|
||||
</Link>
|
||||
|
||||
108
components/ProfileCard/ProfileCard.module.scss
Normal file
108
components/ProfileCard/ProfileCard.module.scss
Normal file
@@ -0,0 +1,108 @@
|
||||
.profile {
|
||||
margin: 2rem 0;
|
||||
background: var(--black1);
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--shadow0);
|
||||
article {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 1.5rem 1.5rem 1rem 1.5rem;
|
||||
gap: 1rem;
|
||||
background-color: var(--black2);
|
||||
border-radius: 8px 8px 0 0;
|
||||
@media screen and (max-width: 400px) {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
img {
|
||||
border-radius: 50%;
|
||||
height: 128px;
|
||||
width: 128px;
|
||||
aspect-ratio: 1 / 1;
|
||||
object-fit: cover;
|
||||
object-position: 50% 35%;
|
||||
@media screen and (max-width: 600px) {
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
}
|
||||
.inner {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
p {
|
||||
font-family: var(--fonts-bold);
|
||||
span {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.badges {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
margin: 8px 0;
|
||||
margin-top: auto;
|
||||
.badge {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: initial;
|
||||
gap: 8px;
|
||||
padding: 4px 8px;
|
||||
background: rgba(white, 0.1);
|
||||
border-radius: 4px;
|
||||
.dot {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background-color: #fb636b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.xpinfo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
background: var(--black2);
|
||||
color: #ababab;
|
||||
padding: 0 14px;
|
||||
}
|
||||
.xpbar {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
background: rgba(white, 0.025);
|
||||
.xpinner {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 99%;
|
||||
background: #fb636b;
|
||||
opacity: 75%;
|
||||
}
|
||||
}
|
||||
footer {
|
||||
min-height: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
section {
|
||||
width: 50%;
|
||||
padding: 2rem;
|
||||
@media screen and (max-width: 800px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
components/ProfileCard/ProfileCard.tsx
Normal file
116
components/ProfileCard/ProfileCard.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import styles from "./ProfileCard.module.scss";
|
||||
|
||||
type UserProfileCardProps = {
|
||||
data: {
|
||||
username: string;
|
||||
description?: string;
|
||||
picture?: string | null;
|
||||
isAdmin?: boolean;
|
||||
isDeveloper?: boolean;
|
||||
experience?: {
|
||||
level: number;
|
||||
tilNextLevel?: number;
|
||||
looseXP?: number;
|
||||
};
|
||||
badges?: {
|
||||
badgeName: string;
|
||||
badgeDesc?: string;
|
||||
badgeMerit?: string;
|
||||
badgeImage?: string;
|
||||
}[];
|
||||
accentColor?: string;
|
||||
};
|
||||
};
|
||||
|
||||
const ProfileCard = ({ data }: UserProfileCardProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.profile}>
|
||||
<article>
|
||||
<img
|
||||
src={data.picture || "https://placewaifu.com/image/128"}
|
||||
alt={data.username}
|
||||
/>
|
||||
<div className={styles.inner}>
|
||||
<header>
|
||||
<h1>{data.username}</h1>
|
||||
<p>
|
||||
{data.experience?.level && (
|
||||
<>
|
||||
{"LVL "}
|
||||
<span>{data.experience.level}</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</header>
|
||||
<p>{data.description}</p>
|
||||
<div className={styles.badges}>
|
||||
{data.isAdmin && (
|
||||
<div className={styles.badge}>
|
||||
<div
|
||||
className={styles.dot}
|
||||
style={{ background: data.accentColor }}
|
||||
/>
|
||||
Admin
|
||||
</div>
|
||||
)}
|
||||
{data.isDeveloper && (
|
||||
<div className={styles.badge}>
|
||||
<div
|
||||
className={styles.dot}
|
||||
style={{ background: data.accentColor }}
|
||||
/>
|
||||
Developer
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{data.experience?.looseXP && data.experience.tilNextLevel && (
|
||||
<div className={styles.xpinfo}>
|
||||
<p>XP: {data.experience.looseXP}</p>
|
||||
<p>XP until next level: {data.experience.tilNextLevel} </p>
|
||||
</div>
|
||||
)}
|
||||
{data.experience?.looseXP && data.experience.tilNextLevel && (
|
||||
<div className={styles.xpbar}>
|
||||
<div
|
||||
className={styles.xpinner}
|
||||
style={{
|
||||
background: data.accentColor,
|
||||
width:
|
||||
(
|
||||
(data.experience.looseXP /
|
||||
(data.experience.looseXP +
|
||||
data.experience.tilNextLevel)) *
|
||||
100
|
||||
).toString() + "%",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<footer>
|
||||
{data.badges
|
||||
?.slice(0, 1)
|
||||
.map(
|
||||
(el: {
|
||||
badgeName: string;
|
||||
badgeDesc?: string;
|
||||
badgeMerit?: string;
|
||||
badgeImage?: string;
|
||||
}) => {
|
||||
return (
|
||||
<section key={el.badgeName}>
|
||||
<h3>{el.badgeName}</h3>
|
||||
<p>{el.badgeDesc}</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { ProfileCard };
|
||||
40
pages/ja.tsx
40
pages/ja.tsx
@@ -1,40 +0,0 @@
|
||||
import styles from "../styles/Ja.module.scss";
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
|
||||
const PageMe = () => {
|
||||
const { user, error, isLoading } = useUser();
|
||||
return (
|
||||
<>
|
||||
{isLoading && (
|
||||
<main>
|
||||
<h3>Ładujemy dane dla Ciebie...</h3>
|
||||
<p>Sit tight.</p>
|
||||
</main>
|
||||
)}
|
||||
{error && (
|
||||
<main>
|
||||
<h3>Wystąpił błąd.</h3>
|
||||
<p>Tyle wiemy.</p>
|
||||
</main>
|
||||
)}
|
||||
{!isLoading && !error && user && (
|
||||
<main>
|
||||
<div className={styles.header}>
|
||||
<img src={user.picture || ""} alt={`${user.name}'s picture`} />
|
||||
<h1>{user.name}</h1>
|
||||
</div>
|
||||
</main>
|
||||
)}
|
||||
{!isLoading && !user && (
|
||||
<main>
|
||||
<h1>/ja</h1>
|
||||
<p>
|
||||
Musisz być zalogowany aby skorzystać z funkcjonalności tej strony.
|
||||
</p>
|
||||
</main>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageMe;
|
||||
125
pages/ja/index.tsx
Normal file
125
pages/ja/index.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ProfileCard } from "../../components/ProfileCard/ProfileCard";
|
||||
import { SEO } from "../../components/SEO";
|
||||
|
||||
const PageMe = () => {
|
||||
const { user, error, isLoading } = useUser();
|
||||
type personsSchema = {
|
||||
Id: string;
|
||||
Name: string;
|
||||
Desc?: string;
|
||||
Img?: string;
|
||||
IsAdmin?: boolean;
|
||||
DevBadge?: boolean;
|
||||
AssignedUser?: string;
|
||||
};
|
||||
const [personsData, setPersonsData] = useState<personsSchema | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
fetch("https://gractwo.pl/api/v1/admincards")
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.then((data) => {
|
||||
setPersonsData(
|
||||
data.filter((el: personsSchema) => {
|
||||
if (!user) return false;
|
||||
return el.AssignedUser === user.sub?.replace("oauth2|discord|", "");
|
||||
})[0]
|
||||
);
|
||||
});
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading && (
|
||||
<main>
|
||||
<h3>Ładujemy dane dla Ciebie...</h3>
|
||||
<p>Sit tight.</p>
|
||||
</main>
|
||||
)}
|
||||
{error && (
|
||||
<main>
|
||||
<h3>Wystąpił błąd.</h3>
|
||||
<p>Tyle wiemy:</p>
|
||||
<p>{error.name}</p>
|
||||
<p>{error.message}</p>
|
||||
</main>
|
||||
)}
|
||||
{!isLoading && !error && user && (
|
||||
<main>
|
||||
<SEO title="twój profil" />
|
||||
<ProfileCard
|
||||
data={{
|
||||
username: user.name || "unknown user",
|
||||
picture: user.picture,
|
||||
description: personsData?.Desc || "twój opis.",
|
||||
isAdmin: personsData?.IsAdmin,
|
||||
isDeveloper: personsData?.DevBadge,
|
||||
// isAdmin: true,
|
||||
// experience: {
|
||||
// level: 69,
|
||||
// looseXP: 420,
|
||||
// tilNextLevel: 69,
|
||||
// },
|
||||
badges: [
|
||||
{
|
||||
badgeName: "Odkrywca internetowy",
|
||||
badgeDesc:
|
||||
"Logowanie się na gractwo.pl nie jest takie straszne.",
|
||||
},
|
||||
{
|
||||
badgeName: "Technik Informatyk",
|
||||
badgeDesc: "Łapanki na korytarzu to normalka.",
|
||||
},
|
||||
{
|
||||
badgeName: "Rozpad PGTF",
|
||||
badgeDesc: "Służba w oddziałach Super Pizzy - powód do dumy.",
|
||||
},
|
||||
{
|
||||
badgeName: "Mollin Stream",
|
||||
badgeDesc: "„Sorry, ja za bardzo nie pamietam.” ~ Mollin",
|
||||
},
|
||||
{
|
||||
badgeName: "Alkoholik",
|
||||
badgeDesc: "pracoholicy gdy skończy im się pracohol:",
|
||||
},
|
||||
{
|
||||
badgeName: "Studnia Oneshot",
|
||||
badgeDesc: "elf w studni - ciekawe jak stamtąd wyjdzie",
|
||||
},
|
||||
{
|
||||
badgeName: "RemCon 2022",
|
||||
badgeDesc: "pomorze konwent",
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<Link href="/ja/ustawienia">
|
||||
<button style={{ width: "100%", margin: 0, marginBottom: "12px" }}>
|
||||
Ustawienia Konta
|
||||
</button>
|
||||
</Link>
|
||||
{/* <Link href="/ja/ustawienia-profilu-publicznego">
|
||||
<button style={{ width: "100%", margin: 0, marginBottom: "12px" }}>
|
||||
Ustawienia Profilu Publicznego
|
||||
</button>
|
||||
</Link> */}
|
||||
</main>
|
||||
)}
|
||||
{!isLoading && !user && (
|
||||
<main>
|
||||
<h1>/ja</h1>
|
||||
<p>
|
||||
Musisz być zalogowany aby skorzystać z funkcjonalności tej strony.
|
||||
</p>
|
||||
</main>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageMe;
|
||||
42
pages/ja/ustawienia.tsx
Normal file
42
pages/ja/ustawienia.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { useUser } from "@auth0/nextjs-auth0/client";
|
||||
import { SEO } from "../../components/SEO";
|
||||
import styles from "../../styles/ustawienia.module.scss";
|
||||
|
||||
const PageMeSettings = () => {
|
||||
const { user, error, isLoading } = useUser();
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading && (
|
||||
<>
|
||||
<main>
|
||||
<h3>Ładowanie danych...</h3>
|
||||
</main>
|
||||
</>
|
||||
)}
|
||||
{error && (
|
||||
<main>
|
||||
<h3>Wystąpił błąd.</h3>
|
||||
<p>Tyle wiemy.</p>
|
||||
</main>
|
||||
)}
|
||||
{!isLoading && !error && user && (
|
||||
<>
|
||||
<main>
|
||||
<SEO title="ustawienia konta" />
|
||||
<h1>ustawienia konta</h1>
|
||||
<p>
|
||||
Kolor akcentowy <input type="color" name="" id="" />
|
||||
</p>
|
||||
</main>
|
||||
<main>
|
||||
<h3>uwaga: strona w trakcie budowy. funkcjonalność niegotowa.</h3>
|
||||
<button>Zapisz zmiany</button>
|
||||
</main>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageMeSettings;
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ProfileCard } from "../../../components/ProfileCard/ProfileCard";
|
||||
import { SEO } from "../../../components/SEO";
|
||||
|
||||
const ProfilePage = () => {
|
||||
@@ -43,37 +44,64 @@ const ProfilePage = () => {
|
||||
return wpis.Name.replaceAll(" ", "-").toLocaleLowerCase() === profname;
|
||||
})[0];
|
||||
return (
|
||||
<main>
|
||||
<>
|
||||
<SEO title={person.Name} />
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: "1rem",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={person.Img}
|
||||
alt={`${person.Name} profile image`}
|
||||
{/* <main>
|
||||
<div
|
||||
style={{
|
||||
width: "128px",
|
||||
aspectRatio: "1/1",
|
||||
objectFit: "cover",
|
||||
borderRadius: "50%",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: "1rem",
|
||||
margin: "2rem 0 0 0",
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<h1>{person.Name}</h1>
|
||||
<p>{person.Desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
>
|
||||
<img
|
||||
src={person.Img}
|
||||
alt={`${person.Name} profile image`}
|
||||
style={{
|
||||
width: "128px",
|
||||
aspectRatio: "1/1",
|
||||
objectFit: "cover",
|
||||
borderRadius: "50%",
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<h1>{person.Name}</h1>
|
||||
<p>{person.Desc}</p>
|
||||
</div>
|
||||
</div> */}
|
||||
{/* FOR LATER BIGDESC DATASET */}
|
||||
{/* {person.profile?.bigdesc.map((el, index) => {
|
||||
return <p key={index}>{el || <br />}</p>;
|
||||
})} */}
|
||||
</main>
|
||||
{/* </main> */}
|
||||
<main>
|
||||
<ProfileCard
|
||||
data={{
|
||||
username: person.Name,
|
||||
picture: person.Img,
|
||||
description: person.Desc,
|
||||
isAdmin: person.IsAdmin,
|
||||
isDeveloper: person.DevBadge,
|
||||
// accentColor: "violet",
|
||||
// experience: {
|
||||
// level: 69,
|
||||
// looseXP: 420,
|
||||
// tilNextLevel: 69,
|
||||
// },
|
||||
badges: [
|
||||
{
|
||||
badgeName: "Odkrywca internetowy",
|
||||
badgeDesc:
|
||||
"Logowanie się na gractwo.pl nie jest takie straszne.",
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
.header {
|
||||
margin: 2rem 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
img {
|
||||
height: 69px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,17 @@ button {
|
||||
// color: black;
|
||||
}
|
||||
}
|
||||
input {
|
||||
display: inline-block;
|
||||
font-size: 1rem;
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
background: rgba(white, 0.1);
|
||||
border: 0;
|
||||
color: white;
|
||||
outline: none;
|
||||
font-family: var(--fonts-norm);
|
||||
}
|
||||
|
||||
.chips {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user