refactor: apply prettier conf

This commit is contained in:
Sonny
2023-11-19 23:37:23 +01:00
parent 371eea85dc
commit 1f42fad0ad
19 changed files with 152 additions and 95 deletions

View File

@@ -6,7 +6,7 @@ const config = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"]
use: ["@svgr/webpack"],
});
return config;
@@ -15,12 +15,12 @@ const config = {
remotePatterns: [
{ hostname: "localhost" },
{ hostname: "t3.gstatic.com" },
{ hostname: "lh3.googleusercontent.com" }
{ hostname: "lh3.googleusercontent.com" },
],
formats: ["image/webp"]
formats: ["image/webp"],
},
reactStrictMode: false,
output: "standalone"
output: "standalone",
};
module.exports = config;

View File

@@ -18,7 +18,7 @@ interface LinkFaviconProps {
export default function LinkFavicon({
url,
size = 32,
noMargin = false
noMargin = false,
}: LinkFaviconProps) {
const [isFailed, setFailed] = useState<boolean>(false);
const [isLoading, setLoading] = useState<boolean>(true);

View File

@@ -13,7 +13,7 @@ import { makeRequest } from "lib/request";
export default function LinkItem({
link,
toggleFavorite,
index
index,
}: {
link: Link;
toggleFavorite: (linkId: Link["id"]) => void;
@@ -28,8 +28,8 @@ export default function LinkItem({
name,
url,
favorite: !favorite,
categoryId: link.category.id
}
categoryId: link.category.id,
},
})
.then(() => toggleFavorite(link.id))
.catch(console.error);
@@ -45,7 +45,7 @@ export default function LinkItem({
type: "spring",
stiffness: 260,
damping: 20,
delay: index * 0.05
delay: index * 0.05,
}}
>
<LinkFavicon url={url} />

View File

@@ -3,11 +3,16 @@ import { useSession } from "next-auth/react";
import PATHS from "constants/paths";
import styles from "./navbar.module.scss";
import { useTranslation } from "next-i18next";
import Image from "next/image";
import { TFunctionParam } from "../../types/i18next";
export default function Navbar() {
const { status } = useSession();
const { data, status } = useSession();
const { t } = useTranslation();
const avatarLabel = t("common:avatar", {
name: data?.user?.name,
} as TFunctionParam);
return (
<nav className={styles["navbar"]}>
<ul className="reset">
@@ -21,9 +26,21 @@ export default function Navbar() {
<LinkTag href={PATHS.TERMS}>{t("common:terms")}</LinkTag>
</li>
{status === "authenticated" ? (
<li>
<LinkTag href={PATHS.LOGOUT}>{t("common:logout")}</LinkTag>
</li>
<>
<li className={styles["user"]}>
<Image
src={data.user.image}
width={24}
height={24}
alt={avatarLabel}
title={avatarLabel}
/>
{data.user.name}
</li>
<li>
<LinkTag href={PATHS.LOGOUT}>{t("common:logout")}</LinkTag>
</li>
</>
) : (
<li>
<LinkTag href={PATHS.LOGIN}>{t("common:login")}</LinkTag>

View File

@@ -8,3 +8,13 @@
gap: 1.5em;
justify-content: center;
}
.navbar .user {
display: flex;
gap: 0.25em;
justify-content: center;
& img {
border-radius: 50%;
}
}

View File

@@ -9,7 +9,7 @@ type ApiHandlerMethod = ({
req,
res,
session,
user
user,
}: {
req: NextApiRequest;
res: NextApiResponse;
@@ -72,7 +72,7 @@ function errorHandler(error: any, response: NextApiResponse) {
function handlePrismaError({
meta,
code,
message
message,
}: PrismaClientKnownRequestError) {
switch (code) {
case "P2002":

View File

@@ -4,16 +4,24 @@ import { i18n } from "next-i18next";
export async function makeRequest({
method = "GET",
url,
body
}: { method?: RequestInit["method"], url: string, body?: object | any[] }): Promise<any> {
body,
}: {
method?: RequestInit["method"];
url: string;
body?: object | any[];
}): Promise<any> {
nProgress.start();
const request = await fetch(url, {
method, body: body ? JSON.stringify(body) : undefined, headers: {
"Content-Type": "application/json"
}
method,
body: body ? JSON.stringify(body) : undefined,
headers: {
"Content-Type": "application/json",
},
});
nProgress.done();
const data = await request.json();
return request.ok ? data : Promise.reject(data?.error || i18n.t("common:generic-error"));
}
return request.ok
? data
: Promise.reject(data?.error || i18n.t("common:generic-error"));
}

View File

@@ -5,7 +5,7 @@ export default async function createUser(profile: Profile) {
return await prisma.user.create({
data: {
email: profile.email,
google_id: profile.sub
}
google_id: profile.sub,
},
});
}
}

View File

@@ -5,7 +5,7 @@ export default async function getUserByProfileProvider(profile: Profile) {
return await prisma.user.findFirst({
where: {
google_id: profile.sub,
email: profile.email
}
email: profile.email,
},
});
}
}

View File

@@ -5,11 +5,11 @@ export default async function updateUser(profile: Profile) {
return await prisma.user.update({
where: {
email: profile.email,
google_id: profile.sub
google_id: profile.sub,
},
data: {
email: profile.email,
google_id: profile.sub
}
google_id: profile.sub,
},
});
}
}

View File

@@ -6,12 +6,18 @@ import createUser from "lib/user/createUser";
import updateUser from "lib/user/updateUser";
import prisma from "utils/prisma";
const authLogger = (profile: Profile, ...args: any[]) => console.log("[AUTH]", profile.email, `(${profile.name} - ${profile.sub})`, ...args);
const authLogger = (profile: Profile, ...args: any[]) =>
console.log(
"[AUTH]",
profile.email,
`(${profile.name} - ${profile.sub})`,
...args,
);
const redirectUser = (errorKey: string) => `${PATHS.LOGIN}?error=${errorKey}`;
const checkProvider = (provider: string) => provider === "google";
const checkAccountDataReceived = (profile: Profile) => !!profile?.sub && !!profile?.email;
const checkAccountDataReceived = (profile: Profile) =>
!!profile?.sub && !!profile?.email;
export const authOptions = {
providers: [
@@ -22,16 +28,16 @@ export const authOptions = {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code"
}
}
})
response_type: "code",
},
},
}),
],
callbacks: {
async session({ session }) {
// check if stored in session still exist in db
const user = await prisma.user.findFirst({
where: { email: session.user.email }
where: { email: session.user.email },
});
return user ? session : undefined;
},
@@ -62,12 +68,12 @@ export const authOptions = {
console.error(error);
return redirectUser("AUTH_ERROR");
}
}
},
},
pages: {
signIn: PATHS.LOGIN,
error: PATHS.LOGIN,
signOut: PATHS.LOGOUT
}
signOut: PATHS.LOGOUT,
},
} as NextAuthOptions;
export default NextAuth(authOptions);

