generated from YashTotale/boilerplate-react-with-redux-and-firebase
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcertification.ts
134 lines (110 loc) · 3.89 KB
/
certification.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Internal Imports
import { getRawTag } from "./tags";
import { getProvider } from "./providers";
import { Certification, ResolvedCertification, Tag } from "../types";
import { compareDates, createResolver, createSorter } from "../funcs";
// Redux Imports
import { useSelector } from "react-redux";
import {
CertificationState,
getCertificationSearch,
getCertificationSort,
getCertificationTagFilter,
getCertificationProviderFilter,
} from "../../Redux";
import { CertificationSort } from "../../Redux/certification.slice";
// Data Imports
import certification from "../../Data/certification.json";
export const getCertification = (): Certification[] => {
return Object.values(certification);
};
export const getRawCertification = (
identifier: string
): Certification | null => {
const all = certification as Record<string, Certification>;
const single = all[identifier];
if (!single) return null;
return single;
};
export const getSingleCertification = createResolver((id: string) => {
const cert = getRawCertification(id);
if (!cert) return null;
const provider = getProvider(cert.provider);
if (!provider) return null;
const tags = cert.tags.reduce((arr, tag) => {
const resolved = getRawTag(tag);
if (!resolved) return arr;
return [...arr, resolved];
}, [] as Tag[]);
const resolved: ResolvedCertification = { ...cert, provider, tags };
return resolved;
});
export const checkTags = (
c: ResolvedCertification,
tags: string[]
): boolean => {
if (!tags.length) return true;
return tags.every((tag) => c.tags.some((t) => t.title === tag));
};
export const checkProvider = (
c: ResolvedCertification,
provider: CertificationState["providerFilter"]
): boolean => {
if (provider === null) return true;
return provider === c.provider.title;
};
const searchCache: Record<string, Record<string, boolean>> = {};
export const checkSearch = (
c: ResolvedCertification,
search: string
): boolean => {
if (!search.length) return true;
if (!searchCache[c.id]) searchCache[c.id] = {};
const cache = searchCache[c.id][search];
if (typeof cache === "boolean") return cache;
const matches: (boolean | undefined)[] = [
c.title.toLowerCase().includes(search),
c.date.toLowerCase().includes(search),
c.provider.title.toLowerCase().includes(search),
c.tags.some((tag) => tag.title.toLowerCase().includes(search)),
];
const result = matches.includes(true);
searchCache[c.id][search] = result;
return result;
};
export const useFilteredCertification = (): ResolvedCertification[] => {
const certification = useSortedCertification(true);
const search = useSelector(getCertificationSearch);
const normalizedSearch = search.toLowerCase();
const tagFilter = useSelector(getCertificationTagFilter);
const providerFilter = useSelector(getCertificationProviderFilter);
return certification.filter((e) => {
if (!checkTags(e, tagFilter)) return false;
if (!checkProvider(e, providerFilter)) return false;
if (!checkSearch(e, normalizedSearch)) return false;
return true;
});
};
export function useSortedCertification(resolve: true): ResolvedCertification[];
export function useSortedCertification(resolve: false): Certification[];
export function useSortedCertification(): Certification[];
export function useSortedCertification(
resolve?: boolean
): (ResolvedCertification | Certification)[] {
const sort = useSelector(getCertificationSort);
const sorted = sortCertification(sort);
if (!resolve) return sorted;
return sorted.reduce((arr, e) => {
const cert = getSingleCertification(e.id);
if (cert) arr.push(cert);
return arr;
}, [] as ResolvedCertification[]);
}
export const sortCertification = createSorter<CertificationSort, Certification>(
{
Newest: (a, b) =>
compareDates(a.date, b.date, ["MMM YYYY", "MMM DD, YYYY"]),
Alphabetically: (a, b) => a.title.localeCompare(b.title),
},
getCertification()
);