@c-rex/components 0.1.37 → 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.
Files changed (146) hide show
  1. package/README.md +73 -73
  2. package/package.json +250 -235
  3. package/src/article/article-action-bar.tsx +110 -110
  4. package/src/article/article-content.tsx +18 -46
  5. package/src/autocomplete.tsx +201 -201
  6. package/src/breadcrumb.tsx +124 -124
  7. package/src/carousel/carousel.tsx +353 -352
  8. package/src/check-article-lang.tsx +47 -43
  9. package/src/directoryNodes/directory-tree-context.tsx +388 -0
  10. package/src/directoryNodes/tree-of-content.tsx +68 -67
  11. package/src/documents/result-list.tsx +124 -127
  12. package/src/favorites/bookmark-button.tsx +97 -79
  13. package/src/favorites/favorite-button.tsx +137 -74
  14. package/src/footer/footer-shell.tsx +52 -0
  15. package/src/footer/footer.tsx +7 -0
  16. package/src/footer/legal-links-block.tsx +25 -0
  17. package/src/footer/organization-contact-block.tsx +94 -0
  18. package/src/footer/social-links-block.tsx +38 -0
  19. package/src/footer/types.ts +10 -0
  20. package/src/footer/vcard-footer.tsx +72 -0
  21. package/src/generated/client-components.tsx +1366 -1350
  22. package/src/generated/create-client-request.tsx +116 -113
  23. package/src/generated/create-server-request.tsx +70 -61
  24. package/src/generated/create-suggestions-request.tsx +55 -55
  25. package/src/generated/server-components.tsx +1056 -1056
  26. package/src/generated/suggestions.tsx +302 -299
  27. package/src/icons/file-icon.tsx +8 -8
  28. package/src/icons/flag-icon.tsx +15 -15
  29. package/src/icons/loading.tsx +11 -11
  30. package/src/icons/social-icon.tsx +24 -0
  31. package/src/info/info-card.tsx +43 -0
  32. package/src/info/{info-table.tsx → information-unit-metadata-grid.tsx} +157 -146
  33. package/src/info/shared.tsx +49 -25
  34. package/src/navbar/language-switcher/content-language-switch.tsx +92 -92
  35. package/src/navbar/language-switcher/shared.tsx +33 -33
  36. package/src/navbar/language-switcher/ui-language-switch.tsx +37 -38
  37. package/src/navbar/navbar.tsx +157 -148
  38. package/src/navbar/settings.tsx +62 -62
  39. package/src/navbar/sign-in-out-btns.tsx +35 -35
  40. package/src/navbar/user-menu.tsx +60 -60
  41. package/src/page-wrapper.tsx +54 -31
  42. package/src/render-article.module.css +155 -0
  43. package/src/render-article.tsx +75 -68
  44. package/src/renditions/file-download.tsx +83 -83
  45. package/src/renditions/html.tsx +64 -64
  46. package/src/renditions/image/container.tsx +54 -54
  47. package/src/renditions/image/rendition.tsx +55 -55
  48. package/src/restriction-menu/restriction-menu-container.tsx +117 -53
  49. package/src/restriction-menu/restriction-menu-item.tsx +155 -147
  50. package/src/restriction-menu/restriction-menu.tsx +341 -157
  51. package/src/results/dialog-filter.tsx +166 -166
  52. package/src/results/empty.tsx +15 -15
  53. package/src/results/filter-navbar.tsx +294 -261
  54. package/src/results/filter-sidebar/__tests__/utils.test.ts +129 -0
  55. package/src/results/filter-sidebar/index.tsx +270 -126
  56. package/src/results/filter-sidebar/utils.ts +196 -164
  57. package/src/results/generic/table-result-list.tsx +97 -99
  58. package/src/results/{table-with-images.tsx → information-unit-search-results-card-list.tsx} +125 -127
  59. package/src/results/{cards.tsx → information-unit-search-results-cards.tsx} +99 -99
  60. package/src/results/{table.tsx → information-unit-search-results-table.tsx} +104 -104
  61. package/src/results/pagination.tsx +81 -81
  62. package/src/results/summary.ts +30 -0
  63. package/src/results/utils.ts +54 -47
  64. package/src/search-input.tsx +70 -70
  65. package/src/share-button.tsx +49 -49
  66. package/src/stores/favorites-store.ts +88 -88
  67. package/src/stores/highlight-store.ts +15 -15
  68. package/src/stores/language-store.ts +14 -43
  69. package/src/stores/restriction-store.ts +11 -11
  70. package/src/stores/search-settings-store.ts +68 -64
  71. package/src/article/article-action-bar.analysis.md +0 -15
  72. package/src/article/article-action-bar.stories.tsx +0 -15
  73. package/src/article/article-content.analysis.md +0 -15
  74. package/src/article/article-content.stories.tsx +0 -21
  75. package/src/autocomplete.analysis.md +0 -17
  76. package/src/breadcrumb.analysis.md +0 -15
  77. package/src/carousel/carousel.analysis.md +0 -17
  78. package/src/check-article-lang.analysis.md +0 -15
  79. package/src/directoryNodes/tree-of-content.analysis.md +0 -14
  80. package/src/directoryNodes/tree-of-content.stories.tsx +0 -22
  81. package/src/documents/result-list.analysis.md +0 -14
  82. package/src/documents/result-list.stories.tsx +0 -19
  83. package/src/favorites/bookmark-button.analysis.md +0 -17
  84. package/src/favorites/bookmark-button.stories.tsx +0 -19
  85. package/src/favorites/favorite-button.analysis.md +0 -18
  86. package/src/favorites/favorite-button.stories.tsx +0 -22
  87. package/src/icons/file-icon.analysis.md +0 -14
  88. package/src/icons/file-icon.stories.tsx +0 -19
  89. package/src/icons/flag-icon.analysis.md +0 -14
  90. package/src/icons/flag-icon.stories.tsx +0 -25
  91. package/src/icons/loading.analysis.md +0 -14
  92. package/src/icons/loading.stories.tsx +0 -21
  93. package/src/info/info-table.analysis.md +0 -15
  94. package/src/info/shared.analysis.md +0 -14
  95. package/src/info/stories/info-table.stories.tsx +0 -31
  96. package/src/info/stories/shared.stories.tsx +0 -24
  97. package/src/navbar/language-switcher/content-language-switch.analysis.md +0 -15
  98. package/src/navbar/language-switcher/shared.analysis.md +0 -14
  99. package/src/navbar/language-switcher/ui-language-switch.analysis.md +0 -15
  100. package/src/navbar/navbar.analysis.md +0 -14
  101. package/src/navbar/settings.analysis.md +0 -14
  102. package/src/navbar/sign-in-out-btns.analysis.md +0 -14
  103. package/src/navbar/stories/navbar.stories.tsx +0 -31
  104. package/src/navbar/stories/settings.stories.tsx +0 -15
  105. package/src/navbar/stories/sign-in-out-btns.stories.tsx +0 -15
  106. package/src/navbar/stories/user-menu.stories.tsx +0 -20
  107. package/src/navbar/user-menu.analysis.md +0 -14
  108. package/src/page-wrapper.analysis.md +0 -14
  109. package/src/render-article.analysis.md +0 -15
  110. package/src/renditions/file-download.analysis.md +0 -14
  111. package/src/renditions/file-download.stories.tsx +0 -19
  112. package/src/renditions/html.analysis.md +0 -17
  113. package/src/renditions/html.stories.tsx +0 -19
  114. package/src/renditions/image/container.analysis.md +0 -15
  115. package/src/renditions/image/container.stories.tsx +0 -19
  116. package/src/renditions/image/rendition.analysis.md +0 -14
  117. package/src/renditions/image/rendition.stories.tsx +0 -19
  118. package/src/restriction-menu/restriction-menu-container.analysis.md +0 -14
  119. package/src/restriction-menu/restriction-menu-item.analysis.md +0 -14
  120. package/src/restriction-menu/restriction-menu.analysis.md +0 -17
  121. package/src/results/analysis/cards.analysis.md +0 -14
  122. package/src/results/analysis/dialog-filter.analysis.md +0 -17
  123. package/src/results/analysis/empty.analysis.md +0 -14
  124. package/src/results/analysis/filter-navbar.analysis.md +0 -16
  125. package/src/results/analysis/pagination.analysis.md +0 -14
  126. package/src/results/analysis/table-with-images.analysis.md +0 -15
  127. package/src/results/analysis/table.analysis.md +0 -15
  128. package/src/results/filter-sidebar/index.analysis.md +0 -14
  129. package/src/results/generic/table-result-list.analysis.md +0 -15
  130. package/src/results/generic/table-result-list.stories.tsx +0 -21
  131. package/src/results/stories/cards.stories.tsx +0 -66
  132. package/src/results/stories/dialog-filter.stories.tsx +0 -20
  133. package/src/results/stories/empty.stories.tsx +0 -25
  134. package/src/results/stories/filter-navbar.stories.tsx +0 -19
  135. package/src/results/stories/filter-sidebar.stories.tsx +0 -20
  136. package/src/results/stories/pagination.stories.tsx +0 -24
  137. package/src/results/stories/table-with-images.stories.tsx +0 -19
  138. package/src/results/stories/table.stories.tsx +0 -78
  139. package/src/search-input.analysis.md +0 -15
  140. package/src/share-button.analysis.md +0 -19
  141. package/src/stories/autocomplete.stories.tsx +0 -20
  142. package/src/stories/breadcrumb.stories.tsx +0 -93
  143. package/src/stories/check-article-lang.stories.tsx +0 -22
  144. package/src/stories/render-article.stories.tsx +0 -19
  145. package/src/stories/search-input.stories.tsx +0 -21
  146. package/src/stories/share-button.stories.tsx +0 -15