View File

@@ -42,13 +42,17 @@ export default async function handler(
}
if (isBase64Image(faviconPath)) {
console.log("[Favicon]", `[first: ${faviconRequestUrl}]`, "base64, convert it to buffer");
console.log(
"[Favicon]",
`[first: ${faviconRequestUrl}]`,
"base64, convert it to buffer",
);
const buffer = convertBase64ToBuffer(faviconPath);
return sendImage(res, {
buffer,
type: "image/x-icon",
size: buffer.length,
url: faviconPath
url: faviconPath,
});
}
@@ -65,7 +69,9 @@ export default async function handler(
const errorMessage = error?.message || "Unable to retrieve favicon";
console.log("[Favicon]", `[second: ${faviconRequestUrl}]`, errorMessage);
const readStream = createReadStream(resolve(process.cwd(), "./public/empty-image.png"));
const readStream = createReadStream(
resolve(process.cwd(), "./public/empty-image.png"),
);
res.writeHead(206);
readStream.pipe(res);
}
@@ -89,15 +95,11 @@ async function downloadImageFromUrl(url: string): Promise<Favicon> {
buffer: Buffer.from(await blob.arrayBuffer()),
url: request.url,
type: blob.type,
size: blob.size
size: blob.size,
};
}
function sendImage(res: NextApiResponse, {
buffer,
type,
size
}: Favicon) {
function sendImage(res: NextApiResponse, { buffer, type, size }: Favicon) {
res.setHeader("Content-Type", type);
res.setHeader("Content-Length", size);
res.send(buffer);
@@ -110,13 +112,16 @@ const rels = [
"apple-touch-icon-precomposed",
"apple-touch-startup-image",
"mask-icon",
"fluid-icon"
"fluid-icon",
];
function findFaviconPath(text: string) {
const document = parse(text);
const favicon = Array.from(document.getElementsByTagName("link")).find(
(element) => rels.includes(element.getAttribute("rel")) && element.getAttribute("href"));
(element) =>
rels.includes(element.getAttribute("rel")) &&
element.getAttribute("href"),
);
if (!favicon) {
throw new Error("No link/href attribute found");

View File

@@ -13,7 +13,7 @@ import { withAuthentication } from "utils/session";
import { makeRequest } from "lib/request";
export default function PageCreateCategory({
categoriesCount
categoriesCount,
}: {
categoriesCount: number;
}) {
@@ -40,9 +40,11 @@ export default function PageCreateCategory({
makeRequest({
url: PATHS.API.CATEGORY,
method: "POST",
body: { name }
body: { name },
})
.then((data) => router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`))
.then((data) =>
router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`),
)
.catch(setError)
.finally(() => setSubmitted(false));
};
@@ -79,8 +81,8 @@ export const getServerSideProps = withAuthentication(
props: {
session,
categoriesCount,
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -36,9 +36,11 @@ export default function PageEditCategory({ category }: { category: Category }) {
makeRequest({
url: `${PATHS.API.CATEGORY}/${category.id}`,
method: "PUT",
body: { name }
body: { name },
})
.then((data) => router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`))
.then((data) =>
router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`),
)
.catch(setError)
.finally(() => setSubmitted(false));
};
@@ -73,8 +75,8 @@ export const getServerSideProps = withAuthentication(
if (!category) {
return {
redirect: {
destination: PATHS.HOME
}
destination: PATHS.HOME,
},
};
}
@@ -82,8 +84,8 @@ export const getServerSideProps = withAuthentication(
props: {
session,
category: JSON.parse(JSON.stringify(category)),
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -14,7 +14,7 @@ import { withAuthentication } from "utils/session";
import { makeRequest } from "lib/request";
export default function PageRemoveCategory({
category
category,
}: {
category: Category;
}) {
@@ -37,7 +37,7 @@ export default function PageRemoveCategory({
makeRequest({
url: `${PATHS.API.CATEGORY}/${category.id}`,
method: "DELETE"
method: "DELETE",
})
.then((data) => router.push(PATHS.HOME))
.catch(setError)
@@ -90,8 +90,8 @@ export const getServerSideProps = withAuthentication(
if (!category) {
return {
redirect: {
destination: PATHS.HOME
}
destination: PATHS.HOME,
},
};
}
@@ -99,8 +99,8 @@ export const getServerSideProps = withAuthentication(
props: {
session,
category: JSON.parse(JSON.stringify(category)),
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -17,7 +17,7 @@ import { withAuthentication } from "utils/session";
import { makeRequest } from "lib/request";
export default function PageCreateLink({
categories
categories,
}: {
categories: Category[];
}) {
@@ -54,9 +54,11 @@ export default function PageCreateLink({
makeRequest({
url: PATHS.API.LINK,
method: "POST",
body: { name, url, favorite, categoryId }
body: { name, url, favorite, categoryId },
})
.then((data) => router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`))
.then((data) =>
router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`),
)
.catch(setError)
.finally(() => setSubmitted(false));
};
@@ -94,7 +96,7 @@ export default function PageCreateLink({
onChangeCallback={(value: number) => setCategoryId(value)}
options={categories.map(({ id, name }) => ({
label: name,
value: id
value: id,
}))}
/>
<Checkbox
@@ -114,8 +116,8 @@ export const getServerSideProps = withAuthentication(
if (categories.length === 0) {
return {
redirect: {
destination: PATHS.HOME
}
destination: PATHS.HOME,
},
};
}
@@ -123,8 +125,8 @@ export const getServerSideProps = withAuthentication(
props: {
session,
categories: JSON.parse(JSON.stringify(categories)),
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -19,7 +19,7 @@ import { makeRequest } from "lib/request";
export default function PageEditLink({
link,
categories
categories,
}: {
link: Link;
categories: Category[];
@@ -59,7 +59,7 @@ export default function PageEditLink({
link.url,
name,
submitted,
url
url,
]);
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
@@ -70,9 +70,11 @@ export default function PageEditLink({
makeRequest({
url: `${PATHS.API.LINK}/${link.id}`,
method: "PUT",
body: { name, url, favorite, categoryId }
body: { name, url, favorite, categoryId },
})
.then((data) => router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`))
.then((data) =>
router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`),
)
.catch(setError)
.finally(() => setSubmitted(false));
};
@@ -109,7 +111,7 @@ export default function PageEditLink({
onChangeCallback={(value: number) => setCategoryId(value)}
options={categories.map(({ id, name }) => ({
label: name,
value: id
value: id,
}))}
/>
<Checkbox
@@ -132,8 +134,8 @@ export const getServerSideProps = withAuthentication(
if (!link) {
return {
redirect: {
destination: PATHS.HOME
}
destination: PATHS.HOME,
},
};
}
@@ -142,8 +144,8 @@ export const getServerSideProps = withAuthentication(
session,
link: JSON.parse(JSON.stringify(link)),
categories: JSON.parse(JSON.stringify(categories)),
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -33,9 +33,11 @@ export default function PageRemoveLink({ link }: { link: Link }) {
makeRequest({
url: `${PATHS.API.LINK}/${link.id}`,
method: "DELETE"
method: "DELETE",
})
.then((data) => router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`))
.then((data) =>
router.push(`${PATHS.HOME}?categoryId=${data?.categoryId}`),
)
.catch(setError)
.finally(() => setSubmitted(false));
};
@@ -97,8 +99,8 @@ export const getServerSideProps = withAuthentication(
if (!link) {
return {
redirect: {
destination: PATHS.HOME
}
destination: PATHS.HOME,
},
};
}
@@ -106,8 +108,8 @@ export const getServerSideProps = withAuthentication(
props: {
session,
link: JSON.parse(JSON.stringify(link)),
...(await getServerSideTranslation(locale))
}
...(await getServerSideTranslation(locale)),
},
};
},
);

View File

@@ -13,6 +13,7 @@ import Image from "next/image";
import { FcGoogle } from "react-icons/fc";
import styles from "styles/login.module.scss";
import { getSession } from "utils/session";
import { TFunctionParam } from "../types/i18next";
interface SignInProps {
providers: Provider[];
@@ -43,7 +44,7 @@ export default function SignIn({ providers }: SignInProps) {
key={id}
>
<FcGoogle size={"1.5em"} />{" "}
{t("login:continue-with", { provider: name } as undefined)}
{t("login:continue-with", { provider: name } as TFunctionParam)}
</ButtonLink>
))}
</div>