@c-rex/templates 0.1.20 → 0.1.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-rex/templates",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -4,6 +4,7 @@ import { Metadata } from "next";
4
4
  import { DocumentsPage } from "./page";
5
5
  import { PageWrapper } from "@c-rex/components/page-wrapper";
6
6
  import { DocumentArticleCollector } from "../../collectors/DocumentArticleCollector";
7
+ import { CrexSDK } from "@c-rex/core/sdk";
7
8
 
8
9
  type Props = {
9
10
  params: { id: string }
@@ -17,9 +18,15 @@ const getCachedDocumentData = cache(async (id: string) => {
17
18
 
18
19
 
19
20
  export const generateMetadata = async ({ params }: Props): Promise<Metadata> => {
20
-
21
21
  const { metaTags, rootNode } = await getCachedDocumentData(params.id);
22
- const title = rootNode?.informationUnits[0]?.labels[0]?.value;
22
+ const sdk = new CrexSDK()
23
+ const config = sdk.getServerConfig()
24
+
25
+ const pageTitle = rootNode?.informationUnits[0]?.labels[0]?.value as string;
26
+ const title = config.titles.sub
27
+ .replace("{{projectName}}", config.projectName)
28
+ .replace("{{pageTitle}}", pageTitle);
29
+
23
30
 
24
31
  const other: Record<string, string[]> = {}
25
32
 
@@ -3,6 +3,7 @@ import { TopicArticleCollector } from "../../collectors/TopicArticleCollector";
3
3
  import { Metadata } from "next";
4
4
  import { PageWrapper } from "@c-rex/components/page-wrapper";
5
5
  import { TopicsPage } from "./page";
6
+ import { CrexSDK } from "@c-rex/core/sdk";
6
7
 
7
8
  type Props = {
8
9
  params: { id: string }
@@ -15,9 +16,13 @@ const getCachedTopicData = cache(async (id: string) => {
15
16
  });
16
17
 
17
18
  export const generateMetadata = async ({ params }: Props): Promise<Metadata> => {
18
-
19
19
  const { metaTags, rootNode } = await getCachedTopicData(params.id);
20
- const title = rootNode?.informationUnits[0]?.labels[0]?.value;
20
+ const sdk = new CrexSDK()
21
+ const config = sdk.getServerConfig()
22
+ const pageTitle = rootNode?.informationUnits[0]?.labels[0]?.value as string;
23
+ const title = config.titles.sub
24
+ .replace("{{projectName}}", config.projectName)
25
+ .replace("{{pageTitle}}", pageTitle);
21
26
 
22
27
  const other: Record<string, string[]> = {}
23
28
 
@@ -68,12 +68,6 @@ export const ArticleWrapper = ({
68
68
  const toggleHighlight = useHighlightStore((state) => state.toggleHighlight);
69
69
  const { rightSidebar } = useMultiSidebar()
70
70
  const [query, setQuery] = useQueryState("q");
71
- const favoritesDocuments = useFavoritesStore((state) => state.documents);
72
- let favoritesList: Favorite[] = []
73
-
74
- if (Object.keys(favoritesDocuments).some(docId => docId === documentId)) {
75
- favoritesList = favoritesDocuments[documentId]?.topics || []
76
- }
77
71
 
78
72
  useEffect(() => {
79
73
  if (open && inputRef.current) {
@@ -111,6 +105,7 @@ export const ArticleWrapper = ({
111
105
  <div className="pr-4 relative">
112
106
  <RenderArticle htmlContent={htmlContent} contentLang={articleLang} />
113
107
 
108
+ {/*
114
109
  <div className="absolute top-0 right-0 flex flex-col gap-2 items-end">
115
110
  {favoritesList.map((item) => (
116
111
  <div
@@ -127,17 +122,21 @@ export const ArticleWrapper = ({
127
122
  `border-r-${item.color}`,
128
123
  )} />
129
124
  )}
130
- <span className="flex items-center justify-end h-8 opacity-0 group-hover:opacity-100 text-primary-foreground transition-all duration-300 text-right px-2">
125
+ <a
126
+ href={`../topics/${item.id}`}
127
+ className="flex items-center justify-end h-8 opacity-0 group-hover:opacity-100 text-primary-foreground transition-all duration-300 text-right px-2"
128
+ >
131
129
  <span
132
130
  className="text-right text-ellipsis overflow-hidden whitespace-nowrap"
133
131
  title={item.label}
134
132
  >
135
133
  {item.label}
136
134
  </span>
137
- </span>
135
+ </a>
138
136
  </div>
139
137
  ))}
140
138
  </div>
139
+ */}
141
140
  </div>
142
141
 
143
142
  <div className="w-full sm:w-auto justify-between bg-primary text-primary-foreground rounded-full shadow-lg flex sticky bottom-4 p-2 float-right gap-2 transition-all duration-300">
@@ -28,7 +28,7 @@ interface FilterSidebarProps {
28
28
  export const FilterSidebar: FC<FilterSidebarProps> = ({ tags, totalItemCount, updateFilterParam }) => {
29
29
  const t = useTranslations();
30
30
  const device = useBreakpoint();
31
- const isMobile = (device === DEVICE_OPTIONS.MOBILE);
31
+ const isMobile = device !== null && (device === DEVICE_OPTIONS.MOBILE);
32
32
 
33
33
  if (Object.keys(tags).length === 0) return null;
34
34
 
package/src/home/page.tsx CHANGED
@@ -37,7 +37,7 @@ export const HomePage: FC<HomePageProps> = ({ data }) => {
37
37
  const t = useTranslations();
38
38
  const { setLoading } = useSearchContext();
39
39
  const device = useBreakpoint();
40
- const isMobile = device === DEVICE_OPTIONS.MOBILE;
40
+ const isMobile = device !== null && device === DEVICE_OPTIONS.MOBILE;
41
41
  const [open, setOpen] = useState<boolean>(false)
42
42
  const [params, setParams] = useQueryStates({
43
43
  language: parseAsString,
@@ -37,7 +37,7 @@ export const HomePage: FC<HomePageProps> = ({ data }) => {
37
37
  const t = useTranslations();
38
38
  const { setLoading } = useSearchContext();
39
39
  const device = useBreakpoint();
40
- const isMobile = device === DEVICE_OPTIONS.MOBILE;
40
+ const isMobile = device !== null && device === DEVICE_OPTIONS.MOBILE;
41
41
  const [open, setOpen] = useState<boolean>(false)
42
42
  const [params, setParams] = useQueryStates({
43
43
  language: parseAsString,
package/src/layout.tsx CHANGED
@@ -4,13 +4,45 @@ import { getLocale } from "next-intl/server";
4
4
  import { Toaster } from "@c-rex/ui/sonner"
5
5
  import { AppConfigProvider } from "@c-rex/contexts/config-provider";
6
6
  import { NuqsAdapter } from 'nuqs/adapters/next/app'
7
+ import { cookies } from "next/headers";
8
+ import { CrexSDK } from "@c-rex/core/sdk";
9
+ import { getIssuerMetadata } from "@c-rex/core/OIDC";
10
+ import { resolveUILanguage, resolveContentLanguage } from "./utils";
11
+ import { LanguageService } from "@c-rex/services";
12
+ import { CONTENT_LANG_KEY, UI_LANG_KEY } from "@c-rex/constants";
7
13
 
8
14
  interface DefaultRootLayoutProps {
9
15
  children: React.ReactNode;
10
16
  }
11
17
 
12
18
  export const DefaultRootLayout = async ({ children }: DefaultRootLayoutProps) => {
19
+ const sdk = new CrexSDK()
13
20
  const locale = await getLocale();
21
+ const metadata = await getIssuerMetadata();
22
+ const cookieStore = cookies();
23
+ const uiLangCookie = cookieStore.get(UI_LANG_KEY)?.value ?? null;
24
+ const clientConfigs = sdk.getClientConfig();
25
+ const serverConfigs = sdk.getServerConfig();
26
+ const languageService = new LanguageService()
27
+ const contentLangCookie = cookieStore.get(CONTENT_LANG_KEY)?.value ?? null;
28
+
29
+ sdk.updateConfigProp('OIDC', {
30
+ ...serverConfigs.OIDC,
31
+ issuerMetadata: metadata
32
+ });
33
+
34
+ const availableLanguages = await languageService.getLanguagesAndCountries();
35
+
36
+ const uiLang = resolveUILanguage({
37
+ uiLangCookie,
38
+ defaultLang: clientConfigs.languageSwitcher.default
39
+ });
40
+
41
+ const contentLang = resolveContentLanguage({
42
+ contentLangCookie,
43
+ availableLanguages,
44
+ defaultLang: clientConfigs.languageSwitcher.default
45
+ });
14
46
 
15
47
  return (
16
48
  <NuqsAdapter>
@@ -20,7 +52,12 @@ export const DefaultRootLayout = async ({ children }: DefaultRootLayoutProps) =>
20
52
  </head>
21
53
  <body className="min-h-screen bg-background font-sans antialiased">
22
54
  <NextIntlClientProvider>
23
- <AppConfigProvider>
55
+ <AppConfigProvider
56
+ uiLang={uiLang}
57
+ contentLang={contentLang}
58
+ availableLanguages={availableLanguages}
59
+ initialConfig={clientConfigs}
60
+ >
24
61
  <Toaster />
25
62
  {children}
26
63
  </AppConfigProvider>
package/src/utils.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { UI_LANG_OPTIONS } from "@c-rex/constants";
2
+ import { headers } from "next/headers";
3
+
4
+ const getBrowserLangFromHeader = (): string => {
5
+ const h = headers();
6
+ const accept = h.get("accept-language"); // ex: "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
7
+
8
+ if (!accept) return "";
9
+
10
+ return accept.split(",")[0]?.toLowerCase() || "";
11
+ }
12
+
13
+
14
+ export const resolveUILanguage = ({
15
+ uiLangCookie,
16
+ defaultLang,
17
+ }: {
18
+ uiLangCookie?: string | null;
19
+ defaultLang: string;
20
+ }): string => {
21
+ const browserLang = getBrowserLangFromHeader();
22
+
23
+ if (uiLangCookie) return uiLangCookie;
24
+ if (browserLang && UI_LANG_OPTIONS.includes(browserLang)) return browserLang;
25
+
26
+ return defaultLang;
27
+ }
28
+
29
+ export const resolveContentLanguage = ({
30
+ contentLangCookie,
31
+ availableLanguages,
32
+ defaultLang,
33
+ }: {
34
+ contentLangCookie?: string | null;
35
+ availableLanguages: { value: string }[];
36
+ defaultLang: string;
37
+ }): string => {
38
+ const browserLang = getBrowserLangFromHeader();
39
+
40
+ if (contentLangCookie) return contentLangCookie;
41
+
42
+ const hasLang = browserLang
43
+ ? availableLanguages.some((l) => l.value === browserLang)
44
+ : false;
45
+
46
+ if (hasLang) return browserLang;
47
+
48
+ return defaultLang;
49
+ }