@@ -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
-
64
- const documentsCopy = { ...documents };
65
- const notFound = documents[documentId] == undefined;
66
-
67
- if (notFound) {
68
- documentsCopy[documentId] = { topics: [] };
69
- }
70
-
71
- documentsCopy[documentId]!.topics.push({ id, label, color });
72
-
73
- return documentsCopy
74
- };
75
-
76
- const unfavoriteTopic = (documents: Record<string, { topics: Favorite[] }>, documentId: string, id: string): Record<string, { topics: Favorite[] }> => {
77
-
78
- const documentsCopy = { ...documents };
79
- const notFound = documents[documentId] == undefined;
80
-
81
- if (notFound) {
82
- return documentsCopy;
83
- }
84
-
85
- documentsCopy[documentId]!.topics = documentsCopy[documentId]!.topics.filter(topic => topic.id !== id);
86
-
87
- return documentsCopy
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,43 +1,14 @@
1
- import { LanguageAndCountries } from "@c-rex/interfaces";
2
- import { create } from "zustand";
3
- import { persist, createJSONStorage, StateStorage } from "zustand/middleware";
4
-
5
- const cookieStorage: StateStorage = {
6
- getItem: (name: string): string | null => {
7
- if (typeof document === "undefined") return null;
8
- const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
9
- return match ? decodeURIComponent(match[2] as string) : null;
10
- },
11
- setItem: (name: string, value: string): void => {
12
- if (typeof document === "undefined") return;
13
- const maxAge = 60 * 60 * 24 * 365; // 1 year
14
- document.cookie = `${name}=${encodeURIComponent(value)};path=/;max-age=${maxAge};SameSite=Lax`;
15
- },
16
- removeItem: (name: string): void => {
17
- if (typeof document === "undefined") return;
18
- document.cookie = `${name}=;path=/;max-age=0`;
19
- },
20
- };
21
-
22
- type LanguageStoreType = {
23
- uiLang: string;
24
- availableLanguages: LanguageAndCountries[];
25
- setUiLang: (v: string) => void;
26
- setAvailableLanguages: (list: LanguageAndCountries[]) => void;
27
- };
28
-
29
- export const useLanguageStore = create<LanguageStoreType>()(
30
- persist((set) => ({
31
- uiLang: "",
32
- availableLanguages: [],
33
- setUiLang: (v) => {
34
- set({ uiLang: v });
35
- },
36
- setAvailableLanguages: (list) => {
37
- set({ availableLanguages: list });
38
- },
39
- }), {
40
- name: "c-rex-language-store",
41
- storage: createJSONStorage(() => cookieStorage),
42
- })
43
- );
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
- export type SearchSettingsStore = SearchSettingsState & {
31
- updatePreferences: (settings: Partial<SearchSettingsState>) => void,
32
- }
33
-
34
- export const defaultSearchSettings: SearchSettingsState = {
35
- //language: DEFAULT_LANG,
36
- wildcard: WILD_CARD_OPTIONS.BOTH,
37
- operator: OPERATOR_OPTIONS.OR,
38
- like: false,
39
- }
40
-
41
- /**
42
- * Helper function to read search settings from cookie on the server.
43
- * Use this in Server Components with Next.js cookies() function.
44
- * @param cookieValue - The raw cookie value from cookies().get("c-rex-search-settings")?.value
45
- */
46
- export function getSearchSettingsFromCookie(cookieValue: string | undefined): SearchSettingsState {
47
- if (!cookieValue) return defaultSearchSettings;
48
- try {
49
- const parsed = JSON.parse(cookieValue);
50
- return { ...defaultSearchSettings, ...parsed.state };
51
- } catch {
52
- return defaultSearchSettings;
53
- }
54
- }
55
-
56
- export const useSearchSettingsStore = create<SearchSettingsStore>()(
57
- persist((set) => ({
58
- ...defaultSearchSettings,
59
- updatePreferences: (settings) => set((state) => ({ ...state, ...settings })),
60
- }), {
61
- name: "c-rex-search-settings",
62
- storage: createJSONStorage(() => cookieStorage),
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,15 +0,0 @@
1
- # Analysis: article-action-bar
2
-
3
- - Component: packages/components/src/article/article-action-bar.tsx
4
- - Type: Client component
5
- - Detected signals: useQueryStates=no, stores=yes, window/document=no, effects=yes, fetch/call=no
6
-
7
- ## Possible re-render causes
8
- - Store subscriptions can re-render this component whenever the selected slice changes.
9
- - Effects that update state can add extra renders on mount and dependency changes.
10
-
11
- ## Possible bugs/risks
12
- - No critical bug is evident in this quick static pass; keep tests for error and loading paths.
13
-
14
- ## Recommended improvements
15
- - Standardize loading/error handling and add regression tests to prevent divergent behavior across consuming apps.
@@ -1,15 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { ArticleActionBar } from '../article-action-bar';
3
-
4
- const meta: Meta<typeof ArticleActionBar> = {
5
- title: 'Components/Article/ActionBar',
6
- component: ArticleActionBar,
7
- parameters: {
8
- layout: 'centered',
9
- },
10
- tags: ['autodocs'],
11
- };
12
- export default meta;
13
- type Story = StoryObj<typeof ArticleActionBar>;
14
-
15
- export const Basic: Story = {};
@@ -1,15 +0,0 @@
1
- # Analysis: article-content
2
-
3
- - Component: packages/components/src/article/article-content.tsx
4
- - Type: Server component
5
- - Detected signals: useQueryStates=no, stores=no, window/document=no, effects=no, fetch/call=yes
6
-
7
- ## Possible re-render causes
8
- - No obvious excessive re-render trigger beyond normal prop/context updates.
9
-
10
- ## Possible bugs/risks
11
- - Async flows can hit race conditions during fast param/route changes.
12
-
13
- ## Recommended improvements
14
- - Consider cancellation guards (isMounted or AbortController) and standardized error handling.
15
-
@@ -1,21 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { ArticleContent } from '../article-content';
3
-
4
- const meta: Meta<typeof ArticleContent> = {
5
- title: 'Components/Article/Content',
6
- component: ArticleContent,
7
- parameters: {
8
- layout: 'centered',
9
- },
10
- tags: ['autodocs'],
11
- };
12
- export default meta;
13
- type Story = StoryObj<typeof ArticleContent>;
14
-
15
- export const Basic: Story = {
16
- args: {
17
- renditions: [], // Não renderiza conteúdo
18
- },
19
- };
20
-
21
- // Exemplo completo depende de dados reais de RenditionModel e fetch, normalmente mockado em ambiente de Storybook.
@@ -1,17 +0,0 @@
1
- # Analysis: autocomplete
2
-
3
- - Component: packages/components/src/autocomplete.tsx
4
- - Type: Client component
5
- - Detected signals: useQueryStates=no, stores=no, window/document=yes, effects=yes, fetch/call=no
6
-
7
- ## Possible re-render causes
8
- - Effects that update state can add extra renders on mount and dependency changes.
9
-
10
- ## Possible bugs/risks
11
- - Access to window/document needs care to avoid hydration mismatch and non-browser runtime issues.
12
- - The component renders list-heavy UI; key stability and memoization strongly affect perceived performance.
13
-
14
- ## Recommended improvements
15
- - Keep browser-only access inside event handlers or useEffect, not in initial render paths.
16
- - Review key strategy and extract memoized subcomponents for large-list rendering.
17
-
@@ -1,15 +0,0 @@
1
- # Analysis: breadcrumb
2
-
3
- - Component: packages/components/src/breadcrumb.tsx
4
- - Type: Client component
5
- - Detected signals: useQueryStates=no, stores=no, window/document=no, effects=no, fetch/call=no
6
-
7
- ## Possible re-render causes
8
- - No obvious excessive re-render trigger beyond normal prop/context updates.
9
-
10
- ## Possible bugs/risks
11
- - The component renders list-heavy UI; key stability and memoization strongly affect perceived performance.
12
-
13
- ## Recommended improvements
14
- - Review key strategy and extract memoized subcomponents for large-list rendering.
15
-
@@ -1,17 +0,0 @@
1
- # Analysis: carousel
2
-
3
- - Component: packages/components/src/carousel/carousel.tsx
4
- - Type: Client component
5
- - Detected signals: useQueryStates=no, stores=no, window/document=yes, effects=yes, fetch/call=no
6
-
7
- ## Possible re-render causes
8
- - Effects that update state can add extra renders on mount and dependency changes.
9
-
10
- ## Possible bugs/risks
11
- - Access to window/document needs care to avoid hydration mismatch and non-browser runtime issues.
12
- - The component renders list-heavy UI; key stability and memoization strongly affect perceived performance.
13
-
14
- ## Recommended improvements
15
- - Keep browser-only access inside event handlers or useEffect, not in initial render paths.
16
- - Review key strategy and extract memoized subcomponents for large-list rendering.
17
-