Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] feat: more fields/data #24

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
25 changes: 22 additions & 3 deletions pages/api/users/[userId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import prisma from "../../../../lib/prisma";
import { Prisma } from "@prisma/client";
import { ModifiedSession } from "../../../../types/session";
import { BadRequest, InternalError, NoContent, Unauthenticated } from "../../../../utility/http";
import countries from "../../../../utility/countries"

const DeleteUserRoute = async (req: NextApiRequest, res: NextApiResponse) => {
const session = await getSession({ req });
if (!session?.user) return Unauthenticated(res);
const id = (session.user as ModifiedSession).id;

// Delete all bios & the user themself
if (req.method === "DELETE") {
const id = (session.user as ModifiedSession).id;

// Delete all bios & the user themself
try {
await prisma.user.delete({ where: { id } });
return NoContent(res);
Expand All @@ -25,6 +25,25 @@ const DeleteUserRoute = async (req: NextApiRequest, res: NextApiResponse) => {
console.error(e);
return InternalError(res);
}
} else if (req.method === "PATCH") {
shayypy marked this conversation as resolved.
Show resolved Hide resolved
// Update the user
if (req.body.country && !Object.keys(countries).includes(req.body.country)) {
return BadRequest(res, "Invalid country code.");
}
try {
await prisma.user.update({ where: { id }, data: {
country: req.body.country,
shayypy marked this conversation as resolved.
Show resolved Hide resolved
} });
return NoContent(res);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === "P2025") {
return BadRequest(res, "The specified user does not exist.");
}
}
console.error(e);
return InternalError(res);
}
}
};

Expand Down
14 changes: 12 additions & 2 deletions pages/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,18 @@ const SettingsPage: NextPage<Props> = ({ user }) => {
</div>
</div>
</div>
<h1 className="font-bold text-2xl mt-4">Settings</h1>
<p>todo</p>
<h1 className="font-bold text-2xl mt-4">You</h1>
<p className="text-guilded-subtitle mb-1">Global profile settings that affect all of your bios.</p>
<form>
<ul>
<li>
<label>
<input type="checkbox" />{" "}
Display a link to <a className="text-guilded-link" href={`https://guilded.gg/profile/${user.id}`}>your Guilded profile</a>
</label>
</li>
</ul>
</form>
<h1 className="font-bold text-2xl mt-2">Destructive</h1>
<Button
color="red"
Expand Down
75 changes: 64 additions & 11 deletions pages/users/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { GetServerSideProps, NextPage } from "next";
import Head from "next/head";
import Image from "next/image";
import { useSession } from "next-auth/react";
import { ModifiedSession } from "../../types/session";
import { useRouter } from "next/router";
import Link from "next/link";

import { ModifiedSession } from "../../types/session";
import NameBadge from "../../components/profile/nameBadge";
import { fetchUser } from "../../lib/api";
import prisma from "../../lib/prisma";
Expand All @@ -13,19 +15,25 @@ import { MouseEventHandler, useState } from "react";
import Button from "../../components/button";
import { DeNullishFilter } from "../../utility/utils";
import { UserFlairs } from "../../components/profile/flairs";
import { useRouter } from "next/router";
import Link from "next/link";
import countries from "../../utility/countries";

export const getServerSideProps: GetServerSideProps = async (ctx) => {
const { id } = ctx.params as { id: string };
const storedUser = id ? await prisma.user.findFirst({ where: { id }, include: { defaultBio: true } }) : null;
const APIUser = storedUser ? await fetchUser(id) : null;
if (storedUser && APIUser) {
(APIUser as ModifiedGuildedUser).country = storedUser.country;
}

return { props: { user: APIUser, bio: storedUser?.defaultBio ?? null } };
};

interface ModifiedGuildedUser extends GuildedUser {
country: string | null;
};

type Props = {
user: GuildedUser;
user: ModifiedGuildedUser;
bio: Bio | null;
};

Expand All @@ -43,6 +51,7 @@ function ToolbarButton(props: { icon: string; onClick: MouseEventHandler }) {
const UserPage: NextPage<Props> = ({ user, bio }) => {
const { data: session } = useSession();
const [isInEditingMode, setIsInEditingMode] = useState(false);
const [isInUserEditingMode, setIsInUserEditingMode] = useState(false);
const [bioContent, setBioContent] = useState(bio?.content);
const [newBioContent, setNewBioContent] = useState(bioContent);
const router = useRouter();
Expand Down Expand Up @@ -124,17 +133,61 @@ const UserPage: NextPage<Props> = ({ user, bio }) => {
<div className="flex">
<div className="flex">
<Image src={user.profilePicture} alt={`${user.name}'s avatar`} className="rounded-full shadow-md" height="120" width="120" />
{isCurrentUser && (
<Link href="/settings">
<a className="z-10 mt-auto">
<i className="ci-settings rounded-full p-1 text-xl -ml-7 bg-guilded-slate text-guilded-subtitle hover:text-guilded-white transition-colors" />
</a>
</Link>
{isCurrentUser && !isInUserEditingMode && (
<>
<div className="z-10 mb-auto translate-x-1 translate-y-1 text-lg text-guilded-subtitle">
<button
className=""
onClick={() => {
setIsInUserEditingMode(true);
}}
>
<i className="ci-edit rounded-full p-1 -ml-7 bg-guilded-slate hover:text-guilded-white transition-colors" />
</button>
</div>
<div className="z-10 mt-auto translate-x-1 translate-y-1 text-lg text-guilded-subtitle">
<Link href="/settings">
<a>
<i className="ci-settings rounded-full p-1 -ml-7 bg-guilded-slate hover:text-guilded-white transition-colors" />
</a>
</Link>
</div>
</>
)}
</div>
<div className="flex flex-col pl-6 my-auto">
<div className="flex">
<h1 className="pr-2 text-2xl md:text-3xl font-bold">{user.name}</h1>
<h1 className="pr-2 text-2xl md:text-3xl font-bold">
<span className={isInUserEditingMode || user.country ? "mr-2": ""}>{user.name}</span>
{user.country && !isInUserEditingMode && (
<span title={`Flag of ${countries[user.country].name}`}>
{countries[user.country].emoji}
</span>
)}
{isInUserEditingMode && (
<select
defaultValue={user.country ?? "null"}
className="text-sm bg-guilded-gray border border-white/10 rounded max-w-[160px]"
onChange={async (e: any) => {
const country = e.currentTarget.selectedOptions[0]?.value;
if (!country || country === "null") return;

await fetch(`/api/users/${user.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ country }),
})
}}
>
<option disabled value="null">Countries</option>
{Object.keys(countries).map(code => (
<option key={code} value={code}>
{countries[code].emoji} {countries[code].name}
</option>
))}
</select>
)}
</h1>
{isCurrentUser && <NameBadge text="You" color="blue" />}
{badges.map((b) => (
<NameBadge key={b.iconUrl} iconURL={b.iconUrl} text={b.label} color={b.color} />
Expand Down
5 changes: 5 additions & 0 deletions prisma/migrations/20220530165004_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "Bio" DROP CONSTRAINT "Bio_authorId_fkey";

-- AddForeignKey
ALTER TABLE "Bio" ADD CONSTRAINT "Bio_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
2 changes: 2 additions & 0 deletions prisma/migrations/20220531000450_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "country" VARCHAR(2);
2 changes: 1 addition & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ model User {
defaultBio Bio? @relation(fields: [defaultBioId], references: [id], name: "DefaultBio")
defaultBioId Int? @unique
bios Bio[] @relation("BioAuthor")

country String? @db.VarChar(2)
}

model Bio {
Expand Down
Loading