Skip to content

Commit cc540f7

Browse files
committed
Upgrade all packages
1 parent f094ae6 commit cc540f7

30 files changed

+6738
-14709
lines changed

__tests__/.gitkeep

Whitespace-only changes.

__tests__/getCategoryIdsFromLabels.test.ts

-61
This file was deleted.

api/categories/fetchCategories.ts

+7
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@ interface FetchCategoriesParams {
55
q?: string | null;
66
page?: number;
77
limit?: number;
8+
labels?: string[];
89
}
910

1011
export const fetchCategories = async ({
1112
q,
1213
page = 1,
1314
limit = 20,
15+
labels,
1416
}: FetchCategoriesParams): Promise<CategoriesListResponse> => {
1517
let url = `${CATEGORIES_API_ENDPOINT}?page=${page}&limit=${limit}`;
1618

1719
if (q) {
1820
url += `&q=${encodeURIComponent(q)}`;
1921
}
2022

23+
if (labels?.length) {
24+
const labelsParams = labels.map((label) => `label=${label}`).join("&");
25+
url += `&${labelsParams}`;
26+
}
27+
2128
const response = await fetchService(url, { method: "GET" });
2229

2330
if (!response.success) {

api/categories/useGetCategories.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ interface UseGetCategoriesParams {
1010
export const useGetCategories = ({ limit }: UseGetCategoriesParams = {}) => {
1111
const searchParams = useSearchParams();
1212
const q = searchParams.get("q");
13+
const labels = searchParams.getAll("label");
1314

1415
return useInfiniteQuery({
15-
queryKey: [CATEGORIES_API_ENDPOINT, q],
16-
queryFn: ({ pageParam }) => fetchCategories({ q, page: pageParam, limit }),
16+
queryKey: [CATEGORIES_API_ENDPOINT, q, labels],
17+
queryFn: ({ pageParam }) =>
18+
fetchCategories({ q, page: pageParam, limit, labels }),
1719
initialPageParam: 1,
1820
getNextPageParam: (lastPage) => {
1921
if (lastPage.pagination.hasMore) {

app/api/categories/[id]/route.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ export async function PUT(
4242
})
4343
.parse(body);
4444

45+
const updatedLabels = parsedBody.labels.map(({ id, ...rest }) => ({
46+
_id: id,
47+
...rest,
48+
}));
49+
4550
const category = await Category.findOneAndUpdate(
4651
{ _id: id },
47-
{ $set: { ...parsedBody } },
52+
{ $set: { name: parsedBody.name, labels: updatedLabels } },
4853
{ new: true }
4954
);
5055

@@ -106,11 +111,6 @@ export async function DELETE(
106111

107112
await Category.findOneAndDelete({ _id: categoryId });
108113

109-
await Label.updateMany(
110-
{ category_ids: categoryId },
111-
{ $pull: { category_ids: categoryId } }
112-
);
113-
114114
return NextResponse.json({ success: true });
115115
} catch (error) {
116116
return NextResponse.json(

app/api/categories/route.ts

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export async function GET(req: NextRequest) {
1717

1818
const { searchParams } = new URL(req.url);
1919
const searchQuery = searchParams.get("q");
20+
const labels = searchParams.getAll("label");
2021
const page = parseInt(searchParams.get("page") || "1", 10);
2122
const limit = parseInt(searchParams.get("limit") || "20", 10);
2223

@@ -68,6 +69,14 @@ export async function GET(req: NextRequest) {
6869

6970
aggregationPipeline.push({ $skip: (page - 1) * limit }, { $limit: limit });
7071

72+
if (labels.length > 0) {
73+
aggregationPipeline.push({
74+
$match: {
75+
"labels.id": { $in: labels },
76+
},
77+
});
78+
}
79+
7180
const categories = await Category.aggregate(aggregationPipeline);
7281

7382
const totalCategories = await Category.countDocuments({

app/api/code-items/route.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export async function GET(req: NextRequest) {
106106

107107
const populatedCodeItems = await CodeItem.populate(codeItems, {
108108
path: "label_ids",
109-
select: "id name color",
109+
select: "id name color text_color",
110110
options: { skipInvalidIds: true },
111111
});
112112

@@ -119,6 +119,7 @@ export async function GET(req: NextRequest) {
119119
id: label._id,
120120
name: label.name,
121121
color: label.color,
122+
text_color: label.text_color,
122123
}))
123124
: [],
124125
}));

app/api/labels/[id]/route.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ interface UpdateLabelRequest {
1414
const labelSchema = z.object({
1515
name: z.string().min(1),
1616
color: z.string().min(1),
17-
category_ids: z.array(z.string()),
1817
type: z.string().min(1),
1918
text_color: z.string().min(1),
2019
});
@@ -39,7 +38,7 @@ const updateLabel = async (id: string, parsedBody: LabelSchema) => {
3938
if (label.type === CATEGORY_TYPE) {
4039
// Update label in all categories
4140
await Category.updateMany(
42-
{ _id: { $in: label.category_ids }, "labels._id": id },
41+
{ "labels._id": id },
4342
{ $set: { "labels.$": label } }
4443
);
4544
}

app/api/labels/route.ts

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export async function GET(req: NextRequest) {
5151
_id: 0,
5252
name: 1,
5353
color: 1,
54-
category_ids: 1,
5554
type: 1,
5655
text_color: 1,
5756
},

app/code-items/edit/[id]/page.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ interface EditPageProps {
1616

1717
const CodeItemEditPage = async ({ params }: EditPageProps) => {
1818
const queryClient = new QueryClient();
19-
const { id: codeItemId } = params;
19+
const { id: codeItemId } = await params;
20+
const resolvedCookies = await cookies();
2021

2122
await queryClient.prefetchQuery({
2223
queryKey: [CODEITEMS_API_ENDPOINT, codeItemId],
2324
queryFn: () =>
24-
fetchOneCodeItem({ codeItemId, headers: { Cookie: cookies() } }),
25+
fetchOneCodeItem({ codeItemId, headers: { Cookie: resolvedCookies } }),
2526
});
2627

2728
return (

app/code-items/page.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ interface CodeItemsPageProps {
1919

2020
const CodeItemsPage = async ({ searchParams }: CodeItemsPageProps) => {
2121
const queryClient = new QueryClient();
22-
const params = new URLSearchParams(searchParams);
22+
const resolvedSearchParams = await searchParams;
23+
const resolvedCookies = await cookies();
24+
const params = new URLSearchParams(resolvedSearchParams);
2325
const categoryId = params.get("categoryId");
2426

2527
const codeItemsResponse = await queryClient.fetchInfiniteQuery({
@@ -32,7 +34,7 @@ const CodeItemsPage = async ({ searchParams }: CodeItemsPageProps) => {
3234
labels: [],
3335
page: 1,
3436
limit: 20,
35-
headers: { Cookie: cookies() },
37+
headers: { Cookie: resolvedCookies },
3638
}),
3739
});
3840
const pageTitle = codeItemsResponse?.pages[0].pageTitle ?? "Code items";

app/code-items/show/[id]/page.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ interface EditPageProps {
1616

1717
const CodeIteShowPage = async ({ params }: EditPageProps) => {
1818
const queryClient = new QueryClient();
19-
const { id: codeItemId } = params;
19+
const { id: codeItemId } = await params;
20+
const resolvedCookies = await cookies();
2021

2122
await queryClient.prefetchQuery({
2223
queryKey: [CODEITEMS_API_ENDPOINT, codeItemId],
2324
queryFn: () =>
24-
fetchOneCodeItem({ codeItemId, headers: { Cookie: cookies() } }),
25+
fetchOneCodeItem({ codeItemId, headers: { Cookie: resolvedCookies } }),
2526
});
2627

2728
return (

app/layout.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ import { ProgressBar } from "@/components/ProgressBar";
1515
export const metadata: Metadata = {
1616
title: "Next App",
1717
description: "Generated by create next app",
18-
viewport:
19-
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no",
18+
};
19+
20+
export const viewport = {
21+
width: "device-width",
22+
initialScale: 1,
23+
maximumScale: 1,
24+
userScalable: false,
2025
};
2126

2227
export default function RootLayout({ children }: { children: ReactNode }) {

app/page.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import { SearchInput } from "@/components/inputs";
66
import { MainLayout } from "@/components/MainLayout";
77
import { FiltersModal } from "@/components/modals";
88
import { CATEGORY_TYPE } from "@/types";
9+
import { useGetLabels } from "@/api";
910

1011
const Home = () => {
1112
const theme = useTheme();
1213
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
14+
useGetLabels({ labelType: CATEGORY_TYPE });
1315

1416
return (
1517
<MainLayout title="Categories">

components/MainLayout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const MainLayout = ({
2121
titleProps,
2222
}: MainLayoutProps) => {
2323
return (
24-
<Box component="main" pt={12} pb={4}>
24+
<Box component="main" pt={12} pb={8}>
2525
<Container maxWidth="lg">
2626
<Grid2 container gap={2} direction="column">
2727
{toolbar}

components/categories/CategoriesList.tsx

+12-31
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
"use client";
22

3-
import { useCallback, useEffect, useMemo, useState } from "react";
4-
import { useSearchParams } from "next/navigation";
3+
import { useCallback, useEffect, useMemo } from "react";
54
import { Box, Grid } from "@mui/material";
65
import { useCategories } from "@/providers";
7-
import { getCategoryIdsFromLabels } from "@/helpers";
8-
import { CATEGORY_TYPE } from "@/types";
9-
import { useGetCategories, useGetLabels } from "@/api";
6+
import { useGetCategories } from "@/api";
107
import { CategoryCard } from "./CategoryCard";
118
import { CategoryCardSkeleton } from "./CategoryCardSkeleton";
129
import { LoadingSpinner } from "../LoadingSpinner";
1310
import { useInView } from "react-intersection-observer";
11+
import { isCategoryLabelsEdited } from "@/helpers";
1412

1513
export const CategoriesList = () => {
1614
const {
@@ -25,40 +23,18 @@ export const CategoriesList = () => {
2523
() => categoriesResponse?.pages.flatMap((page) => page.data) || [],
2624
[categoriesResponse]
2725
);
28-
const { data: labels } = useGetLabels({ labelType: CATEGORY_TYPE });
2926
const { currentCategories, setCurrentCategories } = useCategories();
30-
const searchParams = useSearchParams();
31-
const labelIds = searchParams.getAll("label");
32-
const [filteredCategories, setFilteredCategories] = useState(categories);
3327

3428
useEffect(() => {
35-
// Initial categories filtering when label ids are in search params
36-
if (labels?.length && categories.length && labelIds.length) {
37-
const categoryIds = getCategoryIdsFromLabels({ labelIds, labels });
38-
39-
const filteredCategories = categories.filter((category) =>
40-
categoryIds.includes(category.id)
41-
);
42-
43-
setFilteredCategories(filteredCategories);
44-
setCurrentCategories(filteredCategories);
45-
46-
return;
47-
}
48-
49-
// Initial set of categories without filters
29+
// Initial set of categories
5030
if ((!categories.length && currentCategories.length) || categories.length) {
5131
setCurrentCategories(categories);
5232
}
53-
54-
//eslint-disable-next-line
55-
}, [labels, categories, setCurrentCategories, searchParams]);
33+
}, [categories, setCurrentCategories]);
5634

5735
const onFinishCreatingCategory = useCallback(() => {
58-
labelIds.length
59-
? setCurrentCategories(filteredCategories)
60-
: setCurrentCategories(categories);
61-
}, [categories, labelIds, filteredCategories, setCurrentCategories]);
36+
setCurrentCategories(categories);
37+
}, [categories, setCurrentCategories]);
6238

6339
const { ref, inView } = useInView({
6440
triggerOnce: false,
@@ -85,6 +61,11 @@ export const CategoriesList = () => {
8561
onFinishCreatingCategory={onFinishCreatingCategory}
8662
categoryId={category.id}
8763
labels={category.labels || []}
64+
isCategoryLabelsEdited={isCategoryLabelsEdited({
65+
categories,
66+
categoryId: category.id,
67+
newLabels: category.labels || [],
68+
})}
8869
/>
8970
</Grid>
9071
))}

0 commit comments

Comments
 (0)