@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 +1 -1
- package/src/articles/documents/layout.tsx +9 -2
- package/src/articles/topics/layout.tsx +7 -2
- package/src/articles/wrapper.tsx +7 -8
- package/src/home/components/filter-sidebar.tsx +1 -1
- package/src/home/page.tsx +1 -1
- package/src/home/page2.tsx +1 -1
- package/src/layout.tsx +38 -1
- package/src/utils.ts +49 -0
package/package.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
package/src/articles/wrapper.tsx
CHANGED
|
@@ -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
|
-
<
|
|
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
|
-
</
|
|
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,
|
package/src/home/page2.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,
|
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
|
+
}
|