Final fixups for deployment #31

Closed
a3thakra wants to merge 3 commits from adi-next-export into main
14 changed files with 65 additions and 32 deletions

View File

View File

@ -4,6 +4,8 @@ from werkzeug.security import generate_password_hash, check_password_hash
import json
import sqlite3
import os
import subprocess
DB_PATH = os.path.join(os.path.dirname(__file__), 'links.db')
app = Flask(__name__)
@ -72,11 +74,16 @@ def update_links():
cur.executemany('INSERT INTO links VALUES (?,?,?,?,?)', links)
con.commit()
con.close()
data = regen_JSON()
# TODO: Trigger a rebuild of the frontend
outfile = open('data.json', 'w')
print(data, file=outfile)
outfile.close()
frontend_path = os.environ.get('FRONTEND_PATH', None)
if frontend_path is None:
raise Exception('FRONTEND_PATH is not defined')
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:
cur.execute("rollback")

2
dev.sh
View File

@ -18,7 +18,7 @@ function dev_backend() {
cd ./backend
source venv/bin/activate
python main.py
FRONTEND_UPDATE_SCRIPT=$(realpath ./frontend/update.sh) python main.py
}
run_frontend_backend "dev_frontend" "dev_backend"

View File

@ -16,6 +16,7 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
const { displayDragDrop } = useDragDrop();
const { headers } = useAuth();
const [editableLinks, setEditableLinks] = useState<EditableLink[]>(links);
const [isSaving, setIsSaving] = useState(false);
useEffect(() => {
setEditableLinks(links);
@ -44,7 +45,9 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
]);
const onSubmit = async () => {
const res = await fetch("/api/editor/links", {
setIsSaving(true);
const res = await fetch("api/editor/links", {
method: "POST",
headers: {
"Content-Type": "application/json",
@ -52,8 +55,11 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
},
body: JSON.stringify({ links: editableLinks }),
});
const updatedLinks = await res.json();
setLinks(updatedLinks);
setIsSaving(false);
};
const onCancel = () => {
@ -110,15 +116,15 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
<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"
onClick={onSubmit}
disabled={equal(editableLinks, links)}
disabled={isSaving || equal(editableLinks, links)}
>
Submit
{isSaving ? "Saving ..." : "Submit"}
</button>
<div className="mr-4" />
<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"
onClick={onCancel}
disabled={equal(editableLinks, links)}
disabled={isSaving || equal(editableLinks, links)}
>
Cancel
</button>

View File

@ -12,7 +12,7 @@ interface Props {
export const Links: React.FC<Props> = ({ links, logClicks = false }) => {
const handleClick = (name: string, url: string) => {
if (logClicks) {
fetch("/api/clicks", {
fetch("api/clicks", {
method: "POST",
headers: {
"Content-Type": "application/json",

View File

@ -31,7 +31,7 @@ export const AuthProvider: React.FC = ({ children }) => {
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) {
setHeaders(newHeaders);

View File

@ -1,6 +1,5 @@
import React, { useState } from "react";
import { useAuth } from "components/Login/AuthContext";
import Image from "next/image";
import Head from "next/head";
const LoginBox: React.FC = () => {
@ -37,8 +36,8 @@ const LoginBox: React.FC = () => {
</Head>
<div className="flex flex-col justify-center items-center space-y-10">
<div className="flex flex-row justify-center items-center space-x-5">
<Image
src="/images/csc-logo-fb-trans.png"
<img
src="csc-logo-trans.png"
height={80}
width={80}
alt="CSC Logo"

View File

@ -1,11 +1,7 @@
// @ts-check
/* eslint-disable @typescript-eslint/no-var-requires */
// eslint-disable-next-line no-undef
const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");
const devConfig = {
module.exports = {
async rewrites() {
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;

View File

@ -4,8 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"build": "next build && next export",
"type-check": "tsc",
"format": "prettier --write './**/*'",
"format:check": "prettier --check './**/*'",

View File

@ -13,7 +13,7 @@ const EditorPage: React.FC = () => {
async function fetchLinks() {
if (!loggedIn) return;
const res = await fetch("/api/editor/links", { headers });
const res = await fetch("api/editor/links", { headers });
const links = await res.json();
setLinks(links);
}

View File

@ -3,7 +3,7 @@ import { GetStaticProps } from "next";
import { Link, Links } from "components/Links";
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();
return {

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

3
frontend/update.sh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
npm run build

31
prod.sh Executable file
View File

@ -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