Skip to content

Commit fecbb59

Browse files
committed
fix(faqs, lint): update faqs pages, remove _components folder, resolve all linter errors
1 parent dbfd9a1 commit fecbb59

File tree

17 files changed

+119
-180
lines changed

17 files changed

+119
-180
lines changed

src/actions/resources.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const getResources = async (): Promise<ResourceList[]> => {
1616
`);
1717

1818
if (error) throw new Error(error.message);
19-
// @ts-ignore - supabase returns an array, but we want to return a single object
19+
// @ts-expect-error - supabase returns an array, but we want to return a single object
2020
return data;
2121
};
2222

@@ -49,7 +49,7 @@ export const getResourcesByCategory = async (
4949
.eq("categories.slug", category);
5050

5151
if (error) throw new Error(error.message);
52-
// @ts-ignore - supabase returns an array, but we want to return a single object
52+
// @ts-expect-error - supabase returns an array, but we want to return a single object
5353
return data;
5454
};
5555

@@ -74,7 +74,7 @@ export const searchResources = async (
7474
.limit(20);
7575

7676
if (error) throw new Error(error.message);
77-
// @ts-ignore - supabase returns an array, but we want to return a single object
77+
// @ts-expect-error - supabase returns an array, but we want to return a single object
7878
return data;
7979
};
8080

src/app/(private)/dashboard/resources/client.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ export default function ResourcesPageClient({ resources, categories }: Props) {
4242
},
4343
});
4444

45-
// @ts-ignore
4645
const { fields, replace, append, remove } = useFieldArray({
4746
control,
47+
// @ts-expect-error - name is a valid key for FieldArrayWithId
4848
name: "tags" as const,
4949
});
5050

@@ -100,9 +100,8 @@ export default function ResourcesPageClient({ resources, categories }: Props) {
100100
category: data.category,
101101
};
102102

103-
editingResource
104-
? await updateResource(editingResource.id, payload)
105-
: await createResource(payload);
103+
if (editingResource) await updateResource(editingResource.id, payload);
104+
else await createResource(payload);
106105

107106
router.refresh();
108107
onClose();

src/app/(private)/my-resources/client.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export default function MyResourcesClient({ resources, categories }: Props) {
7676

7777
const { fields, replace, append, remove } = useFieldArray({
7878
control,
79+
// @ts-expect-error - name is a valid key for FieldArrayWithId
7980
name: "tags",
8081
});
8182

@@ -218,7 +219,7 @@ export default function MyResourcesClient({ resources, categories }: Props) {
218219
{resources && resources.length > 0 ? (
219220
<TableBody emptyContent="No rows to display.">
220221
{resources.map((resource) => (
221-
<TableRow key={resource.id}>
222+
<TableRow key={resource.id} textValue={resource.name}>
222223
<TableCell>{resource.name}</TableCell>
223224
<TableCell>{resource.url}</TableCell>
224225
<TableCell>{resource.tags.join(", ")}</TableCell>

src/app/(public)/faqs/_components/faq-item.tsx

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/app/(public)/faqs/_components/faq-list.tsx renamed to src/app/(public)/faqs/client.tsx

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,43 @@
33
import type { Faq } from "@/types";
44

55
import { motion } from "framer-motion";
6+
import { Accordion, AccordionItem } from "@heroui/react";
7+
import { ChevronLeft, BookOpen } from "lucide-react";
68
import { useAnimateOnView } from "@/hooks/use-animate-on-view";
7-
import { FaqItem } from "./faq-item";
89

9-
type Props = {
10-
faqs: Faq[];
11-
};
10+
type FaqItemProps = { faq: Faq };
11+
type FaqsPageClientProps = { faqs: Faq[] };
1212

13-
export default function ({ faqs }: Props) {
13+
function FaqItem({ faq }: FaqItemProps) {
14+
return (
15+
<Accordion variant="bordered">
16+
<AccordionItem
17+
key={faq.id}
18+
title={faq.question}
19+
HeadingComponent="h2"
20+
aria-label={faq.question}
21+
startContent={
22+
<BookOpen
23+
className="stroke-neutral-950 dark:stroke-white"
24+
size={18}
25+
/>
26+
}
27+
indicator={({ isOpen }) =>
28+
isOpen ? (
29+
<ChevronLeft className="stroke-neutral-950 dark:stroke-white" />
30+
) : (
31+
<ChevronLeft className="stroke-neutral-200 dark:stroke-neutral-800 group-hover:stroke-neutral-950 dark:group-hover:stroke-white" />
32+
)
33+
}
34+
classNames={{ title: "text-sm font-medium" }}
35+
>
36+
<p className="text-sm text-neutral-500 pb-4">{faq.answer}</p>
37+
</AccordionItem>
38+
</Accordion>
39+
);
40+
}
41+
42+
export default function FaqsPageClient({ faqs }: FaqsPageClientProps) {
1443
const firstColumnAnimation = useAnimateOnView(0.1, false);
1544
const secondColumnAnimation = useAnimateOnView(0.1, false);
1645

src/app/(public)/faqs/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { getFaqs } from "@/actions/faqs";
44
import { Heading } from "@/components/ui";
55
import { EmptyList } from "@/components/layout";
66
import { PROJECT_NAME } from "@/config/constants";
7-
import FaqList from "./_components/faq-list";
7+
import FaqsPageClient from "./client";
88

99
export const revalidate = 0;
1010

@@ -18,7 +18,7 @@ export default async function FaqsPage() {
1818

1919
const renderFaqs = () => {
2020
if (faqs.length === 0) return <EmptyList type="faqs" />;
21-
return <FaqList faqs={faqs} />;
21+
return <FaqsPageClient faqs={faqs} />;
2222
};
2323

2424
return (

src/app/(public)/resources/[slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Metadata } from "next";
55
import { PROJECT_NAME } from "@/config/constants";
66

77
type Props = {
8-
params: { slug: string };
8+
params: Promise<{ slug: string }>;
99
};
1010

1111
export async function generateMetadata({ params }: Props): Promise<Metadata> {

src/app/(public)/resources/categories/[category]/page.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import { formatSlugToTitle } from "@/lib/utils";
99

1010
export const dynamic = "force-dynamic";
1111

12-
type Props = {
13-
params: { category: string };
14-
};
12+
type Props = { params: Promise<{ category: string }> };
1513

1614
export async function generateMetadata({ params }: Props): Promise<Metadata> {
1715
const { category } = await params;
@@ -27,6 +25,23 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
2725
return {
2826
title: `${formatSlugToTitle(category)} - ${PROJECT_NAME}`,
2927
description: `Explore all the resources by category: ${category}`,
28+
openGraph: {
29+
title: `${formatSlugToTitle(category)} - ${PROJECT_NAME}`,
30+
description: `Explore all the resources by category: ${category}`,
31+
images: [
32+
{
33+
url: category,
34+
width: 1200,
35+
height: 630,
36+
alt: category,
37+
},
38+
],
39+
},
40+
twitter: {
41+
card: "summary_large_image",
42+
title: `${formatSlugToTitle(category)} - ${PROJECT_NAME}`,
43+
description: `Explore all the resources by category: ${category}`,
44+
},
3045
};
3146
}
3247

@@ -35,9 +50,7 @@ export default async function ResourcesByCategoryPage({ params }: Props) {
3550
const resources = await getResourcesByCategory(category);
3651

3752
const renderResources = () => {
38-
if (resources.length === 0) {
39-
return <EmptyList type="resources" />;
40-
}
53+
if (resources.length === 0) return <EmptyList type="resources" />;
4154
return <ResourceList resources={resources} />;
4255
};
4356

src/components/auth/login-modal.tsx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,24 @@ export default function ModalLoginProvider({ children }: Props) {
4343

4444
<Modal isOpen={isOpen} onOpenChange={setIsOpen} backdrop="blur">
4545
<ModalContent>
46-
{(onClose) => (
47-
<>
48-
<ModalHeader>
49-
<div className="flex flex-col gap-2">
50-
<h2 className="text-2xl font-semibold tracking-tight">
51-
Welcome back
52-
</h2>
53-
<p className="text-sm text-neutral-500">
54-
Sign in to continue with your account
55-
</p>
56-
</div>
57-
</ModalHeader>
58-
<ModalBody>
59-
<section className="flex flex-col gap-2 pb-10">
60-
<GoogleButton />
61-
<GitHubButton />
62-
</section>
63-
</ModalBody>
64-
</>
65-
)}
46+
<>
47+
<ModalHeader>
48+
<div className="flex flex-col gap-2">
49+
<h2 className="text-2xl font-semibold tracking-tight">
50+
Welcome back
51+
</h2>
52+
<p className="text-sm text-neutral-500">
53+
Sign in to continue with your account
54+
</p>
55+
</div>
56+
</ModalHeader>
57+
<ModalBody>
58+
<section className="flex flex-col gap-2 pb-10">
59+
<GoogleButton />
60+
<GitHubButton />
61+
</section>
62+
</ModalBody>
63+
</>
6664
</ModalContent>
6765
</Modal>
6866
</ModalLoginContext.Provider>

src/components/auth/user-profile.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import type { User } from "@/types";
3+
import type { User } from "@supabase/supabase-js";
44

55
import { useEffect, useState } from "react";
66
import { useRouter } from "next/navigation";
@@ -17,8 +17,8 @@ import { createClient } from "@/lib/supabase/client";
1717

1818
export default function UserProfile() {
1919
const router = useRouter();
20-
const supabase = createClient();
2120
const [user, setUser] = useState<User | null>(null);
21+
const supabase = createClient();
2222

2323
useEffect(() => {
2424
const getUser = async () => {
@@ -27,11 +27,11 @@ export default function UserProfile() {
2727
error,
2828
} = await supabase.auth.getUser();
2929
if (error || !user) throw new Error(error?.message);
30-
setUser(user as unknown as User);
30+
setUser(user);
3131
};
3232

3333
getUser();
34-
}, []);
34+
}, [supabase]);
3535

3636
const handleLogout = async () => {
3737
await supabase.auth.signOut();
@@ -61,6 +61,7 @@ export default function UserProfile() {
6161
<DropdownMenu aria-label="User actions">
6262
<DropdownItem
6363
key="profile"
64+
textValue="Profile"
6465
classNames={{
6566
base: "text-white pb-4 mb-2 cursor-default rounded-none pointer-events-none border-b-2 border-neutral-200 dark:border-neutral-800",
6667
}}
@@ -83,11 +84,12 @@ export default function UserProfile() {
8384
</DropdownItem>
8485
<DropdownItem
8586
key="my-resources"
87+
textValue="My Resources"
8688
onPress={() => router.push("/my-resources")}
8789
>
8890
My Resources
8991
</DropdownItem>
90-
<DropdownItem key="logout" onPress={handleLogout}>
92+
<DropdownItem key="logout" textValue="Log out" onPress={handleLogout}>
9193
Log out
9294
</DropdownItem>
9395
</DropdownMenu>

0 commit comments

Comments
 (0)