Compare commits
3 Commits
main
...
adi-next-e
Author | SHA1 | Date |
---|---|---|
Aditya Thakral | ae34744c47 | |
Aditya Thakral | 39692a0333 | |
Aditya Thakral | 5de03bf8d1 |
|
@ -4,6 +4,8 @@ from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
DB_PATH = os.path.join(os.path.dirname(__file__), 'links.db')
|
DB_PATH = os.path.join(os.path.dirname(__file__), 'links.db')
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -72,11 +74,16 @@ def update_links():
|
||||||
cur.executemany('INSERT INTO links VALUES (?,?,?,?,?)', links)
|
cur.executemany('INSERT INTO links VALUES (?,?,?,?,?)', links)
|
||||||
con.commit()
|
con.commit()
|
||||||
con.close()
|
con.close()
|
||||||
data = regen_JSON()
|
|
||||||
# TODO: Trigger a rebuild of the frontend
|
frontend_path = os.environ.get('FRONTEND_PATH', None)
|
||||||
outfile = open('data.json', 'w')
|
if frontend_path is None:
|
||||||
print(data, file=outfile)
|
raise Exception('FRONTEND_PATH is not defined')
|
||||||
outfile.close()
|
|
||||||
|
update_command = f"cd '{frontend_path}' && ./update.sh"
|
||||||
|
status = subprocess.call(update_command, shell=True)
|
||||||
|
|
||||||
|
if status != 0:
|
||||||
|
raise Exception(f"`{update_command}` exited with an error ({status})")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
cur.execute("rollback")
|
cur.execute("rollback")
|
||||||
|
|
2
dev.sh
2
dev.sh
|
@ -18,7 +18,7 @@ function dev_backend() {
|
||||||
cd ./backend
|
cd ./backend
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
|
|
||||||
python main.py
|
FRONTEND_UPDATE_SCRIPT=$(realpath ./frontend/update.sh) python main.py
|
||||||
}
|
}
|
||||||
|
|
||||||
run_frontend_backend "dev_frontend" "dev_backend"
|
run_frontend_backend "dev_frontend" "dev_backend"
|
||||||
|
|
|
@ -16,6 +16,7 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
|
||||||
const { displayDragDrop } = useDragDrop();
|
const { displayDragDrop } = useDragDrop();
|
||||||
const { headers } = useAuth();
|
const { headers } = useAuth();
|
||||||
const [editableLinks, setEditableLinks] = useState<EditableLink[]>(links);
|
const [editableLinks, setEditableLinks] = useState<EditableLink[]>(links);
|
||||||
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setEditableLinks(links);
|
setEditableLinks(links);
|
||||||
|
@ -44,7 +45,9 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const res = await fetch("/api/editor/links", {
|
setIsSaving(true);
|
||||||
|
|
||||||
|
const res = await fetch("api/editor/links", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -52,8 +55,11 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ links: editableLinks }),
|
body: JSON.stringify({ links: editableLinks }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedLinks = await res.json();
|
const updatedLinks = await res.json();
|
||||||
|
|
||||||
setLinks(updatedLinks);
|
setLinks(updatedLinks);
|
||||||
|
setIsSaving(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
|
@ -110,15 +116,15 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
|
||||||
<button
|
<button
|
||||||
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
|
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
|
||||||
onClick={onSubmit}
|
onClick={onSubmit}
|
||||||
disabled={equal(editableLinks, links)}
|
disabled={isSaving || equal(editableLinks, links)}
|
||||||
>
|
>
|
||||||
Submit
|
{isSaving ? "Saving ..." : "Submit"}
|
||||||
</button>
|
</button>
|
||||||
<div className="mr-4" />
|
<div className="mr-4" />
|
||||||
<button
|
<button
|
||||||
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
|
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
disabled={equal(editableLinks, links)}
|
disabled={isSaving || equal(editableLinks, links)}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface Props {
|
||||||
export const Links: React.FC<Props> = ({ links, logClicks = false }) => {
|
export const Links: React.FC<Props> = ({ links, logClicks = false }) => {
|
||||||
const handleClick = (name: string, url: string) => {
|
const handleClick = (name: string, url: string) => {
|
||||||
if (logClicks) {
|
if (logClicks) {
|
||||||
fetch("/api/clicks", {
|
fetch("api/clicks", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
@ -31,7 +31,7 @@ export const AuthProvider: React.FC = ({ children }) => {
|
||||||
Authorization: `CustomBasic ${btoa(`${username}:${password}`)}`,
|
Authorization: `CustomBasic ${btoa(`${username}:${password}`)}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await fetch("/api/editor/links", { headers: newHeaders });
|
const res = await fetch("api/editor/links", { headers: newHeaders });
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
setHeaders(newHeaders);
|
setHeaders(newHeaders);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useAuth } from "components/Login/AuthContext";
|
import { useAuth } from "components/Login/AuthContext";
|
||||||
import Image from "next/image";
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
const LoginBox: React.FC = () => {
|
const LoginBox: React.FC = () => {
|
||||||
|
@ -37,8 +36,8 @@ const LoginBox: React.FC = () => {
|
||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-col justify-center items-center space-y-10">
|
<div className="flex flex-col justify-center items-center space-y-10">
|
||||||
<div className="flex flex-row justify-center items-center space-x-5">
|
<div className="flex flex-row justify-center items-center space-x-5">
|
||||||
<Image
|
<img
|
||||||
src="/images/csc-logo-fb-trans.png"
|
src="csc-logo-trans.png"
|
||||||
height={80}
|
height={80}
|
||||||
width={80}
|
width={80}
|
||||||
alt="CSC Logo"
|
alt="CSC Logo"
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");
|
module.exports = {
|
||||||
|
|
||||||
const devConfig = {
|
|
||||||
async rewrites() {
|
async rewrites() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -19,11 +15,3 @@ const devConfig = {
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const prodConfig = {
|
|
||||||
basePath: "/links",
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
module.exports = (phase) =>
|
|
||||||
phase === PHASE_DEVELOPMENT_SERVER ? devConfig : prodConfig;
|
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build && next export",
|
||||||
"start": "next start",
|
|
||||||
"type-check": "tsc",
|
"type-check": "tsc",
|
||||||
"format": "prettier --write './**/*'",
|
"format": "prettier --write './**/*'",
|
||||||
"format:check": "prettier --check './**/*'",
|
"format:check": "prettier --check './**/*'",
|
||||||
|
|
|
@ -13,7 +13,7 @@ const EditorPage: React.FC = () => {
|
||||||
async function fetchLinks() {
|
async function fetchLinks() {
|
||||||
if (!loggedIn) return;
|
if (!loggedIn) return;
|
||||||
|
|
||||||
const res = await fetch("/api/editor/links", { headers });
|
const res = await fetch("api/editor/links", { headers });
|
||||||
const links = await res.json();
|
const links = await res.json();
|
||||||
setLinks(links);
|
setLinks(links);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { GetStaticProps } from "next";
|
||||||
import { Link, Links } from "components/Links";
|
import { Link, Links } from "components/Links";
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<Props> = async () => {
|
export const getStaticProps: GetStaticProps<Props> = async () => {
|
||||||
const res = await fetch(`${process.env.DEV_URL}/links`);
|
const res = await fetch(`http://${process.env.SERVER_URL}/links`);
|
||||||
const links = await res.json();
|
const links = await res.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
npm run build
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Starting the python server..."
|
||||||
|
|
||||||
|
pushd backend
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
FRONTEND_PATH=$(realpath ../frontend) python main.py &
|
||||||
|
pid_backend=$!
|
||||||
|
|
||||||
|
trap_ctrlc() {
|
||||||
|
kill $pid_backend
|
||||||
|
}
|
||||||
|
|
||||||
|
trap trap_ctrlc INT
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
echo "Building frontend..."
|
||||||
|
|
||||||
|
pushd frontend
|
||||||
|
npm run build
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
|
wait
|
Loading…
Reference in New Issue