a tool for shared writing and social publishing
1"use client";
2
3import { createNewLeaflet } from "actions/createNewLeaflet";
4import { createNewLeafletFromTemplate } from "actions/createNewLeafletFromTemplate";
5import { ActionButton } from "components/ActionBar/ActionButton";
6import { AddTiny } from "components/Icons/AddTiny";
7import { BlockCanvasPageSmall } from "components/Icons/BlockCanvasPageSmall";
8import { BlockDocPageSmall } from "components/Icons/BlockDocPageSmall";
9import { TemplateSmall } from "components/Icons/TemplateSmall";
10import { Menu, MenuItem } from "components/Layout";
11import { useIsMobile } from "src/hooks/isMobile";
12import { create } from "zustand";
13import { combine, createJSONStorage, persist } from "zustand/middleware";
14
15export const useTemplateState = create(
16 persist(
17 combine(
18 {
19 templates: [] as { id: string; name: string }[],
20 },
21 (set) => ({
22 removeTemplate: (template: { id: string }) =>
23 set((state) => {
24 return {
25 templates: state.templates.filter((t) => t.id !== template.id),
26 };
27 }),
28 addTemplate: (template: { id: string; name: string }) =>
29 set((state) => {
30 if (state.templates.find((t) => t.id === template.id)) return state;
31 return { templates: [...state.templates, template] };
32 }),
33 }),
34 ),
35 {
36 name: "home-templates",
37 storage: createJSONStorage(() => localStorage),
38 },
39 ),
40);
41export const CreateNewLeafletButton = (props: {}) => {
42 let isMobile = useIsMobile();
43 let templates = useTemplateState((s) => s.templates);
44 let openNewLeaflet = (id: string) => {
45 if (isMobile) {
46 window.location.href = `/${id}?focusFirstBlock`;
47 } else {
48 window.open(`/${id}?focusFirstBlock`, "_blank");
49 }
50 };
51 return (
52 <Menu
53 asChild
54 trigger={
55 <ActionButton
56 id="new-leaflet-button"
57 primary
58 icon=<AddTiny className="m-1 shrink-0" />
59 label="New"
60 />
61 }
62 >
63 <MenuItem
64 onSelect={async () => {
65 let id = await createNewLeaflet({
66 pageType: "doc",
67 redirectUser: false,
68 });
69 openNewLeaflet(id);
70 }}
71 >
72 <BlockDocPageSmall />{" "}
73 <div className="flex flex-col">
74 <div>New Doc</div>
75 <div className="text-tertiary text-sm font-normal">
76 A good ol' text document
77 </div>
78 </div>
79 </MenuItem>
80 <MenuItem
81 onSelect={async () => {
82 let id = await createNewLeaflet({
83 pageType: "canvas",
84 redirectUser: false,
85 });
86 openNewLeaflet(id);
87 }}
88 >
89 <BlockCanvasPageSmall />
90 <div className="flex flex-col">
91 New Canvas
92 <div className="text-tertiary text-sm font-normal">
93 A digital whiteboard
94 </div>
95 </div>
96 </MenuItem>
97 {templates.length > 0 && (
98 <hr className="border-border-light mx-2 mb-0.5" />
99 )}
100 {templates.map((t) => {
101 return (
102 <MenuItem
103 key={t.id}
104 onSelect={async () => {
105 let id = await createNewLeafletFromTemplate(t.id, false);
106 if (!id.error) openNewLeaflet(id.id);
107 }}
108 >
109 <TemplateSmall />
110 New {t.name}
111 </MenuItem>
112 );
113 })}
114 </Menu>
115 );
116};