1
- import { createContext , FC , useContext , useState } from "react" ;
1
+ import {
2
+ createContext ,
3
+ FC ,
4
+ useCallback ,
5
+ useContext ,
6
+ useEffect ,
7
+ useState ,
8
+ } from "react" ;
9
+ import { useParams } from "react-router-dom" ;
2
10
3
- import { AppState , LanguageType , SnippetType } from "@types" ;
4
- import { defaultCategory , defaultLanguage } from "@utils/consts" ;
11
+ import { useLanguages } from "@hooks/useLanguages" ;
12
+ import { AppState , CategoryType , LanguageType , SnippetType } from "@types" ;
13
+ import { defaultLanguage } from "@utils/consts" ;
14
+ import { slugify } from "@utils/slugify" ;
5
15
6
16
// TODO: add custom loading and error handling
7
17
const defaultState : AppState = {
8
- language : defaultLanguage ,
18
+ language : null as unknown as AppState [ "language" ] ,
9
19
setLanguage : ( ) => { } ,
10
- category : defaultCategory ,
20
+ category : null as unknown as AppState [ "category" ] ,
11
21
setCategory : ( ) => { } ,
12
22
snippet : null ,
13
23
setSnippet : ( ) => { } ,
@@ -20,18 +30,73 @@ const AppContext = createContext<AppState>(defaultState);
20
30
export const AppProvider : FC < { children : React . ReactNode } > = ( {
21
31
children,
22
32
} ) => {
23
- const [ language , setLanguage ] = useState < LanguageType > ( defaultLanguage ) ;
24
- const [ category , setCategory ] = useState < string > ( defaultCategory ) ;
33
+ const { languageName, categoryName } = useParams ( ) ;
34
+
35
+ const { fetchedLanguages } = useLanguages ( ) ;
36
+
37
+ const [ language , setLanguage ] = useState < LanguageType | null > ( null ) ;
38
+ const [ category , setCategory ] = useState < string | null > ( null ) ;
25
39
const [ snippet , setSnippet ] = useState < SnippetType | null > ( null ) ;
26
40
const [ searchText , setSearchText ] = useState < string > ( "" ) ;
27
41
42
+ const assignLanguage = useCallback ( ( ) => {
43
+ if ( fetchedLanguages . length === 0 ) {
44
+ return ;
45
+ }
46
+
47
+ const language = fetchedLanguages . find (
48
+ ( lang ) => slugify ( lang . lang ) === languageName
49
+ ) ;
50
+ if ( ! language ) {
51
+ setLanguage ( defaultLanguage ) ;
52
+ return ;
53
+ }
54
+ setLanguage ( language ) ;
55
+ } , [ fetchedLanguages , languageName ] ) ;
56
+
57
+ const assignCategory = useCallback ( async ( ) => {
58
+ if ( ! language ) {
59
+ return ;
60
+ }
61
+
62
+ let category : CategoryType | undefined ;
63
+ try {
64
+ const res = await fetch ( `/consolidated/${ slugify ( language . lang ) } .json` ) ;
65
+ const data : CategoryType [ ] = await res . json ( ) ;
66
+ category = data . find (
67
+ ( item : { categoryName : string } ) =>
68
+ slugify ( item . categoryName ) === categoryName
69
+ ) ;
70
+ if ( ! category ) {
71
+ setCategory ( data [ 0 ] . categoryName ) ;
72
+ return ;
73
+ }
74
+ setCategory ( category . categoryName ) ;
75
+ } catch ( _error ) {
76
+ // no-op
77
+ }
78
+ } , [ language , categoryName ] ) ;
79
+
80
+ useEffect ( ( ) => {
81
+ assignLanguage ( ) ;
82
+ } , [ assignLanguage , languageName ] ) ;
83
+
84
+ useEffect ( ( ) => {
85
+ assignCategory ( ) ;
86
+ } , [ assignCategory , categoryName ] ) ;
87
+
88
+ if ( ! language || ! category ) {
89
+ return < div > Loading...</ div > ;
90
+ }
91
+
92
+ console . log ( { language } ) ;
28
93
return (
29
94
< AppContext . Provider
30
95
value = { {
31
96
language,
32
- setLanguage,
97
+ setLanguage : setLanguage as AppState [ "setLanguage" ] ,
33
98
category,
34
- setCategory,
99
+ setCategory : setCategory as AppState [ "setCategory" ] ,
35
100
snippet,
36
101
setSnippet,
37
102
searchText,
0 commit comments