Skip to content

Commit 1de907c

Browse files
committed
feat: persist project filters in URL query params
1 parent 4901245 commit 1de907c

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

app/composables/useProjects.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,61 @@ import type { Project, ProjectCategory, ProjectType } from "~/data";
22
import { projects, projectTypes } from "~/data";
33

44
export const useProjects = () => {
5+
const route = useRoute();
6+
const router = useRouter();
7+
58
const {
69
trackProjectFilterClick,
710
trackProjectSearch,
811
trackProjectClearFilters,
912
} = useAnalytics();
1013

11-
const searchQuery = ref("");
12-
const selectedTypes = ref<ProjectType[]>([]);
13-
const selectedTechs = ref<string[]>([]);
14+
const getInitialSearch = (): string => {
15+
const q = route.query.q;
16+
return typeof q === "string" ? q : "";
17+
};
18+
19+
const getInitialTypes = (): ProjectType[] => {
20+
const types = route.query.type;
21+
if (!types) return [];
22+
const typeArray = typeof types === "string" ? types.split(",") : types;
23+
const validTypes = projectTypes.map((t) => t.value);
24+
return typeArray.filter((t): t is ProjectType =>
25+
validTypes.includes(t as ProjectType)
26+
);
27+
};
28+
29+
const getInitialTechs = (): string[] => {
30+
const techs = route.query.tech;
31+
if (!techs) return [];
32+
return typeof techs === "string" ? techs.split(",") : (techs as string[]);
33+
};
34+
35+
const searchQuery = ref(getInitialSearch());
36+
const selectedTypes = ref<ProjectType[]>(getInitialTypes());
37+
const selectedTechs = ref<string[]>(getInitialTechs());
1438
const searchDebounceTimeout = ref<NodeJS.Timeout | null>(null);
1539

40+
const updateUrlQuery = () => {
41+
const query: Record<string, string | undefined> = {};
42+
43+
if (searchQuery.value) {
44+
query.q = searchQuery.value;
45+
}
46+
if (selectedTypes.value.length > 0) {
47+
query.type = selectedTypes.value.join(",");
48+
}
49+
if (selectedTechs.value.length > 0) {
50+
query.tech = selectedTechs.value.join(",");
51+
}
52+
53+
router.replace({ query });
54+
};
55+
56+
watch([searchQuery, selectedTypes, selectedTechs], updateUrlQuery, {
57+
deep: true,
58+
});
59+
1660
const availableTypes = computed(() => {
1761
const types = new Set(projects.map((p) => p.type));
1862
return projectTypes.filter((t) => types.has(t.value));

0 commit comments

Comments
 (0)