Skip to content

Commit 12e98c8

Browse files
committed
The page blocks are fully ported to use page-primitives; page builder UI enhancements; Page switcher in page builder; page blocks picks the theme mostly (wip); the API returns default theme when no theme is set;
1 parent 066caca commit 12e98c8

File tree

34 files changed

+320
-257
lines changed

34 files changed

+320
-257
lines changed

apps/web/app/(with-contexts)/(with-layout)/home-page-layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import {
66
ServerConfigContext,
77
SiteInfoContext,
88
TypefacesContext,
9+
ThemeContext,
910
} from "@components/contexts";
1011
import { MasterLayout } from "@components/public/base-layout";
1112
import { Profile } from "@courselit/common-models";
12-
import { defaultTheme } from "@courselit/page-primitives";
1313
import { getPage } from "@ui-lib/utils";
1414
import { useContext, useEffect, useState } from "react";
1515

@@ -24,6 +24,7 @@ export default function HomepageLayout({
2424
const [page, setPage] = useState<any>(null);
2525
const config = useContext(ServerConfigContext);
2626
const { profile } = useContext(ProfileContext);
27+
const theme = useContext(ThemeContext);
2728

2829
useEffect(() => {
2930
if (address.backend) {
@@ -41,8 +42,8 @@ export default function HomepageLayout({
4142
title={page.title}
4243
typefaces={typefaces}
4344
siteInfo={siteinfo}
44-
// theme={{ name: "", active: true, styles: {} }}
4545
dispatch={() => {}}
46+
theme={theme}
4647
state={{
4748
config: config,
4849
siteinfo,
@@ -53,7 +54,7 @@ export default function HomepageLayout({
5354
checked: profile ? true : false,
5455
},
5556
networkAction: false,
56-
theme: defaultTheme,
57+
theme,
5758
typefaces,
5859
message: {
5960
message: "",

apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import {
66
ProfileContext,
77
ServerConfigContext,
88
SiteInfoContext,
9+
ThemeContext,
910
TypefacesContext,
1011
} from "@components/contexts";
1112
import { Profile } from "@courselit/common-models";
12-
import { defaultTheme } from "@courselit/page-primitives";
1313
import { useSearchParams } from "next/navigation";
1414
import { useContext } from "react";
1515

@@ -22,6 +22,7 @@ export default function Page({ params }: { params: { id: string } }) {
2222
const typefaces = useContext(TypefacesContext);
2323
const { profile } = useContext(ProfileContext);
2424
const config = useContext(ServerConfigContext);
25+
const theme = useContext(ThemeContext);
2526

2627
return (
2728
<PageEditor
@@ -47,7 +48,7 @@ export default function Page({ params }: { params: { id: string } }) {
4748
checked: profile ? true : false,
4849
},
4950
networkAction: false,
50-
theme: defaultTheme,
51+
theme,
5152
typefaces: [
5253
{
5354
section: "default",

apps/web/app/(with-contexts)/layout-with-context.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
"use client";
22

33
import { ReactNode, useEffect, useState, Suspense } from "react";
4-
import { SiteInfo, Typeface, ServerConfig } from "@courselit/common-models";
4+
import {
5+
SiteInfo,
6+
Typeface,
7+
ServerConfig,
8+
Theme,
9+
} from "@courselit/common-models";
510
import { defaultState } from "@components/default-state";
611
import { FetchBuilder } from "@courselit/utils";
712
import {
@@ -10,6 +15,7 @@ import {
1015
SiteInfoContext,
1116
TypefacesContext,
1217
ServerConfigContext,
18+
ThemeContext,
1319
} from "@components/contexts";
1420
import { Toaster, useToast } from "@courselit/components-library";
1521
import { TOAST_TITLE_ERROR } from "@ui-config/strings";
@@ -20,13 +26,15 @@ function LayoutContent({
2026
children,
2127
siteinfo,
2228
typefaces,
29+
theme,
2330
config,
2431
session,
2532
}: {
2633
address: string;
2734
children: ReactNode;
2835
siteinfo: SiteInfo;
2936
typefaces: Typeface[];
37+
theme: Theme;
3038
config: ServerConfig;
3139
session: Session | null;
3240
}) {
@@ -93,13 +101,15 @@ function LayoutContent({
93101
}}
94102
>
95103
<SiteInfoContext.Provider value={siteinfo}>
96-
<ProfileContext.Provider value={{ profile, setProfile }}>
97-
<TypefacesContext.Provider value={typefaces}>
98-
<ServerConfigContext.Provider value={config}>
99-
<Suspense fallback={null}>{children}</Suspense>
100-
</ServerConfigContext.Provider>
101-
</TypefacesContext.Provider>
102-
</ProfileContext.Provider>
104+
<ThemeContext.Provider value={theme}>
105+
<ProfileContext.Provider value={{ profile, setProfile }}>
106+
<TypefacesContext.Provider value={typefaces}>
107+
<ServerConfigContext.Provider value={config}>
108+
<Suspense fallback={null}>{children}</Suspense>
109+
</ServerConfigContext.Provider>
110+
</TypefacesContext.Provider>
111+
</ProfileContext.Provider>
112+
</ThemeContext.Provider>
103113
</SiteInfoContext.Provider>
104114
<Toaster />
105115
</AddressContext.Provider>
@@ -111,6 +121,7 @@ export default function Layout(props: {
111121
children: ReactNode;
112122
siteinfo: SiteInfo;
113123
typefaces: Typeface[];
124+
theme: Theme;
114125
config: ServerConfig;
115126
session: Session | null;
116127
}) {

apps/web/app/(with-contexts)/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export default async function Layout({
7373
address={address}
7474
siteinfo={formatSiteInfo(siteInfoResponse.site.settings)}
7575
typefaces={siteInfoResponse.site.typefaces}
76+
theme={siteInfoResponse.site.theme}
7677
config={config}
7778
session={session}
7879
>

apps/web/components/admin/page-editor/index.tsx

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import {
5656
SelectTrigger,
5757
SelectValue,
5858
} from "@/components/ui/select";
59+
import { ThemeContext } from "@components/contexts";
5960

6061
const EditWidget = dynamic(() => import("./edit-widget"));
6162
const AddWidget = dynamic(() => import("./add-widget"));
@@ -110,8 +111,8 @@ export default function PageEditor({
110111
const [primaryFontFamily, setPrimaryFontFamily] =
111112
useState("Roboto, sans-serif");
112113
const [loading, setLoading] = useState(false);
113-
const [draftTheme, setDraftTheme] = useState<Theme>();
114-
const [theme, setTheme] = useState<Theme>();
114+
const [draftTheme, setDraftTheme] = useState<Theme>(state.theme);
115+
// const [theme, setTheme] = useState<Theme>(state.theme);
115116
const { toast } = useToast();
116117
const [pages, setPages] = useState<Page[]>([]);
117118
const [loadingPages, setLoadingPages] = useState(true);
@@ -131,13 +132,13 @@ export default function PageEditor({
131132
useEffect(() => {
132133
loadDraftTypefaces();
133134
loadPage();
134-
135+
135136
loadPages();
136137
}, [address.backend, dispatch]);
137138

138-
async function loadPages() {
139-
setLoadingPages(true);
140-
const query = `
139+
async function loadPages() {
140+
setLoadingPages(true);
141+
const query = `
141142
query {
142143
pages: getPages(type: SITE) {
143144
pageId,
@@ -147,28 +148,28 @@ export default function PageEditor({
147148
}
148149
}
149150
`;
150-
const fetch = new FetchBuilder()
151-
.setUrl(`${address.backend}/api/graph`)
152-
.setPayload(query)
153-
.setIsGraphQLEndpoint(true)
154-
.build();
155-
try {
156-
dispatch && dispatch(networkAction(true));
157-
const response = await fetch.exec();
158-
if (response.pages) {
159-
setPages(response.pages);
160-
}
161-
} catch (err: any) {
162-
toast({
163-
title: TOAST_TITLE_ERROR,
164-
description: err.message || "Failed to load pages",
165-
variant: "destructive",
166-
});
167-
} finally {
168-
setLoadingPages(false);
169-
dispatch && dispatch(networkAction(false));
151+
const fetch = new FetchBuilder()
152+
.setUrl(`${address.backend}/api/graph`)
153+
.setPayload(query)
154+
.setIsGraphQLEndpoint(true)
155+
.build();
156+
try {
157+
dispatch && dispatch(networkAction(true));
158+
const response = await fetch.exec();
159+
if (response.pages) {
160+
setPages(response.pages);
170161
}
162+
} catch (err: any) {
163+
toast({
164+
title: TOAST_TITLE_ERROR,
165+
description: err.message || "Failed to load pages",
166+
variant: "destructive",
167+
});
168+
} finally {
169+
setLoadingPages(false);
170+
dispatch && dispatch(networkAction(false));
171171
}
172+
}
172173

173174
useEffect(() => {
174175
if (JSON.stringify(layout) !== JSON.stringify(page.draftLayout)) {
@@ -294,13 +295,6 @@ export default function PageEditor({
294295
interactives
295296
structure
296297
}
297-
theme {
298-
name
299-
colors
300-
typography
301-
interactives
302-
structure
303-
}
304298
}
305299
}
306300
`;
@@ -318,9 +312,6 @@ export default function PageEditor({
318312
if (response.site.draftTheme) {
319313
setDraftTheme(response.site.draftTheme);
320314
}
321-
if (response.site.theme) {
322-
setTheme(response.site.theme);
323-
}
324315
} catch (err: any) {
325316
toast({
326317
title: TOAST_TITLE_ERROR,
@@ -595,8 +586,6 @@ export default function PageEditor({
595586
setLayout([...moveMemberUp(layout, index)]);
596587
};
597588

598-
const saveTheme = async (theme: Theme) => {};
599-
600589
const activeSidePaneContent = (
601590
<>
602591
{leftPaneContent === "widgets" && (
@@ -618,21 +607,7 @@ export default function PageEditor({
618607
<ThemeEditor
619608
draftTheme={draftTheme}
620609
onClose={onClose}
621-
onSave={({
622-
name,
623-
colors,
624-
typography,
625-
interactives,
626-
structure,
627-
}) =>
628-
saveTheme({
629-
name,
630-
colors,
631-
typography,
632-
interactives,
633-
structure,
634-
})
635-
}
610+
onSave={(theme) => setDraftTheme(theme)}
636611
/>
637612
)}
638613
{leftPaneContent === "seo" && (
@@ -696,7 +671,9 @@ export default function PageEditor({
696671
value={page.pageId}
697672
onValueChange={(value) => {
698673
if (value !== page.pageId) {
699-
router.push(`/dashboard/page/${value}`);
674+
router.push(
675+
`/dashboard/page/${value}`,
676+
);
700677
}
701678
}}
702679
>
@@ -705,7 +682,10 @@ export default function PageEditor({
705682
</SelectTrigger>
706683
<SelectContent>
707684
{pages.map((p) => (
708-
<SelectItem key={p.pageId} value={p.pageId}>
685+
<SelectItem
686+
key={p.pageId}
687+
value={p.pageId}
688+
>
709689
{p.name}
710690
</SelectItem>
711691
))}
@@ -839,13 +819,19 @@ export default function PageEditor({
839819
<div className="flex w-full h-[calc(100vh-56px)] mt-14 gap-4 p-4 bg-muted/10">
840820
{leftPaneContent !== "none" && (
841821
<div className="w-[300px] rounded-xl border bg-background/98 backdrop-blur supports-[backdrop-filter]:bg-background/80 shadow-sm flex flex-col overflow-hidden">
842-
<PanelHeader
822+
<PanelHeader
843823
title={
844-
leftPaneContent === "widgets" ? EDIT_PAGE_ADD_WIDGET_TITLE :
845-
leftPaneContent === "editor" ? "Edit Widget" :
846-
leftPaneContent === "fonts" ? "Fonts" :
847-
leftPaneContent === "theme" ? "Theme" :
848-
leftPaneContent === "seo" ? "SEO" : ""
824+
leftPaneContent === "widgets"
825+
? EDIT_PAGE_ADD_WIDGET_TITLE
826+
: leftPaneContent === "editor"
827+
? "Edit Widget"
828+
: leftPaneContent === "fonts"
829+
? "Fonts"
830+
: leftPaneContent === "theme"
831+
? "Theme"
832+
: leftPaneContent === "seo"
833+
? "SEO"
834+
: ""
849835
}
850836
onClose={onClose}
851837
/>
@@ -879,7 +865,9 @@ export default function PageEditor({
879865
onAddWidgetBelow={onAddWidgetBelow}
880866
onMoveWidgetDown={onMoveWidgetDown}
881867
onMoveWidgetUp={onMoveWidgetUp}
882-
state={state}
868+
state={Object.assign({}, state, {
869+
theme: draftTheme,
870+
})}
883871
dispatch={dispatch}
884872
/>
885873
)}

0 commit comments

Comments
 (0)