2023-12-23 09:16:54 +08:00
|
|
|
import { useEffect } from "react";
|
2023-11-30 15:18:41 +08:00
|
|
|
import { Link } from "react-router-dom";
|
2024-01-29 17:39:06 +08:00
|
|
|
import { Tabs, TabPane, Banner, Steps } from "@douyinfe/semi-ui";
|
2023-12-23 09:16:54 +08:00
|
|
|
import { IconDeleteStroked } from "@douyinfe/semi-icons";
|
2023-12-11 09:00:25 +08:00
|
|
|
import { db } from "../data/db";
|
2023-12-23 09:16:54 +08:00
|
|
|
import { useLiveQuery } from "dexie-react-hooks";
|
2024-04-05 08:02:29 +08:00
|
|
|
import Thumbnail from "../components/Thumbnail";
|
2024-04-05 10:12:50 +08:00
|
|
|
import logo_light from "../assets/logo_light_160.png";
|
|
|
|
import template_screenshot from "../assets/template_screenshot.png";
|
2023-12-11 09:00:25 +08:00
|
|
|
|
2023-11-30 15:18:41 +08:00
|
|
|
export default function Templates() {
|
2023-12-23 09:16:54 +08:00
|
|
|
const defaultTemplates = useLiveQuery(() =>
|
|
|
|
db.templates.where({ custom: 0 }).toArray()
|
|
|
|
);
|
|
|
|
const customTemplates = useLiveQuery(() =>
|
|
|
|
db.templates.where({ custom: 1 }).toArray()
|
|
|
|
);
|
|
|
|
|
|
|
|
const deleteTemplate = async (id) => {
|
|
|
|
await db.templates.delete(id);
|
|
|
|
};
|
2023-12-11 09:00:25 +08:00
|
|
|
|
2023-12-24 09:06:49 +08:00
|
|
|
const editTemplate = (id) => {
|
2023-12-25 05:26:14 +08:00
|
|
|
const newWindow = window.open("/editor", "_blank");
|
|
|
|
newWindow.name = "t " + id;
|
2023-12-24 09:06:49 +08:00
|
|
|
};
|
|
|
|
|
2023-12-26 22:40:47 +08:00
|
|
|
const forkTemplate = (id) => {
|
|
|
|
const newWindow = window.open("/editor", "_blank");
|
|
|
|
newWindow.name = "lt " + id;
|
|
|
|
};
|
|
|
|
|
2023-12-11 09:00:25 +08:00
|
|
|
useEffect(() => {
|
|
|
|
document.title = "Templates | drawDB";
|
|
|
|
}, []);
|
|
|
|
|
2023-11-30 15:18:41 +08:00
|
|
|
return (
|
|
|
|
<div>
|
2023-12-12 07:14:29 +08:00
|
|
|
<div className="min-h-screen">
|
|
|
|
<div className="sm:py-3 py-5 px-12 xl:px-20 sm:px-6 flex justify-between items-center select-none">
|
|
|
|
<div className="flex items-center justify-start">
|
|
|
|
<Link to="/">
|
|
|
|
<img
|
|
|
|
src={logo_light}
|
|
|
|
alt="logo"
|
2024-02-28 22:53:59 +08:00
|
|
|
className="me-2 sm:h-[28px] md:h-[46px] h-[48px]"
|
2023-12-12 07:14:29 +08:00
|
|
|
/>
|
|
|
|
</Link>
|
|
|
|
<div className="ms-4 sm:text-sm xl:text-xl text-xl font-semibold">
|
|
|
|
Templates
|
|
|
|
</div>
|
2023-11-30 15:18:41 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-12-12 07:14:29 +08:00
|
|
|
<hr className="border-zinc-300" />
|
|
|
|
<div className="xl:px-20 sm:px-6 px-12 py-6">
|
|
|
|
<div className="w-full md:w-[75%] xl:w-[50%] mb-2">
|
|
|
|
<div className="text-2xl sm:text-lg font-semibold mb-2 text-neutral-800">
|
|
|
|
Database schema templates
|
|
|
|
</div>
|
|
|
|
<div className="text-sm text-neutral-700">
|
|
|
|
A compilation of database entity relationship diagrams to give you
|
2023-12-16 11:39:13 +08:00
|
|
|
a quick start or inspire your application's architecture.
|
2023-12-12 07:14:29 +08:00
|
|
|
</div>
|
2023-12-11 09:00:25 +08:00
|
|
|
</div>
|
2023-12-12 07:14:29 +08:00
|
|
|
<Tabs>
|
|
|
|
<TabPane
|
|
|
|
tab={<span className="mx-2">Default templates</span>}
|
|
|
|
itemKey="1"
|
|
|
|
>
|
2023-12-23 09:16:54 +08:00
|
|
|
<div className="grid xl:grid-cols-3 grid-cols-2 sm:grid-cols-1 gap-10 my-6">
|
2023-12-19 10:36:10 +08:00
|
|
|
{defaultTemplates?.map((t, i) => (
|
2023-12-12 07:14:29 +08:00
|
|
|
<div
|
|
|
|
key={i}
|
|
|
|
className="bg-gray-100 hover:translate-y-[-6px] transition-all duration-300 border rounded-md"
|
|
|
|
>
|
2024-04-05 08:02:29 +08:00
|
|
|
<div className="h-48">
|
|
|
|
<Thumbnail
|
|
|
|
diagram={t}
|
|
|
|
i={"1" + i}
|
|
|
|
zoom={0.3}
|
|
|
|
theme="light"
|
|
|
|
/>
|
|
|
|
</div>
|
2023-12-12 07:14:29 +08:00
|
|
|
<div className="px-4 py-3">
|
|
|
|
<div className="flex justify-between">
|
|
|
|
<div className="text-lg font-bold text-zinc-700">
|
|
|
|
{t.title}
|
|
|
|
</div>
|
2023-12-26 22:40:47 +08:00
|
|
|
<button
|
|
|
|
className="border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
|
|
|
|
onClick={() => forkTemplate(t.id)}
|
|
|
|
>
|
2023-12-12 07:14:29 +08:00
|
|
|
<i className="fa-solid fa-code-fork"></i>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div>{t.description}</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</TabPane>
|
|
|
|
<TabPane
|
|
|
|
tab={<span className="mx-2">Your templates</span>}
|
|
|
|
itemKey="2"
|
|
|
|
>
|
2024-03-11 08:45:44 +08:00
|
|
|
{customTemplates?.length > 0 ? (
|
|
|
|
<div className="grid xl:grid-cols-3 grid-cols-2 sm:grid-cols-1 gap-8 my-6">
|
|
|
|
{customTemplates?.map((c, i) => (
|
|
|
|
<div
|
|
|
|
key={i}
|
|
|
|
className="bg-gray-100 hover:translate-y-[-6px] transition-all duration-300 border rounded-md"
|
|
|
|
>
|
|
|
|
<Thumbnail diagram={c} i={"2" + i} />
|
|
|
|
<div className="px-4 py-3 w-full">
|
|
|
|
<div className="flex justify-between">
|
|
|
|
<div className="text-lg font-bold text-zinc-700">
|
|
|
|
{c.title}
|
2024-01-29 17:39:06 +08:00
|
|
|
</div>
|
2024-03-11 08:45:44 +08:00
|
|
|
<div>
|
2024-01-29 17:39:06 +08:00
|
|
|
<button
|
2024-03-11 08:45:44 +08:00
|
|
|
className="me-1 border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
|
|
|
|
onClick={() => forkTemplate(c.id)}
|
2024-01-29 17:39:06 +08:00
|
|
|
>
|
2024-03-11 08:45:44 +08:00
|
|
|
<i className="fa-solid fa-code-fork"></i>
|
2024-01-29 17:39:06 +08:00
|
|
|
</button>
|
|
|
|
</div>
|
2023-12-23 09:16:54 +08:00
|
|
|
</div>
|
2024-03-11 08:45:44 +08:00
|
|
|
<div className="flex justify-around mt-2">
|
|
|
|
<button
|
|
|
|
className="w-full text-center flex justify-center items-center border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-blue-500"
|
|
|
|
onClick={() => editTemplate(c.id)}
|
|
|
|
>
|
|
|
|
<i className="bi bi-pencil-fill"></i>
|
|
|
|
<div className="ms-1.5 font-semibold">Edit</div>
|
|
|
|
</button>
|
|
|
|
<div className="border-l border-gray-300 mx-2" />
|
|
|
|
<button
|
|
|
|
className="w-full text-center flex justify-center items-center border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-red-500"
|
|
|
|
onClick={() => deleteTemplate(c.id)}
|
|
|
|
>
|
|
|
|
<IconDeleteStroked />
|
|
|
|
<div className="ms-1.5 font-semibold">Delete</div>
|
|
|
|
</button>
|
|
|
|
</div>
|
2023-12-23 09:16:54 +08:00
|
|
|
</div>
|
2024-03-11 08:45:44 +08:00
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
) : (
|
|
|
|
<div className="py-5">
|
|
|
|
<Banner
|
|
|
|
fullMode={false}
|
|
|
|
type="info"
|
|
|
|
bordered
|
|
|
|
icon={null}
|
|
|
|
closeIcon={null}
|
|
|
|
description={<div>You have no custom templates saved.</div>}
|
|
|
|
/>
|
|
|
|
<div className="grid grid-cols-5 sm:grid-cols-1 gap-4 place-content-center my-4">
|
|
|
|
<img
|
|
|
|
src={template_screenshot}
|
|
|
|
className="border col-span-3 sm:cols-span-1 rounded"
|
2024-01-29 17:39:06 +08:00
|
|
|
/>
|
2024-03-11 08:45:44 +08:00
|
|
|
<div className="col-span-2 sm:cols-span-1">
|
|
|
|
<div className="text-xl font-bold my-4">
|
|
|
|
How to save a template
|
2023-12-19 10:36:10 +08:00
|
|
|
</div>
|
2024-03-11 08:45:44 +08:00
|
|
|
<Steps direction="vertical" style={{ margin: "12px" }}>
|
|
|
|
<Steps.Step
|
|
|
|
title="Build a diagram"
|
|
|
|
description="Build the template in the editor"
|
|
|
|
/>
|
|
|
|
<Steps.Step
|
|
|
|
title="Save as template"
|
|
|
|
description="Editor > File > Save as template"
|
|
|
|
/>
|
|
|
|
<Steps.Step
|
|
|
|
title="Load a template"
|
|
|
|
description="Fork a template to build on"
|
|
|
|
/>
|
|
|
|
</Steps>
|
2023-12-19 10:36:10 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
2024-03-11 08:45:44 +08:00
|
|
|
</div>
|
|
|
|
)}
|
2023-12-12 07:14:29 +08:00
|
|
|
</TabPane>
|
|
|
|
</Tabs>
|
2023-12-11 09:00:25 +08:00
|
|
|
</div>
|
2023-12-12 07:14:29 +08:00
|
|
|
</div>
|
|
|
|
<hr className="border-zinc-300 my-1" />
|
|
|
|
<div className="text-center text-sm py-3">
|
|
|
|
© 2024 <strong>drawDB</strong> - All right reserved.
|
2023-12-11 09:00:25 +08:00
|
|
|
</div>
|
2023-11-30 15:18:41 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|