wip fix registration
This commit is contained in:
parent
4070f54e9b
commit
8d94e2779a
|
|
@ -6,5 +6,7 @@ export const _ = {
|
|||
async api() {
|
||||
const { res } = apiContext(this);
|
||||
res.setHeader("set-cookie", `${session.cookieKey}=X`);
|
||||
|
||||
return res;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
import { apiContext } from "service-srv";
|
||||
import argon from "@node-rs/argon2";
|
||||
|
||||
export const _ = {
|
||||
url: "/_register",
|
||||
async api(p: { username: string; password: string; email: string }) {
|
||||
const { req, res } = apiContext(this);
|
||||
|
||||
const user = await _db.user.findFirst({
|
||||
where: {
|
||||
username: p.username,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
const pwd = await argon.hash(p.password);
|
||||
const user = await _db.user.create({
|
||||
data: {
|
||||
username: p.username,
|
||||
email: p.email,
|
||||
password: pwd,
|
||||
phone: "",
|
||||
},
|
||||
});
|
||||
return {
|
||||
status: "success",
|
||||
user: {
|
||||
id: user.id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "failed",
|
||||
reason: `\
|
||||
Register failed!
|
||||
Username already exists, please choose another username.`,
|
||||
};
|
||||
},
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,14 +1,12 @@
|
|||
import { useEffect } from "react";
|
||||
import { page, useGlobal } from "web-utils";
|
||||
import { EDGlobal } from "../../nova/ed/logic/ed-global";
|
||||
import { edInitSync } from "../../nova/ed/logic/ed-sync";
|
||||
import { Loading } from "../../utils/ui/loading";
|
||||
import { isLocalhost } from "../../utils/ui/is-localhost";
|
||||
import { Loading } from "../../utils/ui/loading";
|
||||
|
||||
export default page({
|
||||
url: "**",
|
||||
component: ({}) => {
|
||||
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("prasi-session")) {
|
||||
|
|
@ -16,7 +14,7 @@ export default page({
|
|||
location.pathname === "/ed" ||
|
||||
location.pathname.startsWith("/ed/")
|
||||
) {
|
||||
edInitSync(p);
|
||||
location.href = "/ed/_/_";
|
||||
} else if (location.pathname.startsWith("/editor")) {
|
||||
const arr = location.pathname.split("/");
|
||||
if (arr.length <= 2) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Loading } from "../../../utils/ui/loading";
|
|||
export default page({
|
||||
url: "/logout",
|
||||
component: ({}) => {
|
||||
localStorage.clear();
|
||||
_api.logout().then(() => {
|
||||
location.href = "/login";
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export default page({
|
|||
form.render();
|
||||
alert(s.reason);
|
||||
} else {
|
||||
await _api.login(form.username, form.password);
|
||||
alert("Registration success!");
|
||||
navigate("/ed");
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
import { page, useGlobal } from "web-utils";
|
||||
import { EdBase } from "../../nova/ed/ed-base";
|
||||
import { EDGlobal } from "../../nova/ed/logic/ed-global";
|
||||
import { edInitSync } from "../../nova/ed/logic/ed-sync";
|
||||
import { Loading } from "../../utils/ui/loading";
|
||||
import { validate } from "uuid";
|
||||
import init from "wasm-gzip";
|
||||
import { page, useGlobal, useLocal } from "web-utils";
|
||||
import { EdBase } from "../../nova/ed/ed-base";
|
||||
import { EDGlobal, PG } from "../../nova/ed/logic/ed-global";
|
||||
import { edInitSync, loadSession } from "../../nova/ed/logic/ed-sync";
|
||||
import { EdFormSite } from "../../nova/ed/panel/popup/site/site-form";
|
||||
import { Loading } from "../../utils/ui/loading";
|
||||
|
||||
export default page({
|
||||
url: "/ed/:site_id/:page_id",
|
||||
component: ({}) => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
const local = useLocal({
|
||||
new_site: false,
|
||||
});
|
||||
|
||||
const w = window as any;
|
||||
if (!w.Y) {
|
||||
|
|
@ -23,10 +28,174 @@ export default page({
|
|||
|
||||
w.isEditor = true;
|
||||
|
||||
if (!edInitSync(p) && !p.sync) {
|
||||
return <Loading note="connecting-ws" />;
|
||||
if (p.status === "no-site") {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center">
|
||||
{local.new_site ? (
|
||||
<EdFormSite
|
||||
group_id=""
|
||||
site={{}}
|
||||
onSave={(data) => {
|
||||
if (data) {
|
||||
location.href = `/ed/${data.id}/_`;
|
||||
}
|
||||
}}
|
||||
onClose={() => {}}
|
||||
header={
|
||||
<div className="border-b border-blue-500 text-xl">
|
||||
Create New Site
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex flex-col p-10 rounded-lg border shadow-2xl">
|
||||
<div className="text-3xl">Welcome to Prasi</div>
|
||||
<div className="">
|
||||
You are logged in!
|
||||
<br />
|
||||
<br /> Now ask someone to invite to their site.
|
||||
<br /> Or you can{" "}
|
||||
<span
|
||||
className="underline text-blue-500 cursor-pointer"
|
||||
onClick={() => {
|
||||
local.new_site = true;
|
||||
local.render();
|
||||
}}
|
||||
>
|
||||
create your own site
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
Change account?{" "}
|
||||
<a
|
||||
href="/logout"
|
||||
className="underline text-blue-500 cursor-pointer"
|
||||
>
|
||||
Logout here
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (validate(params.page_id) && validate(params.site_id)) {
|
||||
if (!edInitSync(p) && !p.sync) {
|
||||
return <Loading note="connecting-ws" />;
|
||||
}
|
||||
} else {
|
||||
navSitePage(p);
|
||||
return <Loading note="finding-page" />;
|
||||
}
|
||||
|
||||
return <EdBase />;
|
||||
},
|
||||
});
|
||||
|
||||
const navSitePage = async (p: PG) => {
|
||||
loadSession(p);
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: validate(params.site_id)
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
contains: "root",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
orderBy: {
|
||||
site: {
|
||||
name: "asc",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (e && e.id && e.id_site) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
else {
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: validate(params.site_id)
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
contains: "home",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
});
|
||||
|
||||
if (e && e.id && e.id_site) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
else {
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: validate(params.site_id)
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
});
|
||||
if (e) {
|
||||
if (e.id && e.id_site) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
else {
|
||||
p.status = "no-site";
|
||||
p.render();
|
||||
}
|
||||
} else {
|
||||
if (validate(params.site_id)) {
|
||||
const page = await _db.page.create({
|
||||
data: {
|
||||
content_tree: {
|
||||
childs: [],
|
||||
id: "root",
|
||||
type: "root",
|
||||
},
|
||||
name: "home",
|
||||
url: "/",
|
||||
id_site: params.site_id,
|
||||
},
|
||||
});
|
||||
location.href = `/ed/${params.site_id}/${page.id}`;
|
||||
return;
|
||||
} else {
|
||||
p.status = "no-site";
|
||||
p.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,7 +39,20 @@ export const EdLeft = () => {
|
|||
"h-[35px] border-b flex p-1 items-stretch text-[12px] justify-between"
|
||||
)}
|
||||
>
|
||||
<EdSitePicker />
|
||||
<div className="flex items-stretch">
|
||||
<EdSitePicker />
|
||||
<div
|
||||
className="flex items-center ml-2 text-[12px] cursor-pointer"
|
||||
onClick={() => {
|
||||
if (confirm("Logout ?")) {
|
||||
location.href = "/logout";
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div>Logout</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-stretch space-x-1 pl-2">
|
||||
<EdSiteJS />
|
||||
<EdApi />
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ export const EDGlobal = {
|
|||
| "reload"
|
||||
| "site-not-found"
|
||||
| "page-not-found"
|
||||
| "ready",
|
||||
| "ready"
|
||||
| "no-site",
|
||||
preview: {
|
||||
url_cache: new Set<string>(),
|
||||
route_cache: createRouter<{ url: string; id: string }>(),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const page = {
|
|||
route: null as null | RadixRouter<{ id: string; url: string }>,
|
||||
};
|
||||
|
||||
export const edInitSync = (p: PG) => {
|
||||
export const loadSession = (p: PG) => {
|
||||
const session = JSON.parse(
|
||||
localStorage.getItem("prasi-session") || "null"
|
||||
) as { data: { user: { id: string; username: string } } };
|
||||
|
|
@ -35,6 +35,10 @@ export const edInitSync = (p: PG) => {
|
|||
p.user.username = "anonymous";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const edInitSync = (p: PG) => {
|
||||
loadSession(p);
|
||||
if (location.pathname.startsWith("/vi/")) {
|
||||
if (page.list.length === 0) {
|
||||
_db.page
|
||||
|
|
@ -81,89 +85,6 @@ export const edInitSync = (p: PG) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (!params.page_id) {
|
||||
if (location.pathname.startsWith("/ed")) {
|
||||
(async () => {
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: params.site_id
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
contains: "root",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
orderBy: {
|
||||
site: {
|
||||
name: "asc",
|
||||
},
|
||||
},
|
||||
});
|
||||
if (e) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
else {
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: params.site_id
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
contains: "home",
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
});
|
||||
|
||||
if (e) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
else {
|
||||
const e = await _db.page.findFirst({
|
||||
where: {
|
||||
is_deleted: false,
|
||||
is_default_layout: false,
|
||||
site: params.site_id
|
||||
? { id: params.site_id }
|
||||
: {
|
||||
org: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: { id: true, id_site: true },
|
||||
});
|
||||
if (e) location.href = `/ed/${e.id_site}/${e.id}`;
|
||||
}
|
||||
}
|
||||
})();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.sync) {
|
||||
if (p.site.id === "--loading--") return false;
|
||||
if (params.site_id !== p.site.id) {
|
||||
|
|
@ -199,6 +120,10 @@ export const edInitSync = (p: PG) => {
|
|||
select: { id: true },
|
||||
})
|
||||
.then((e) => {
|
||||
if (params.site_id === "_") {
|
||||
alert("asdsa");
|
||||
return;
|
||||
}
|
||||
if (e) location.href = `/ed/${params.site_id}/${e.id}`;
|
||||
});
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
iconNewTab,
|
||||
iconScrollOff,
|
||||
iconScrollOn,
|
||||
iconUpload
|
||||
iconUpload,
|
||||
} from "./icons";
|
||||
|
||||
export const code = {
|
||||
|
|
@ -290,46 +290,21 @@ const CodeBody = () => {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{code_mode === "vsc" ? (
|
||||
<div className="flex flex-1 relative">
|
||||
{!p.ui.popup.code.open ? (
|
||||
<Loading backdrop={false} />
|
||||
) : (
|
||||
<>
|
||||
<iframe
|
||||
className="flex flex-1 absolute inset-0 w-full h-full z-10"
|
||||
src={`${vscode_url}folder=/site/${p.site.id}/site/src`}
|
||||
></iframe>
|
||||
<div className="flex flex-1 absolute inset-0 z-0 items-center justify-center">
|
||||
Loading VSCode...
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col flex-1 relative items-center justify-center space-y-2">
|
||||
<div className="text-xs">VSCode is turned off</div>
|
||||
<div
|
||||
className="flex items-center p-2 cursor-pointer text-xs font-mono space-x-1 bg-green-700 text-white hover:opacity-40 transition-all"
|
||||
onClick={async () => {
|
||||
if (
|
||||
confirm(
|
||||
"Are you sure want to turn on VSCode?\nThis will disable old npm module (you can enable it again later)."
|
||||
)
|
||||
) {
|
||||
localStorage.vsc_opened = "yes";
|
||||
await _db.site.update({
|
||||
where: { id: p.site.id },
|
||||
data: { code_mode: "vsc" },
|
||||
});
|
||||
location.reload();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div>Turn on VSCode</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-1 relative">
|
||||
{!p.ui.popup.code.open ? (
|
||||
<Loading backdrop={false} />
|
||||
) : (
|
||||
<>
|
||||
<iframe
|
||||
className="flex flex-1 absolute inset-0 w-full h-full z-10"
|
||||
src={`${vscode_url}folder=/site/${p.site.id}/site/src`}
|
||||
></iframe>
|
||||
<div className="flex flex-1 absolute inset-0 z-0 items-center justify-center">
|
||||
Loading VSCode...
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{(local.namePicker || local.codeAssign) && (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { site } from "dbgen";
|
||||
import { FC } from "react";
|
||||
import { FC, ReactNode } from "react";
|
||||
import { useGlobal, useLocal } from "web-utils";
|
||||
import { EDGlobal } from "../../../logic/ed-global";
|
||||
import { formStyle } from "../../../../../utils/ui/form.style";
|
||||
|
|
@ -8,14 +8,16 @@ import { Input } from "../../../../../utils/ui/form/input";
|
|||
export const EdFormSite: FC<{
|
||||
site: Partial<site>;
|
||||
onClose: () => void;
|
||||
onSave: () => void;
|
||||
onSave: (data: null | site) => void;
|
||||
group_id: string;
|
||||
}> = ({ site, onClose, onSave, group_id }) => {
|
||||
header?: ReactNode;
|
||||
}> = ({ site, onClose, onSave, group_id, header }) => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
const local = useLocal({
|
||||
init: false,
|
||||
saving: false,
|
||||
preventClose: false,
|
||||
domain_follow_name: false,
|
||||
});
|
||||
const form = useLocal({} as Partial<site>);
|
||||
|
||||
|
|
@ -57,15 +59,43 @@ export const EdFormSite: FC<{
|
|||
local.saving = true;
|
||||
local.render();
|
||||
try {
|
||||
let gid = group_id;
|
||||
if (!gid) {
|
||||
let org = await _db.org.findFirst({
|
||||
where: {
|
||||
org_user: {
|
||||
some: {
|
||||
id_user: p.user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!org) {
|
||||
org = await _db.org.create({
|
||||
data: {
|
||||
name: `${p.user.username}'s sites`,
|
||||
org_user: {
|
||||
create: { id_user: p.user.id },
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
if (org) {
|
||||
gid = org.id;
|
||||
}
|
||||
}
|
||||
|
||||
let data = null as null | site;
|
||||
if (!form.id) {
|
||||
try {
|
||||
await _db.site.create({
|
||||
data = await _db.site.create({
|
||||
data: {
|
||||
name: form.name,
|
||||
favicon: "",
|
||||
domain: form.domain || "",
|
||||
id_user: p.user.id,
|
||||
id_org: group_id,
|
||||
id_org: gid,
|
||||
responsive: form.responsive,
|
||||
},
|
||||
});
|
||||
|
|
@ -73,7 +103,7 @@ export const EdFormSite: FC<{
|
|||
alert(e);
|
||||
}
|
||||
} else {
|
||||
await _db.site.update({
|
||||
data = await _db.site.update({
|
||||
data: {
|
||||
name: form.name,
|
||||
domain: form.domain,
|
||||
|
|
@ -82,7 +112,7 @@ export const EdFormSite: FC<{
|
|||
where: { id: form.id },
|
||||
});
|
||||
}
|
||||
onSave();
|
||||
onSave(data);
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
|
|
@ -94,101 +124,109 @@ export const EdFormSite: FC<{
|
|||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
className={cx(formStyle, "bg-white shadow-2xl border")}
|
||||
>
|
||||
<label>
|
||||
<span>Name</span>
|
||||
<Input
|
||||
form={form}
|
||||
autoFocus
|
||||
name={"name"}
|
||||
onBlur={() => {
|
||||
if (!form.domain) {
|
||||
form.domain = (form.name || "")
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\-_\.]/g, "");
|
||||
|
||||
form.render();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Domain</span>
|
||||
<Input
|
||||
form={form}
|
||||
name={"domain"}
|
||||
onChange={(text) => {
|
||||
return text.replace(/[^a-z0-9\-_\.]/g, "");
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Responsive</span>
|
||||
<select
|
||||
value={form.responsive}
|
||||
onChange={(e) => {
|
||||
form.responsive = e.currentTarget.value as any;
|
||||
local.render();
|
||||
}}
|
||||
>
|
||||
<option value="all">All</option>
|
||||
<option value="mobile-only">Mobile Only</option>
|
||||
<option value="desktop-only">Desktop Only</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{form.id && (
|
||||
{header}
|
||||
<div className={cx(formStyle, "bg-white shadow-2xl border")}>
|
||||
<label>
|
||||
<span>Site ID:</span>
|
||||
<Input form={form} name="id" disabled />
|
||||
</label>
|
||||
)}
|
||||
<span>Name</span>
|
||||
<Input
|
||||
form={form}
|
||||
autoFocus
|
||||
name={"name"}
|
||||
onChange={(e) => {
|
||||
if (!form.domain) {
|
||||
local.domain_follow_name = true;
|
||||
}
|
||||
|
||||
<div className="flex">
|
||||
<button type="submit" disabled={local.saving} className="flex-1">
|
||||
{local.saving ? "Saving..." : "Save"}
|
||||
</button>
|
||||
{form.id && (
|
||||
<button
|
||||
className="bg-red-600 w-[40px] flex justify-center items-center"
|
||||
onClick={async () => {
|
||||
if (confirm("Delete site cannot be undone. Are you sure ?")) {
|
||||
if (
|
||||
prompt(
|
||||
"Please type 'yes' (without quote) to confirm deletion: "
|
||||
)?.toLowerCase() === "yes"
|
||||
) {
|
||||
await _db.site.update({
|
||||
where: {
|
||||
id: site.id,
|
||||
},
|
||||
data: {
|
||||
is_deleted: true,
|
||||
},
|
||||
});
|
||||
onSave();
|
||||
}
|
||||
if (local.domain_follow_name) {
|
||||
form.domain = (form.name || "")
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\-_\.]/g, "");
|
||||
|
||||
form.render();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Domain</span>
|
||||
<Input
|
||||
form={form}
|
||||
name={"domain"}
|
||||
onChange={(text) => {
|
||||
return text.replace(/[^a-z0-9\-_\.]/g, "");
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Responsive</span>
|
||||
<select
|
||||
value={form.responsive}
|
||||
onChange={(e) => {
|
||||
form.responsive = e.currentTarget.value as any;
|
||||
local.render();
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="15"
|
||||
height="15"
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M5.5 1a.5.5 0 000 1h4a.5.5 0 000-1h-4zM3 3.5a.5.5 0 01.5-.5h8a.5.5 0 010 1H11v8a1 1 0 01-1 1H5a1 1 0 01-1-1V4h-.5a.5.5 0 01-.5-.5zM5 4h5v8H5V4z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
<option value="all">All</option>
|
||||
<option value="mobile-only">Mobile Only</option>
|
||||
<option value="desktop-only">Desktop Only</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{form.id && (
|
||||
<label>
|
||||
<span>Site ID:</span>
|
||||
<Input form={form} name="id" disabled />
|
||||
</label>
|
||||
)}
|
||||
|
||||
<div className="flex">
|
||||
<button type="submit" disabled={local.saving} className="flex-1">
|
||||
{local.saving ? "Saving..." : "Save"}
|
||||
</button>
|
||||
{form.id && (
|
||||
<button
|
||||
className="bg-red-600 w-[40px] flex justify-center items-center"
|
||||
onClick={async () => {
|
||||
if (
|
||||
confirm("Delete site cannot be undone. Are you sure ?")
|
||||
) {
|
||||
if (
|
||||
prompt(
|
||||
"Please type 'yes' (without quote) to confirm deletion: "
|
||||
)?.toLowerCase() === "yes"
|
||||
) {
|
||||
let data = await _db.site.update({
|
||||
where: {
|
||||
id: site.id,
|
||||
},
|
||||
data: {
|
||||
is_deleted: true,
|
||||
},
|
||||
});
|
||||
onSave(data);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="15"
|
||||
height="15"
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M5.5 1a.5.5 0 000 1h4a.5.5 0 000-1h-4zM3 3.5a.5.5 0 01.5-.5h8a.5.5 0 010 1H11v8a1 1 0 01-1 1H5a1 1 0 01-1-1V4h-.5a.5.5 0 01-.5-.5zM5 4h5v8H5V4z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export const base = {
|
|||
domain: string;
|
||||
api_url: string;
|
||||
code: {
|
||||
mode: "new";
|
||||
mode: "new" | "vsc";
|
||||
};
|
||||
api: any;
|
||||
db: any;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export const initBaseRoute = async (isPreviewProd: boolean) => {
|
|||
}
|
||||
|
||||
base.site = res.site;
|
||||
base.site.code = { mode: "new" };
|
||||
base.site.code = { mode: "vsc" };
|
||||
await injectSiteScript();
|
||||
|
||||
base.site.api = apiProxy(base.site.api_url);
|
||||
|
|
|
|||
Loading…
Reference in New Issue