a tool for shared writing and social publishing
1import { useEntity, useReplicache } from "src/replicache";
2import { useEntitySetContext } from "components/EntitySetProvider";
3import { pickers, SectionArrow, setColorAttribute } from "./ThemeSetter";
4
5import {
6 SubpageBackgroundPicker,
7 PageThemePickers,
8} from "./Pickers/PageThemePickers";
9import { useMemo, useState } from "react";
10import { theme } from "tailwind.config";
11import { ButtonPrimary } from "components/Buttons";
12import { PaintSmall } from "components/Icons/PaintSmall";
13import { AccentPickers } from "./Pickers/AccentPickers";
14import Page from "twilio/lib/base/Page";
15
16export const PageThemeSetter = (props: { entityID: string }) => {
17 let { rootEntity } = useReplicache();
18 let permission = useEntitySetContext().permissions.write;
19 let [openPicker, setOpenPicker] = useState<pickers>("null");
20
21 let leafletBGImage = useEntity(rootEntity, "theme/background-image");
22 let leafletBGRepeat = useEntity(rootEntity, "theme/background-image-repeat");
23
24 if (!permission) return null;
25
26 let { rep } = useReplicache();
27 let set = useMemo(() => {
28 return setColorAttribute(rep, props.entityID);
29 }, [rep, props.entityID]);
30
31 return (
32 <>
33 <div className="pageThemeSetter flex flex-row gap-2 px-3 py-1 z-10">
34 <div className="gap-2 flex font-bold ">
35 <PaintSmall /> Theme Page
36 </div>
37 <ResetButton entityID={props.entityID} />
38 </div>
39
40 <div
41 className="pageThemeSetterContent bg-bg-leaflet w-80 p-3 pb-0 flex flex-col gap-4 rounded-md -mb-1"
42 style={{
43 backgroundImage: leafletBGImage
44 ? `url(${leafletBGImage.data.src})`
45 : undefined,
46 backgroundPosition: "center",
47 backgroundRepeat: leafletBGRepeat ? "repeat" : "no-repeat",
48 backgroundSize: !leafletBGRepeat
49 ? "cover"
50 : `calc(${leafletBGRepeat.data.value}px / 2 )`,
51 }}
52 >
53 <div
54 className="pageThemeBG flex flex-col gap-2 h-full text-primary bg-bg-leaflet p-2 rounded-md border border-primary shadow-[0_0_0_1px_rgb(var(--bg-page))]"
55 style={{ backgroundColor: "rgba(var(--bg-page), 0.6)" }}
56 >
57 <SubpageBackgroundPicker
58 entityID={props.entityID}
59 openPicker={openPicker}
60 setOpenPicker={setOpenPicker}
61 />
62 </div>
63
64 <div className="flex flex-col z-10">
65 <PageThemePickers
66 entityID={props.entityID}
67 openPicker={openPicker}
68 setOpenPicker={(pickers) => setOpenPicker(pickers)}
69 hideFonts
70 />
71 </div>
72 <AccentPickers
73 entityID={props.entityID}
74 openPicker={openPicker}
75 setOpenPicker={(pickers) => setOpenPicker(pickers)}
76 />
77 <SamplePage entityID={props.entityID} />
78 </div>
79 </>
80 );
81};
82
83const ResetButton = (props: { entityID: string }) => {
84 let { rep } = useReplicache();
85
86 return (
87 <ButtonPrimary
88 compact
89 onClick={() => {
90 if (!rep) return;
91 rep.mutate.retractAttribute({
92 entity: props.entityID,
93 attribute: [
94 "theme/primary",
95 "theme/card-background",
96 "theme/accent-background",
97 "theme/accent-text",
98 "theme/card-background-image",
99 "theme/card-background-image-repeat",
100 "theme/card-background-image-opacity",
101 "theme/card-border-hidden",
102 "canvas/background-pattern",
103 ],
104 });
105 }}
106 >
107 reset
108 </ButtonPrimary>
109 );
110};
111
112const SamplePage = (props: { entityID: string }) => {
113 let { rootEntity } = useReplicache();
114
115 let rootBackgroundImage = useEntity(
116 rootEntity,
117 "theme/card-background-image",
118 );
119 let rootBackgroundRepeat = useEntity(
120 rootEntity,
121 "theme/card-background-image-repeat",
122 );
123 let rootBackgroundOpacity = useEntity(
124 rootEntity,
125 "theme/card-background-image-opacity",
126 );
127
128 let pageBackgroundImage =
129 useEntity(props.entityID, "theme/card-background-image") ||
130 rootBackgroundImage;
131 let pageBackgroundImageRepeat =
132 useEntity(props.entityID, "theme/card-background-image-repeat") ||
133 rootBackgroundRepeat;
134 let pageBackgroundImageOpacity =
135 useEntity(props.entityID, "theme/card-background-image-opacity") ||
136 rootBackgroundOpacity;
137
138 let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden");
139 let entityPageBorderHidden = useEntity(
140 props.entityID,
141 "theme/card-border-hidden",
142 );
143 let pageBorderHidden = (entityPageBorderHidden || rootPageBorderHidden)?.data
144 .value;
145
146 return (
147 <div
148 className={
149 pageBorderHidden
150 ? "relative py-2 px-0 border border-transparent"
151 : `relative rounded-t-lg p-2 shadow-md text-primary border border-border border-b-transparent`
152 }
153 style={
154 pageBorderHidden
155 ? undefined
156 : {
157 backgroundColor: "rgba(var(--bg-page), var(--bg-page-alpha))",
158 }
159 }
160 >
161 <div
162 className="background absolute top-0 right-0 bottom-0 left-0 z-0 rounded-t-lg"
163 style={
164 pageBorderHidden
165 ? undefined
166 : {
167 backgroundImage: pageBackgroundImage
168 ? `url(${pageBackgroundImage.data.src})`
169 : undefined,
170
171 backgroundRepeat: pageBackgroundImageRepeat
172 ? "repeat"
173 : "no-repeat",
174 opacity: pageBackgroundImageOpacity?.data.value || 1,
175 backgroundSize: !pageBackgroundImageRepeat?.data.value
176 ? "cover"
177 : `calc(${pageBackgroundImageRepeat.data.value}px / 2 )`,
178 }
179 }
180 />
181 <div className="relative">
182 <p className="font-bold">Theme Each Page!</p>
183 <small className="">
184 OMG! You can theme each page individually in{" "}
185 <span className="font-bold text-accent-contrast">Leaflet</span>!
186 <br /> Buttons and sections appear like:
187 </small>
188 <div className="p-2 mt-2 border border-border bg-bg-page rounded-md text-sm flex justify-between items-center font-bold text-secondary">
189 Happy Theming!
190 <div className="bg-accent-1 text-accent-2 py-0.5 px-2 w-fit text-center text-sm font-bold rounded-md">
191 Button
192 </div>
193 </div>
194 </div>
195 </div>
196 );
197};