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 />
70 </div>
71 <AccentPickers
72 entityID={props.entityID}
73 openPicker={openPicker}
74 setOpenPicker={(pickers) => setOpenPicker(pickers)}
75 />
76 <SamplePage entityID={props.entityID} />
77 </div>
78 </>
79 );
80};
81
82const ResetButton = (props: { entityID: string }) => {
83 let { rep } = useReplicache();
84
85 return (
86 <ButtonPrimary
87 compact
88 onClick={() => {
89 if (!rep) return;
90 rep.mutate.retractAttribute({
91 entity: props.entityID,
92 attribute: [
93 "theme/primary",
94 "theme/card-background",
95 "theme/accent-background",
96 "theme/accent-text",
97 "theme/card-background-image",
98 "theme/card-background-image-repeat",
99 "theme/card-background-image-opacity",
100 "theme/card-border-hidden",
101 "canvas/background-pattern",
102 ],
103 });
104 }}
105 >
106 reset
107 </ButtonPrimary>
108 );
109};
110
111const SamplePage = (props: { entityID: string }) => {
112 let { rootEntity } = useReplicache();
113
114 let rootBackgroundImage = useEntity(
115 rootEntity,
116 "theme/card-background-image",
117 );
118 let rootBackgroundRepeat = useEntity(
119 rootEntity,
120 "theme/card-background-image-repeat",
121 );
122 let rootBackgroundOpacity = useEntity(
123 rootEntity,
124 "theme/card-background-image-opacity",
125 );
126
127 let pageBackgroundImage =
128 useEntity(props.entityID, "theme/card-background-image") ||
129 rootBackgroundImage;
130 let pageBackgroundImageRepeat =
131 useEntity(props.entityID, "theme/card-background-image-repeat") ||
132 rootBackgroundRepeat;
133 let pageBackgroundImageOpacity =
134 useEntity(props.entityID, "theme/card-background-image-opacity") ||
135 rootBackgroundOpacity;
136
137 let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden");
138 let entityPageBorderHidden = useEntity(
139 props.entityID,
140 "theme/card-border-hidden",
141 );
142 let pageBorderHidden = (entityPageBorderHidden || rootPageBorderHidden)?.data
143 .value;
144
145 return (
146 <div
147 className={
148 pageBorderHidden
149 ? "relative py-2 px-0 border border-transparent"
150 : `relative rounded-t-lg p-2 shadow-md text-primary border border-border border-b-transparent`
151 }
152 style={
153 pageBorderHidden
154 ? undefined
155 : {
156 backgroundColor: "rgba(var(--bg-page), var(--bg-page-alpha))",
157 }
158 }
159 >
160 <div
161 className="background absolute top-0 right-0 bottom-0 left-0 z-0 rounded-t-lg"
162 style={
163 pageBorderHidden
164 ? undefined
165 : {
166 backgroundImage: pageBackgroundImage
167 ? `url(${pageBackgroundImage.data.src})`
168 : undefined,
169
170 backgroundRepeat: pageBackgroundImageRepeat
171 ? "repeat"
172 : "no-repeat",
173 opacity: pageBackgroundImageOpacity?.data.value || 1,
174 backgroundSize: !pageBackgroundImageRepeat?.data.value
175 ? "cover"
176 : `calc(${pageBackgroundImageRepeat.data.value}px / 2 )`,
177 }
178 }
179 />
180 <div className="relative">
181 <p className="font-bold">Theme Each Page!</p>
182 <small className="">
183 OMG! You can theme each page individually in{" "}
184 <span className="font-bold text-accent-contrast">Leaflet</span>!
185 <br /> Buttons and sections appear like:
186 </small>
187 <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">
188 Happy Theming!
189 <div className="bg-accent-1 text-accent-2 py-0.5 px-2 w-fit text-center text-sm font-bold rounded-md">
190 Button
191 </div>
192 </div>
193 </div>
194 </div>
195 );
196};