wip fix registration
This commit is contained in:
parent
4070f54e9b
commit
8d94e2779a
|
|
@ -6,5 +6,7 @@ export const _ = {
|
||||||
async api() {
|
async api() {
|
||||||
const { res } = apiContext(this);
|
const { res } = apiContext(this);
|
||||||
res.setHeader("set-cookie", `${session.cookieKey}=X`);
|
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 { useEffect } from "react";
|
||||||
import { page, useGlobal } from "web-utils";
|
import { page, useGlobal } from "web-utils";
|
||||||
import { EDGlobal } from "../../nova/ed/logic/ed-global";
|
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 { isLocalhost } from "../../utils/ui/is-localhost";
|
||||||
|
import { Loading } from "../../utils/ui/loading";
|
||||||
|
|
||||||
export default page({
|
export default page({
|
||||||
url: "**",
|
url: "**",
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
|
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("prasi-session")) {
|
if (localStorage.getItem("prasi-session")) {
|
||||||
|
|
@ -16,7 +14,7 @@ export default page({
|
||||||
location.pathname === "/ed" ||
|
location.pathname === "/ed" ||
|
||||||
location.pathname.startsWith("/ed/")
|
location.pathname.startsWith("/ed/")
|
||||||
) {
|
) {
|
||||||
edInitSync(p);
|
location.href = "/ed/_/_";
|
||||||
} else if (location.pathname.startsWith("/editor")) {
|
} else if (location.pathname.startsWith("/editor")) {
|
||||||
const arr = location.pathname.split("/");
|
const arr = location.pathname.split("/");
|
||||||
if (arr.length <= 2) {
|
if (arr.length <= 2) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { Loading } from "../../../utils/ui/loading";
|
||||||
export default page({
|
export default page({
|
||||||
url: "/logout",
|
url: "/logout",
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
|
localStorage.clear();
|
||||||
_api.logout().then(() => {
|
_api.logout().then(() => {
|
||||||
location.href = "/login";
|
location.href = "/login";
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ export default page({
|
||||||
form.render();
|
form.render();
|
||||||
alert(s.reason);
|
alert(s.reason);
|
||||||
} else {
|
} else {
|
||||||
|
await _api.login(form.username, form.password);
|
||||||
|
alert("Registration success!");
|
||||||
navigate("/ed");
|
navigate("/ed");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
import { page, useGlobal } from "web-utils";
|
import { validate } from "uuid";
|
||||||
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 init from "wasm-gzip";
|
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({
|
export default page({
|
||||||
url: "/ed/:site_id/:page_id",
|
url: "/ed/:site_id/:page_id",
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const local = useLocal({
|
||||||
|
new_site: false,
|
||||||
|
});
|
||||||
|
|
||||||
const w = window as any;
|
const w = window as any;
|
||||||
if (!w.Y) {
|
if (!w.Y) {
|
||||||
|
|
@ -23,10 +28,174 @@ export default page({
|
||||||
|
|
||||||
w.isEditor = true;
|
w.isEditor = true;
|
||||||
|
|
||||||
if (!edInitSync(p) && !p.sync) {
|
if (p.status === "no-site") {
|
||||||
return <Loading note="connecting-ws" />;
|
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 />;
|
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"
|
"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">
|
<div className="flex items-stretch space-x-1 pl-2">
|
||||||
<EdSiteJS />
|
<EdSiteJS />
|
||||||
<EdApi />
|
<EdApi />
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,8 @@ export const EDGlobal = {
|
||||||
| "reload"
|
| "reload"
|
||||||
| "site-not-found"
|
| "site-not-found"
|
||||||
| "page-not-found"
|
| "page-not-found"
|
||||||
| "ready",
|
| "ready"
|
||||||
|
| "no-site",
|
||||||
preview: {
|
preview: {
|
||||||
url_cache: new Set<string>(),
|
url_cache: new Set<string>(),
|
||||||
route_cache: createRouter<{ url: string; id: string }>(),
|
route_cache: createRouter<{ url: string; id: string }>(),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const page = {
|
||||||
route: null as null | RadixRouter<{ id: string; url: string }>,
|
route: null as null | RadixRouter<{ id: string; url: string }>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const edInitSync = (p: PG) => {
|
export const loadSession = (p: PG) => {
|
||||||
const session = JSON.parse(
|
const session = JSON.parse(
|
||||||
localStorage.getItem("prasi-session") || "null"
|
localStorage.getItem("prasi-session") || "null"
|
||||||
) as { data: { user: { id: string; username: string } } };
|
) as { data: { user: { id: string; username: string } } };
|
||||||
|
|
@ -35,6 +35,10 @@ export const edInitSync = (p: PG) => {
|
||||||
p.user.username = "anonymous";
|
p.user.username = "anonymous";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export const edInitSync = (p: PG) => {
|
||||||
|
loadSession(p);
|
||||||
if (location.pathname.startsWith("/vi/")) {
|
if (location.pathname.startsWith("/vi/")) {
|
||||||
if (page.list.length === 0) {
|
if (page.list.length === 0) {
|
||||||
_db.page
|
_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.sync) {
|
||||||
if (p.site.id === "--loading--") return false;
|
if (p.site.id === "--loading--") return false;
|
||||||
if (params.site_id !== p.site.id) {
|
if (params.site_id !== p.site.id) {
|
||||||
|
|
@ -199,6 +120,10 @@ export const edInitSync = (p: PG) => {
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
})
|
})
|
||||||
.then((e) => {
|
.then((e) => {
|
||||||
|
if (params.site_id === "_") {
|
||||||
|
alert("asdsa");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (e) location.href = `/ed/${params.site_id}/${e.id}`;
|
if (e) location.href = `/ed/${params.site_id}/${e.id}`;
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
||||||
iconNewTab,
|
iconNewTab,
|
||||||
iconScrollOff,
|
iconScrollOff,
|
||||||
iconScrollOn,
|
iconScrollOn,
|
||||||
iconUpload
|
iconUpload,
|
||||||
} from "./icons";
|
} from "./icons";
|
||||||
|
|
||||||
export const code = {
|
export const code = {
|
||||||
|
|
@ -290,46 +290,21 @@ const CodeBody = () => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{code_mode === "vsc" ? (
|
<div className="flex flex-1 relative">
|
||||||
<div className="flex flex-1 relative">
|
{!p.ui.popup.code.open ? (
|
||||||
{!p.ui.popup.code.open ? (
|
<Loading backdrop={false} />
|
||||||
<Loading backdrop={false} />
|
) : (
|
||||||
) : (
|
<>
|
||||||
<>
|
<iframe
|
||||||
<iframe
|
className="flex flex-1 absolute inset-0 w-full h-full z-10"
|
||||||
className="flex flex-1 absolute inset-0 w-full h-full z-10"
|
src={`${vscode_url}folder=/site/${p.site.id}/site/src`}
|
||||||
src={`${vscode_url}folder=/site/${p.site.id}/site/src`}
|
></iframe>
|
||||||
></iframe>
|
<div className="flex flex-1 absolute inset-0 z-0 items-center justify-center">
|
||||||
<div className="flex flex-1 absolute inset-0 z-0 items-center justify-center">
|
Loading VSCode...
|
||||||
Loading VSCode...
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
)}
|
||||||
)}
|
</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>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(local.namePicker || local.codeAssign) && (
|
{(local.namePicker || local.codeAssign) && (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { site } from "dbgen";
|
import { site } from "dbgen";
|
||||||
import { FC } from "react";
|
import { FC, ReactNode } from "react";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { EDGlobal } from "../../../logic/ed-global";
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
import { formStyle } from "../../../../../utils/ui/form.style";
|
import { formStyle } from "../../../../../utils/ui/form.style";
|
||||||
|
|
@ -8,14 +8,16 @@ import { Input } from "../../../../../utils/ui/form/input";
|
||||||
export const EdFormSite: FC<{
|
export const EdFormSite: FC<{
|
||||||
site: Partial<site>;
|
site: Partial<site>;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: () => void;
|
onSave: (data: null | site) => void;
|
||||||
group_id: string;
|
group_id: string;
|
||||||
}> = ({ site, onClose, onSave, group_id }) => {
|
header?: ReactNode;
|
||||||
|
}> = ({ site, onClose, onSave, group_id, header }) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
init: false,
|
init: false,
|
||||||
saving: false,
|
saving: false,
|
||||||
preventClose: false,
|
preventClose: false,
|
||||||
|
domain_follow_name: false,
|
||||||
});
|
});
|
||||||
const form = useLocal({} as Partial<site>);
|
const form = useLocal({} as Partial<site>);
|
||||||
|
|
||||||
|
|
@ -57,15 +59,43 @@ export const EdFormSite: FC<{
|
||||||
local.saving = true;
|
local.saving = true;
|
||||||
local.render();
|
local.render();
|
||||||
try {
|
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) {
|
if (!form.id) {
|
||||||
try {
|
try {
|
||||||
await _db.site.create({
|
data = await _db.site.create({
|
||||||
data: {
|
data: {
|
||||||
name: form.name,
|
name: form.name,
|
||||||
favicon: "",
|
favicon: "",
|
||||||
domain: form.domain || "",
|
domain: form.domain || "",
|
||||||
id_user: p.user.id,
|
id_user: p.user.id,
|
||||||
id_org: group_id,
|
id_org: gid,
|
||||||
responsive: form.responsive,
|
responsive: form.responsive,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -73,7 +103,7 @@ export const EdFormSite: FC<{
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await _db.site.update({
|
data = await _db.site.update({
|
||||||
data: {
|
data: {
|
||||||
name: form.name,
|
name: form.name,
|
||||||
domain: form.domain,
|
domain: form.domain,
|
||||||
|
|
@ -82,7 +112,7 @@ export const EdFormSite: FC<{
|
||||||
where: { id: form.id },
|
where: { id: form.id },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
onSave();
|
onSave(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
|
|
@ -94,101 +124,109 @@ export const EdFormSite: FC<{
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
className={cx(formStyle, "bg-white shadow-2xl border")}
|
|
||||||
>
|
>
|
||||||
<label>
|
{header}
|
||||||
<span>Name</span>
|
<div className={cx(formStyle, "bg-white shadow-2xl border")}>
|
||||||
<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 && (
|
|
||||||
<label>
|
<label>
|
||||||
<span>Site ID:</span>
|
<span>Name</span>
|
||||||
<Input form={form} name="id" disabled />
|
<Input
|
||||||
</label>
|
form={form}
|
||||||
)}
|
autoFocus
|
||||||
|
name={"name"}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (!form.domain) {
|
||||||
|
local.domain_follow_name = true;
|
||||||
|
}
|
||||||
|
|
||||||
<div className="flex">
|
if (local.domain_follow_name) {
|
||||||
<button type="submit" disabled={local.saving} className="flex-1">
|
form.domain = (form.name || "")
|
||||||
{local.saving ? "Saving..." : "Save"}
|
.toLowerCase()
|
||||||
</button>
|
.replace(/[^a-z0-9\-_\.]/g, "");
|
||||||
{form.id && (
|
|
||||||
<button
|
form.render();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
/>
|
||||||
|
</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
|
<option value="all">All</option>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<option value="mobile-only">Mobile Only</option>
|
||||||
width="15"
|
<option value="desktop-only">Desktop Only</option>
|
||||||
height="15"
|
</select>
|
||||||
fill="none"
|
</label>
|
||||||
viewBox="0 0 15 15"
|
|
||||||
>
|
{form.id && (
|
||||||
<path
|
<label>
|
||||||
fill="currentColor"
|
<span>Site ID:</span>
|
||||||
fillRule="evenodd"
|
<Input form={form} name="id" disabled />
|
||||||
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"
|
</label>
|
||||||
clipRule="evenodd"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export const base = {
|
||||||
domain: string;
|
domain: string;
|
||||||
api_url: string;
|
api_url: string;
|
||||||
code: {
|
code: {
|
||||||
mode: "new";
|
mode: "new" | "vsc";
|
||||||
};
|
};
|
||||||
api: any;
|
api: any;
|
||||||
db: any;
|
db: any;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export const initBaseRoute = async (isPreviewProd: boolean) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
base.site = res.site;
|
base.site = res.site;
|
||||||
base.site.code = { mode: "new" };
|
base.site.code = { mode: "vsc" };
|
||||||
await injectSiteScript();
|
await injectSiteScript();
|
||||||
|
|
||||||
base.site.api = apiProxy(base.site.api_url);
|
base.site.api = apiProxy(base.site.api_url);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue