@c-rex/components 0.1.38 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -73
- package/package.json +250 -218
- package/src/article/article-action-bar.tsx +110 -110
- package/src/article/article-content.tsx +18 -46
- package/src/autocomplete.tsx +201 -201
- package/src/breadcrumb.tsx +124 -124
- package/src/carousel/carousel.tsx +353 -353
- package/src/check-article-lang.tsx +47 -47
- package/src/directoryNodes/directory-tree-context.tsx +388 -0
- package/src/directoryNodes/tree-of-content.tsx +68 -67
- package/src/documents/result-list.tsx +124 -127
- package/src/favorites/bookmark-button.tsx +97 -94
- package/src/favorites/favorite-button.tsx +137 -120
- package/src/footer/footer-shell.tsx +52 -0
- package/src/footer/footer.tsx +7 -0
- package/src/footer/legal-links-block.tsx +25 -0
- package/src/footer/organization-contact-block.tsx +94 -0
- package/src/footer/social-links-block.tsx +38 -0
- package/src/footer/types.ts +10 -0
- package/src/footer/vcard-footer.tsx +72 -0
- package/src/generated/client-components.tsx +1366 -1350
- package/src/generated/create-client-request.tsx +116 -113
- package/src/generated/create-server-request.tsx +70 -61
- package/src/generated/create-suggestions-request.tsx +55 -55
- package/src/generated/server-components.tsx +1056 -1056
- package/src/generated/suggestions.tsx +302 -299
- package/src/icons/file-icon.tsx +8 -8
- package/src/icons/flag-icon.tsx +15 -15
- package/src/icons/loading.tsx +11 -11
- package/src/icons/social-icon.tsx +24 -0
- package/src/info/info-card.tsx +43 -0
- package/src/info/{info-table.tsx → information-unit-metadata-grid.tsx} +157 -168
- package/src/info/shared.tsx +49 -25
- package/src/navbar/language-switcher/content-language-switch.tsx +92 -92
- package/src/navbar/language-switcher/shared.tsx +33 -33
- package/src/navbar/language-switcher/ui-language-switch.tsx +37 -37
- package/src/navbar/navbar.tsx +157 -152
- package/src/navbar/settings.tsx +62 -62
- package/src/navbar/sign-in-out-btns.tsx +35 -35
- package/src/navbar/user-menu.tsx +60 -60
- package/src/page-wrapper.tsx +54 -31
- package/src/render-article.module.css +155 -0
- package/src/render-article.tsx +75 -68
- package/src/renditions/file-download.tsx +83 -83
- package/src/renditions/html.tsx +64 -64
- package/src/renditions/image/container.tsx +54 -54
- package/src/renditions/image/rendition.tsx +55 -55
- package/src/restriction-menu/restriction-menu-container.tsx +117 -53
- package/src/restriction-menu/restriction-menu-item.tsx +155 -147
- package/src/restriction-menu/restriction-menu.tsx +341 -156
- package/src/results/dialog-filter.tsx +166 -166
- package/src/results/empty.tsx +15 -15
- package/src/results/filter-navbar.tsx +294 -261
- package/src/results/filter-sidebar/__tests__/utils.test.ts +129 -0
- package/src/results/filter-sidebar/index.tsx +270 -126
- package/src/results/filter-sidebar/utils.ts +196 -164
- package/src/results/generic/table-result-list.tsx +97 -99
- package/src/results/{table-with-images.tsx → information-unit-search-results-card-list.tsx} +125 -127
- package/src/results/{cards.tsx → information-unit-search-results-cards.tsx} +99 -99
- package/src/results/{table.tsx → information-unit-search-results-table.tsx} +104 -104
- package/src/results/pagination.tsx +81 -81
- package/src/results/summary.ts +30 -0
- package/src/results/utils.ts +54 -54
- package/src/search-input.tsx +70 -70
- package/src/share-button.tsx +49 -49
- package/src/stores/favorites-store.ts +88 -88
- package/src/stores/highlight-store.ts +15 -15
- package/src/stores/language-store.ts +14 -14
- package/src/stores/restriction-store.ts +11 -11
- package/src/stores/search-settings-store.ts +68 -64
- package/src/info/set-available-versions.tsx +0 -19
package/src/share-button.tsx
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import { Button } from "@c-rex/ui/button";
|
|
5
|
-
import { Share2 } from "lucide-react"
|
|
6
|
-
|
|
7
|
-
export const ShareButton = () => {
|
|
8
|
-
const [copied, setCopied] = useState(false);
|
|
9
|
-
const [shareData, setShareData] = useState({
|
|
10
|
-
title: '',
|
|
11
|
-
url: '',
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
setShareData({
|
|
16
|
-
title: document.title,
|
|
17
|
-
url: window.location.href,
|
|
18
|
-
});
|
|
19
|
-
}, []);
|
|
20
|
-
|
|
21
|
-
const handleShare = async () => {
|
|
22
|
-
if (navigator.share) {
|
|
23
|
-
try {
|
|
24
|
-
await navigator.share(shareData);
|
|
25
|
-
console.log('Compartilhado com sucesso');
|
|
26
|
-
} catch (err) {
|
|
27
|
-
console.log('Erro ao compartilhar:', err);
|
|
28
|
-
}
|
|
29
|
-
} else {
|
|
30
|
-
navigator.clipboard.writeText(shareData.url);
|
|
31
|
-
setCopied(true);
|
|
32
|
-
setTimeout(() => setCopied(false), 2000);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<div style={{ fontFamily: 'sans-serif' }}>
|
|
38
|
-
<Button
|
|
39
|
-
variant="ghost"
|
|
40
|
-
size="icon"
|
|
41
|
-
onClick={handleShare}
|
|
42
|
-
>
|
|
43
|
-
<Share2 />
|
|
44
|
-
</Button>
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Button } from "@c-rex/ui/button";
|
|
5
|
+
import { Share2 } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
export const ShareButton = () => {
|
|
8
|
+
const [copied, setCopied] = useState(false);
|
|
9
|
+
const [shareData, setShareData] = useState({
|
|
10
|
+
title: '',
|
|
11
|
+
url: '',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
setShareData({
|
|
16
|
+
title: document.title,
|
|
17
|
+
url: window.location.href,
|
|
18
|
+
});
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
const handleShare = async () => {
|
|
22
|
+
if (navigator.share) {
|
|
23
|
+
try {
|
|
24
|
+
await navigator.share(shareData);
|
|
25
|
+
console.log('Compartilhado com sucesso');
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.log('Erro ao compartilhar:', err);
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
navigator.clipboard.writeText(shareData.url);
|
|
31
|
+
setCopied(true);
|
|
32
|
+
setTimeout(() => setCopied(false), 2000);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div style={{ fontFamily: 'sans-serif' }}>
|
|
38
|
+
<Button
|
|
39
|
+
variant="ghost"
|
|
40
|
+
size="icon"
|
|
41
|
+
onClick={handleShare}
|
|
42
|
+
>
|
|
43
|
+
<Share2 />
|
|
44
|
+
</Button>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
import { Favorite } from "@c-rex/types";
|
|
2
|
-
import { create } from "zustand";
|
|
3
|
-
import { persist } from "zustand/middleware";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type FavoritesStore = {
|
|
7
|
-
favorites: Favorite[];
|
|
8
|
-
documents: Record<string, { topics: Favorite[], label?: string }>;
|
|
9
|
-
favoriteTopic: (documentId: string, id: string, label: string, color: string) => void;
|
|
10
|
-
unfavoriteTopic: (documentId: string, id: string) => void;
|
|
11
|
-
favoriteDocument: (id: string, label: string) => void;
|
|
12
|
-
unfavoriteDocument: (id: string) => void;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const useFavoritesStore = create<FavoritesStore>()(
|
|
16
|
-
persist((set) => ({
|
|
17
|
-
documents: {},
|
|
18
|
-
favorites: [],
|
|
19
|
-
favoriteTopic: (documentId: string, id: string, label: string, color: string) =>
|
|
20
|
-
set((state) => ({
|
|
21
|
-
documents: favoriteTopic(state.documents, documentId, id, label, color),
|
|
22
|
-
favorites: [...state.favorites, { id, label, color }, { id: documentId, label: "", color: "" }],
|
|
23
|
-
})),
|
|
24
|
-
unfavoriteTopic: (documentId: string, id: string) =>
|
|
25
|
-
set((state) => ({
|
|
26
|
-
documents: unfavoriteTopic(state.documents, documentId, id),
|
|
27
|
-
favorites: state.favorites.filter((topic) => topic.id !== id),
|
|
28
|
-
})),
|
|
29
|
-
favoriteDocument: (id: string, label: string) =>
|
|
30
|
-
set((state) => {
|
|
31
|
-
const documentsCopy = { ...state.documents };
|
|
32
|
-
if (documentsCopy[id]) {
|
|
33
|
-
return state;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
documents: {
|
|
38
|
-
...state.documents,
|
|
39
|
-
[id]: { topics: [], label },
|
|
40
|
-
},
|
|
41
|
-
favorites: [...state.favorites, { id, label, color: "" }],
|
|
42
|
-
}
|
|
43
|
-
}),
|
|
44
|
-
unfavoriteDocument: (id: string) =>
|
|
45
|
-
set((state) => {
|
|
46
|
-
const documentsCopy = { ...state.documents };
|
|
47
|
-
if (!documentsCopy[id]) {
|
|
48
|
-
return state;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const favoritesToRemove = documentsCopy[id]?.topics.map(topic => topic.id) || [];
|
|
52
|
-
const newFavorites = state.favorites.filter(fav => fav.id !== id && !favoritesToRemove.includes(fav.id));
|
|
53
|
-
delete documentsCopy[id];
|
|
54
|
-
return { documents: documentsCopy, favorites: newFavorites };
|
|
55
|
-
}),
|
|
56
|
-
}), {
|
|
57
|
-
name: "c-rex-favorites",
|
|
58
|
-
})
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const favoriteTopic = (documents: Record<string, { topics: Favorite[] }>, documentId: string, id: string, label: string, color: string): Record<string, { topics: Favorite[] }> => {
|
|
63
|
-
const currentDocument = documents[documentId];
|
|
64
|
-
const currentTopics = currentDocument?.topics ?? [];
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
...documents,
|
|
68
|
-
[documentId]: {
|
|
69
|
-
...currentDocument,
|
|
70
|
-
topics: [...currentTopics, { id, label, color }],
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const unfavoriteTopic = (documents: Record<string, { topics: Favorite[] }>, documentId: string, id: string): Record<string, { topics: Favorite[] }> => {
|
|
76
|
-
const currentDocument = documents[documentId];
|
|
77
|
-
if (!currentDocument) {
|
|
78
|
-
return documents;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
...documents,
|
|
83
|
-
[documentId]: {
|
|
84
|
-
...currentDocument,
|
|
85
|
-
topics: currentDocument.topics.filter(topic => topic.id !== id),
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
1
|
+
import { Favorite } from "@c-rex/types";
|
|
2
|
+
import { create } from "zustand";
|
|
3
|
+
import { persist } from "zustand/middleware";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
type FavoritesStore = {
|
|
7
|
+
favorites: Favorite[];
|
|
8
|
+
documents: Record<string, { topics: Favorite[], label?: string }>;
|
|
9
|
+
favoriteTopic: (documentId: string, id: string, label: string, color: string) => void;
|
|
10
|
+
unfavoriteTopic: (documentId: string, id: string) => void;
|
|
11
|
+
favoriteDocument: (id: string, label: string) => void;
|
|
12
|
+
unfavoriteDocument: (id: string) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const useFavoritesStore = create<FavoritesStore>()(
|
|
16
|
+
persist((set) => ({
|
|
17
|
+
documents: {},
|
|
18
|
+
favorites: [],
|
|
19
|
+
favoriteTopic: (documentId: string, id: string, label: string, color: string) =>
|
|
20
|
+
set((state) => ({
|
|
21
|
+
documents: favoriteTopic(state.documents, documentId, id, label, color),
|
|
22
|
+
favorites: [...state.favorites, { id, label, color }, { id: documentId, label: "", color: "" }],
|
|
23
|
+
})),
|
|
24
|
+
unfavoriteTopic: (documentId: string, id: string) =>
|
|
25
|
+
set((state) => ({
|
|
26
|
+
documents: unfavoriteTopic(state.documents, documentId, id),
|
|
27
|
+
favorites: state.favorites.filter((topic) => topic.id !== id),
|
|
28
|
+
})),
|
|
29
|
+
favoriteDocument: (id: string, label: string) =>
|
|
30
|
+
set((state) => {
|
|
31
|
+
const documentsCopy = { ...state.documents };
|
|
32
|
+
if (documentsCopy[id]) {
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
documents: {
|
|
38
|
+
...state.documents,
|
|
39
|
+
[id]: { topics: [], label },
|
|
40
|
+
},
|
|
41
|
+
favorites: [...state.favorites, { id, label, color: "" }],
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
unfavoriteDocument: (id: string) =>
|
|
45
|
+
set((state) => {
|
|
46
|
+
const documentsCopy = { ...state.documents };
|
|
47
|
+
if (!documentsCopy[id]) {
|
|
48
|
+
return state;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const favoritesToRemove = documentsCopy[id]?.topics.map(topic => topic.id) || [];
|
|
52
|
+
const newFavorites = state.favorites.filter(fav => fav.id !== id && !favoritesToRemove.includes(fav.id));
|
|
53
|
+
delete documentsCopy[id];
|
|
54
|
+
return { documents: documentsCopy, favorites: newFavorites };
|
|
55
|
+
}),
|
|
56
|
+
}), {
|
|
57
|
+
name: "c-rex-favorites",
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const favoriteTopic = (documents: Record<string, { topics: Favorite[] }>, documentId: string, id: string, label: string, color: string): Record<string, { topics: Favorite[] }> => {
|
|
63
|
+
const currentDocument = documents[documentId];
|
|
64
|
+
const currentTopics = currentDocument?.topics ?? [];
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
...documents,
|
|
68
|
+
[documentId]: {
|
|
69
|
+
...currentDocument,
|
|
70
|
+
topics: [...currentTopics, { id, label, color }],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const unfavoriteTopic = (documents: Record<string, { topics: Favorite[] }>, documentId: string, id: string): Record<string, { topics: Favorite[] }> => {
|
|
76
|
+
const currentDocument = documents[documentId];
|
|
77
|
+
if (!currentDocument) {
|
|
78
|
+
return documents;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
...documents,
|
|
83
|
+
[documentId]: {
|
|
84
|
+
...currentDocument,
|
|
85
|
+
topics: currentDocument.topics.filter(topic => topic.id !== id),
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { create } from "zustand";
|
|
2
|
-
import { persist } from "zustand/middleware";
|
|
3
|
-
|
|
4
|
-
type HighlightStoreType = {
|
|
5
|
-
enable: boolean;
|
|
6
|
-
toggleHighlight: (v: boolean) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const useHighlightStore = create<HighlightStoreType>()(
|
|
10
|
-
persist((set) => ({
|
|
11
|
-
enable: false,
|
|
12
|
-
toggleHighlight: (v) => set({ enable: v }),
|
|
13
|
-
}), {
|
|
14
|
-
name: "c-rex-highlight-settings",
|
|
15
|
-
})
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
import { persist } from "zustand/middleware";
|
|
3
|
+
|
|
4
|
+
type HighlightStoreType = {
|
|
5
|
+
enable: boolean;
|
|
6
|
+
toggleHighlight: (v: boolean) => void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useHighlightStore = create<HighlightStoreType>()(
|
|
10
|
+
persist((set) => ({
|
|
11
|
+
enable: false,
|
|
12
|
+
toggleHighlight: (v) => set({ enable: v }),
|
|
13
|
+
}), {
|
|
14
|
+
name: "c-rex-highlight-settings",
|
|
15
|
+
})
|
|
16
16
|
);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { LanguageAndCountries } from "@c-rex/interfaces";
|
|
2
|
-
import { create } from "zustand";
|
|
3
|
-
|
|
4
|
-
type LanguageStoreType = {
|
|
5
|
-
availableLanguages: LanguageAndCountries[];
|
|
6
|
-
setAvailableLanguages: (list: LanguageAndCountries[]) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const useLanguageStore = create<LanguageStoreType>()((set) => ({
|
|
10
|
-
availableLanguages: [],
|
|
11
|
-
setAvailableLanguages: (list) => {
|
|
12
|
-
set({ availableLanguages: list });
|
|
13
|
-
},
|
|
14
|
-
}));
|
|
1
|
+
import { LanguageAndCountries } from "@c-rex/interfaces";
|
|
2
|
+
import { create } from "zustand";
|
|
3
|
+
|
|
4
|
+
type LanguageStoreType = {
|
|
5
|
+
availableLanguages: LanguageAndCountries[];
|
|
6
|
+
setAvailableLanguages: (list: LanguageAndCountries[]) => void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useLanguageStore = create<LanguageStoreType>()((set) => ({
|
|
10
|
+
availableLanguages: [],
|
|
11
|
+
setAvailableLanguages: (list) => {
|
|
12
|
+
set({ availableLanguages: list });
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { create } from 'zustand';
|
|
2
|
-
|
|
3
|
-
type RestrictionStore = {
|
|
4
|
-
restrictionList: Map<string, string>;
|
|
5
|
-
setRestrictionList: (restrictionList: Map<string, string>) => void;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const useRestrictionStore = create<RestrictionStore>((set) => ({
|
|
9
|
-
restrictionList: new Map(),
|
|
10
|
-
setRestrictionList: (restrictionList) => set({ restrictionList }),
|
|
11
|
-
}));
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
|
|
3
|
+
type RestrictionStore = {
|
|
4
|
+
restrictionList: Map<string, string>;
|
|
5
|
+
setRestrictionList: (restrictionList: Map<string, string>) => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const useRestrictionStore = create<RestrictionStore>((set) => ({
|
|
9
|
+
restrictionList: new Map(),
|
|
10
|
+
setRestrictionList: (restrictionList) => set({ restrictionList }),
|
|
11
|
+
}));
|
|
@@ -1,64 +1,68 @@
|
|
|
1
|
-
import { OPERATOR_OPTIONS, WILD_CARD_OPTIONS } from "@c-rex/constants";
|
|
2
|
-
import { OperatorType, WildCardType } from "@c-rex/types";
|
|
3
|
-
import { create } from "zustand";
|
|
4
|
-
import { persist, createJSONStorage, StateStorage } from "zustand/middleware";
|
|
5
|
-
|
|
6
|
-
const cookieStorage: StateStorage = {
|
|
7
|
-
getItem: (name: string): string | null => {
|
|
8
|
-
if (typeof document === "undefined") return null;
|
|
9
|
-
const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
|
|
10
|
-
return match ? decodeURIComponent(match[2] as string) : null;
|
|
11
|
-
},
|
|
12
|
-
setItem: (name: string, value: string): void => {
|
|
13
|
-
if (typeof document === "undefined") return;
|
|
14
|
-
const maxAge = 60 * 60 * 24 * 365; // 1 year
|
|
15
|
-
document.cookie = `${name}=${encodeURIComponent(value)};path=/;max-age=${maxAge};SameSite=Lax`;
|
|
16
|
-
},
|
|
17
|
-
removeItem: (name: string): void => {
|
|
18
|
-
if (typeof document === "undefined") return;
|
|
19
|
-
document.cookie = `${name}=;path=/;max-age=0`;
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type SearchSettingsState = {
|
|
24
|
-
language?: string,
|
|
25
|
-
wildcard: WildCardType,
|
|
26
|
-
operator: OperatorType,
|
|
27
|
-
like: boolean,
|
|
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
|
-
)
|
|
1
|
+
import { OPERATOR_OPTIONS, WILD_CARD_OPTIONS } from "@c-rex/constants";
|
|
2
|
+
import { OperatorType, WildCardType } from "@c-rex/types";
|
|
3
|
+
import { create } from "zustand";
|
|
4
|
+
import { persist, createJSONStorage, StateStorage } from "zustand/middleware";
|
|
5
|
+
|
|
6
|
+
const cookieStorage: StateStorage = {
|
|
7
|
+
getItem: (name: string): string | null => {
|
|
8
|
+
if (typeof document === "undefined") return null;
|
|
9
|
+
const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
|
|
10
|
+
return match ? decodeURIComponent(match[2] as string) : null;
|
|
11
|
+
},
|
|
12
|
+
setItem: (name: string, value: string): void => {
|
|
13
|
+
if (typeof document === "undefined") return;
|
|
14
|
+
const maxAge = 60 * 60 * 24 * 365; // 1 year
|
|
15
|
+
document.cookie = `${name}=${encodeURIComponent(value)};path=/;max-age=${maxAge};SameSite=Lax`;
|
|
16
|
+
},
|
|
17
|
+
removeItem: (name: string): void => {
|
|
18
|
+
if (typeof document === "undefined") return;
|
|
19
|
+
document.cookie = `${name}=;path=/;max-age=0`;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type SearchSettingsState = {
|
|
24
|
+
language?: string,
|
|
25
|
+
wildcard: WildCardType,
|
|
26
|
+
operator: OperatorType,
|
|
27
|
+
like: boolean,
|
|
28
|
+
facetExcludeProperties?: string[],
|
|
29
|
+
metadataExcludeProperties?: string[],
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type SearchSettingsStore = SearchSettingsState & {
|
|
33
|
+
updatePreferences: (settings: Partial<SearchSettingsState>) => void,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const defaultSearchSettings: SearchSettingsState = {
|
|
37
|
+
//language: DEFAULT_LANG,
|
|
38
|
+
wildcard: WILD_CARD_OPTIONS.BOTH,
|
|
39
|
+
operator: OPERATOR_OPTIONS.OR,
|
|
40
|
+
like: false,
|
|
41
|
+
facetExcludeProperties: [],
|
|
42
|
+
metadataExcludeProperties: [],
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Helper function to read search settings from cookie on the server.
|
|
47
|
+
* Use this in Server Components with Next.js cookies() function.
|
|
48
|
+
* @param cookieValue - The raw cookie value from cookies().get("c-rex-search-settings")?.value
|
|
49
|
+
*/
|
|
50
|
+
export function getSearchSettingsFromCookie(cookieValue: string | undefined): SearchSettingsState {
|
|
51
|
+
if (!cookieValue) return defaultSearchSettings;
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(cookieValue);
|
|
54
|
+
return { ...defaultSearchSettings, ...parsed.state };
|
|
55
|
+
} catch {
|
|
56
|
+
return defaultSearchSettings;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const useSearchSettingsStore = create<SearchSettingsStore>()(
|
|
61
|
+
persist((set) => ({
|
|
62
|
+
...defaultSearchSettings,
|
|
63
|
+
updatePreferences: (settings) => set((state) => ({ ...state, ...settings })),
|
|
64
|
+
}), {
|
|
65
|
+
name: "c-rex-search-settings",
|
|
66
|
+
storage: createJSONStorage(() => cookieStorage),
|
|
67
|
+
})
|
|
68
|
+
);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
import { AvailableVersionsInterface } from "@c-rex/interfaces";
|
|
5
|
-
import { useAppConfig } from "@c-rex/contexts/config-provider";
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
versions: AvailableVersionsInterface[];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const SetAvailableVersions = ({ versions }: Props) => {
|
|
12
|
-
const { setAvailableVersions } = useAppConfig();
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
setAvailableVersions(versions);
|
|
16
|
-
}, [setAvailableVersions, versions]);
|
|
17
|
-
|
|
18
|
-
return null;
|
|
19
|
-
};
|