Compare commits

...

2 Commits

Author SHA1 Message Date
89124b9ad9 seperate regular 2023-04-26 23:19:42 +08:00
6d2c0d8cb3 fix 2023-04-26 22:41:36 +08:00
12 changed files with 108 additions and 18 deletions

2
.gitignore vendored
View File

@@ -1,8 +1,10 @@
/data
/html.html /html.html
/json /json
/hours.json /hours.json
/regular.json /regular.json
/record.json /record.json
/store.json
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies # dependencies

View File

@@ -35,6 +35,7 @@ const downloadObjectAsJson = (exportObj: any, exportName: string) => {
const Timetable = ({ const Timetable = ({
user, user,
isRegular = false,
disableNetwork = false, disableNetwork = false,
disableConflictCheck = false, disableConflictCheck = false,
replaceInputType = "checkbox", replaceInputType = "checkbox",
@@ -126,7 +127,18 @@ const Timetable = ({
for (const td_index in tr.children) { for (const td_index in tr.children) {
const td: HTMLTableCellElement = tr.children[td_index]; const td: HTMLTableCellElement = tr.children[td_index];
if (td.tagName !== "TD") continue; if (td.tagName !== "TD") continue;
if (td.getAttribute("bgcolor")?.toUpperCase() !== "#39CEFF") { if (td.getAttribute("bgcolor")?.toUpperCase() !== "#39CEFF") {
// const position (assigned by supervisor)
if (td?.textContent?.trim() === user) {
const constSelected = document.createElement("input");
constSelected.setAttribute("type", "checkbox");
constSelected.setAttribute("checked", "1");
constSelected.setAttribute("disabled", "1");
td.innerHTML = "";
td.appendChild(constSelected);
}
row.push(null); row.push(null);
continue; continue;
} }
@@ -210,7 +222,7 @@ const Timetable = ({
} }
}; };
React.useEffect(() => { React.useEffect(() => {
if (disableNetwork) return; if (disableNetwork || isRegular) return;
const interval = setInterval(() => { const interval = setInterval(() => {
refresh(); refresh();
@@ -222,7 +234,7 @@ const Timetable = ({
React.useEffect(() => { React.useEffect(() => {
const main = async () => { const main = async () => {
const json = await get("/api/html"); const json = await get(isRegular ? "/api/html-regular" : "/api/html");
ref.current.innerHTML = json.html; ref.current.innerHTML = json.html;
handleInput({ target: ref.current }); handleInput({ target: ref.current });
refresh(); refresh();

View File

@@ -1,6 +1,6 @@
const obj = { const obj = {
begin: false, begin: false,
limit: 2, limit: 2,
token: process.env.TOKEN || "woshimima", token: process.env.TOKEN ?? "woshimima",
}; };
export default obj; export default obj;

View File

@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import { store, html } from "@/store"; import { store, html } from "@/store";
import config from "@/config"; import config from "@/config";
export default function handler( export default async function handler(
req: NextApiRequest, req: NextApiRequest,
res: NextApiResponse<Record<string, string>> res: NextApiResponse<Record<string, string>>
) { ) {
@@ -16,5 +16,6 @@ export default function handler(
const json = req.body; const json = req.body;
store.update(json); store.update(json);
} }
await store.save();
res.status(200).json(store.get()); res.status(200).json(store.get());
} }

View File

@@ -4,6 +4,7 @@ import config from "@/config";
export default function handler(req: NextApiRequest, res: NextApiResponse) { export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") { if (req.method === "POST") {
if (req.headers.token !== config.token) { if (req.headers.token !== config.token) {
console.log("wrong token", req.headers.token, config.token);
res.status(403).json({ error: "wrong token" }); res.status(403).json({ error: "wrong token" });
return; return;
} }

16
pages/api/html-regular.ts Normal file
View File

@@ -0,0 +1,16 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { htmlRegular } from "@/store";
import config from "@/config";
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") {
if (req.headers.token !== config.token) {
res.status(403).json({ error: "wrong token" });
return;
}
htmlRegular.set(req.body.html);
}
res.status(200).json({
html: htmlRegular.get(),
});
}

View File

@@ -8,7 +8,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") { if (req.method === "POST") {
if (!config.begin) { if (!config.begin) {
res.status(400).json({ res.status(400).json({
error: "还没到开时间哦", error: "还没到开时间哦",
}); });
return; return;
} }

View File

@@ -8,7 +8,7 @@ const read = promisify(fs.readFile);
// 索引与工时 // 索引与工时
const indexToHour: Record<string, number> = JSON.parse( const indexToHour: Record<string, number> = JSON.parse(
fs.readFileSync("./hours.json", "utf8") fs.readFileSync("./data/hours.json", "utf8")
).selections; ).selections;
export default async function handler( export default async function handler(
@@ -18,7 +18,7 @@ export default async function handler(
// 读入全部json文件 // 读入全部json文件
// users: {姓名: {坐标: 权重}} // users: {姓名: {坐标: 权重}}
const users: Record<string, Record<string, number>> = {}; const users: Record<string, Record<string, number>> = {};
const files = await g("./json/*.json"); const files = await g("./data/json/*.json");
for (const file of files) { for (const file of files) {
const jsonStr = await read(file, "utf8"); const jsonStr = await read(file, "utf8");
const json: { const json: {

View File

@@ -5,8 +5,9 @@ import { get, post } from "@/common";
const ControlPage = () => { const ControlPage = () => {
const [isBegin, setIsBegin] = React.useState(false); const [isBegin, setIsBegin] = React.useState(false);
const [inputLimit, setInputLimit] = React.useState("2"); const [inputLimit, setInputLimit] = React.useState("2");
const [token, setToken] = React.useState("");
const toggleBegin = async () => { const toggleBegin = async () => {
const json = await post("/api/config", { begin: !isBegin }); const json = await post("/api/config", { begin: !isBegin }, { token });
setIsBegin(json.begin); setIsBegin(json.begin);
}; };
const refresh = async () => { const refresh = async () => {
@@ -26,9 +27,16 @@ const ControlPage = () => {
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
</Head> </Head>
<main> <main>
<p>
<input
value={token}
onChange={(event) => setToken(event.target.value)}
placeholder="Token"
/>
</p>
<p> <p>
<button onClick={() => toggleBegin()}> <button onClick={() => toggleBegin()}>
{isBegin ? "Begin" : "Pause"} {isBegin ? "Pause" : "Begin"}
</button> </button>
</p> </p>
<p> <p>
@@ -40,9 +48,13 @@ const ControlPage = () => {
/> />
<button <button
onClick={() => { onClick={() => {
post("/api/config", { post(
"/api/config",
{
limit: parseInt(inputLimit) || 2, limit: parseInt(inputLimit) || 2,
}); },
{ token }
);
}} }}
> >
Set Limit Set Limit

39
pages/edit-regular.tsx Normal file
View File

@@ -0,0 +1,39 @@
import React from "react";
import { get, post } from "@/common";
const EditPage = () => {
const [token, setToken] = React.useState("");
const ref = React.useRef();
const upload = async () => {
const html = ref.current.innerHTML;
await post("/api/html-regular", { html }, { token });
alert("Upload success");
refresh();
};
const refresh = async () => {
const html = await get("/api/html-regular");
ref.current.innerHTML = html.html;
};
React.useEffect(() => {
refresh();
}, []);
return (
<>
<input
value={token}
placeholder={"token"}
onChange={(event) => setToken(event.target.value)}
/>
<button onClick={() => upload()}>Upload</button>
<div
ref={ref}
onInput={(event) => {
console.log(event.currentTarget.innerHTML);
}}
contentEditable="true"
></div>
</>
);
};
export default EditPage;

View File

@@ -22,6 +22,7 @@ const ReportPage = () => {
disableNetwork={true} disableNetwork={true}
apiRecordEndPoint="/api/regular" apiRecordEndPoint="/api/regular"
openRecordMode={true} openRecordMode={true}
isRegular={true}
/> />
</UserInputWrap> </UserInputWrap>
</main> </main>

View File

@@ -27,16 +27,21 @@ class Store {
} }
public async update(record: Record<string, string>) { public async update(record: Record<string, string>) {
this.record = record; this.record = record;
await this.save();
}
public async save() {
await write(this.filename, JSON.stringify(this.record), "utf8"); await write(this.filename, JSON.stringify(this.record), "utf8");
} }
} }
class HTML { class HTML {
html: string; html: string;
constructor() { filename: string;
constructor(filename: string) {
this.filename = filename;
// load from file // load from file
try { try {
this.html = fs.readFileSync("./html.html", "utf8"); this.html = fs.readFileSync(this.filename, "utf8");
} catch { } catch {
this.html = ""; this.html = "";
} }
@@ -47,10 +52,11 @@ class HTML {
public async set(html: string) { public async set(html: string) {
this.html = html; this.html = html;
// store into file // store into file
await write("./html.html", html, "utf8"); await write(this.filename, html, "utf8");
} }
} }
export const html = new HTML(); export const html = new HTML("./data/html.html");
export const store = new Store("store.json"); export const htmlRegular = new HTML("./data/html-regular.html");
export const regular = new Store("regular.json"); export const store = new Store("./data/store.json");
export const regular = new Store("./data/regular.json");