workin like a worker bee but not keeping track of what i do
This commit is contained in:
parent
6ce4def6e5
commit
1e0eb1e831
@ -1,5 +1,8 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
padding-left: 60vmin;
|
||||
padding-right: 60vmin;
|
||||
background-color: #282c34;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
@ -14,7 +17,6 @@
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -41,6 +43,8 @@
|
||||
text-align: left;
|
||||
padding: 1em;
|
||||
border: 1px solid black;
|
||||
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
.Page-contents pre {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import './App.css';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { useState } from 'react';
|
||||
import { apiUrl, fetchPage, postPage, deletePage } from './clientStuff.jsx';
|
||||
import { apiUrl, fetchPage, postPage, deletePage } from './apiTools.jsx';
|
||||
|
||||
function PageView() {
|
||||
const queryClient = useQueryClient();
|
||||
@ -56,43 +56,42 @@ function PageView() {
|
||||
navigate(`/`);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<a href="/"><img src={logo} className="App-logo" alt="logo" /></a>
|
||||
<div className="Page-title">
|
||||
<h3>
|
||||
{pagenumber}.
|
||||
<span
|
||||
contentEditable="true"
|
||||
dangerouslySetInnerHTML={{__html: ready ? page_title : "..." }} />
|
||||
</h3>
|
||||
</div>
|
||||
{ ready ?
|
||||
<>
|
||||
<div className="Page-contents">
|
||||
<pre
|
||||
contentEditable="true"
|
||||
dangerouslySetInnerHTML={{__html: page_text}} />
|
||||
</div>
|
||||
<button
|
||||
disabled={postMutation.isPending}
|
||||
onClick={submitChanges}>
|
||||
{postMutation.isPending ? "Updating..." : "Update"}
|
||||
</button>
|
||||
<button
|
||||
disabled={deleteMutation.isPending}
|
||||
onClick={submitDelete}>
|
||||
{deleteMutation.isPending ? "Deleting..." : "Delete this page (no backsies)"}
|
||||
</button>
|
||||
</>
|
||||
:
|
||||
<section className="App-header">
|
||||
<a href="/"><img src={logo} className="App-logo" alt="logo" /></a>
|
||||
<div className="Page-title">
|
||||
<h3>
|
||||
{pagenumber}.
|
||||
<span
|
||||
contentEditable="true"
|
||||
dangerouslySetInnerHTML={{__html: ready ? page_title : "..." }} />
|
||||
</h3>
|
||||
</div>
|
||||
{ ready ?
|
||||
<>
|
||||
<div className="Page-contents">
|
||||
{ fetchQuery.isPending ? "Loading..." : JSON.stringify(fetchQuery.error) }
|
||||
<pre
|
||||
contentEditable="true"
|
||||
dangerouslySetInnerHTML={{__html: page_text}} />
|
||||
</div>
|
||||
}
|
||||
</header>
|
||||
<button
|
||||
disabled={postMutation.isPending}
|
||||
onClick={submitChanges}>
|
||||
{postMutation.isPending ? "Updating..." : "Update"}
|
||||
</button>
|
||||
<button
|
||||
disabled={deleteMutation.isPending}
|
||||
onClick={submitDelete}>
|
||||
{deleteMutation.isPending ? "Deleting..." : "Delete this page (no backsies)"}
|
||||
</button>
|
||||
</>
|
||||
:
|
||||
<div className="Page-contents">
|
||||
{ fetchQuery.isPending ? "Loading..." : JSON.stringify(fetchQuery.error) }
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNavigate, Link } from 'react-router-dom'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { apiUrl, fetchPageList, postNewPage } from './clientStuff.jsx';
|
||||
import { apiUrl, fetchPageList, postNewPage } from './apiTools.jsx';
|
||||
import { useFixLinks } from './clientStuff.jsx';
|
||||
|
||||
function Landing() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const noLoad = useFixLinks();
|
||||
const { isPending, error, data } = useQuery({ // fetch the currrent values
|
||||
queryKey: ['pages'],
|
||||
queryFn: fetchPageList
|
||||
@ -38,8 +40,8 @@ function Landing() {
|
||||
<ul>
|
||||
{
|
||||
data.map((row) =>
|
||||
<li>
|
||||
<a key={row} href={`/${row}`}>page {row}</a>
|
||||
<li key={row}>
|
||||
<a href={`/${row}`} {...noLoad}>page {row}</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ import './App.css';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { useState } from 'react';
|
||||
import { apiUrl, fetchPage, postPage } from './clientStuff.jsx';
|
||||
import { apiUrl, fetchPage, postPage } from './apiTools.jsx';
|
||||
import { useFixLinks } from './clientStuff.jsx';
|
||||
|
||||
|
||||
function PageView() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const noLoad = useFixLinks();
|
||||
const { pagenumber } = useParams();
|
||||
|
||||
const { isPending, error, data } = useQuery({ // fetch the currrent values
|
||||
@ -24,7 +27,7 @@ function PageView() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<a href="/"><img src={logo} className="App-logo" alt="logo" /></a>
|
||||
<a href="/" {...noLoad}><img src={logo} className="App-logo" alt="logo" /></a>
|
||||
<div className="Page-title">
|
||||
<h3>{pagenumber}. {ready ? (page_title || " ") : "..."}</h3>
|
||||
</div>
|
||||
@ -32,6 +35,7 @@ function PageView() {
|
||||
<div
|
||||
className="Page-contents"
|
||||
dangerouslySetInnerHTML={{ __html: (page_html || " ") }}
|
||||
{...noLoad}
|
||||
/>
|
||||
:
|
||||
<div className="Page-contents">
|
||||
|
45
client/src/apiTools.jsx
Normal file
45
client/src/apiTools.jsx
Normal file
@ -0,0 +1,45 @@
|
||||
// This is wrapper functtions to do requests to the api, from the frontend.
|
||||
|
||||
export const apiUrl = "http://127.0.0.1:3001"
|
||||
|
||||
const defaults = {
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
};
|
||||
|
||||
export async function postNewPage() {
|
||||
return fetch(`${apiUrl}/page/new`, {
|
||||
method: 'POST',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
.then((data) => data.id)
|
||||
}
|
||||
|
||||
export async function fetchPageList() {
|
||||
return fetch(`${apiUrl}/pages`, {
|
||||
method: 'GET',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
}
|
||||
|
||||
export async function fetchPage(id) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'GET',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
}
|
||||
|
||||
export async function postPage({id, title, description}) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({id: id, title: title, description: description}),
|
||||
...defaults
|
||||
})
|
||||
}
|
||||
|
||||
export async function deletePage(id) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
...defaults
|
||||
})
|
||||
}
|
@ -1,43 +1,14 @@
|
||||
export const apiUrl = "http://127.0.0.1:3001"
|
||||
// New hook to make links use the react-router `navigate` method instead of default browser behavior.
|
||||
|
||||
const defaults = {
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
};
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
export async function postNewPage() {
|
||||
return fetch(`${apiUrl}/page/new`, {
|
||||
method: 'POST',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
.then((data) => data.id)
|
||||
}
|
||||
|
||||
export async function fetchPageList() {
|
||||
return fetch(`${apiUrl}/pages`, {
|
||||
method: 'GET',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
}
|
||||
|
||||
export async function fetchPage(id) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'GET',
|
||||
...defaults
|
||||
}).then((res) => res.json())
|
||||
}
|
||||
|
||||
export async function postPage({id, title, description}) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({id: id, title: title, description: description}),
|
||||
...defaults
|
||||
})
|
||||
}
|
||||
|
||||
export async function deletePage(id) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
...defaults
|
||||
})
|
||||
export function useFixLinks() {
|
||||
// spread this return value on <a/> elements in order to make them navigate
|
||||
const navigate = useNavigate();
|
||||
return { onClick: (e) => {
|
||||
if (e.target.tagName != "A") { return; }
|
||||
if (!e.target.href.includes(window.location.origin)) { return; }
|
||||
e.preventDefault();
|
||||
navigate(e.target.href.replace(window.location.origin, ""));
|
||||
}};
|
||||
}
|
@ -1 +0,0 @@
|
||||
'{"statements": [{"q": ["replace into pages (id, title, description) values (?, ?, ?)", "params": [2,"main2","dummyvalue"] }], }'
|
Binary file not shown.
@ -1 +1 @@
|
||||
{"id":"7de13931-444c-4dd2-a19a-5cd1e70b7f36","rows_written":109,"rows_read":1706,"storage_bytes_used":12288,"write_requests_delegated":0,"current_frame_no":108,"top_query_threshold":3,"top_queries":[{"rows_written":2,"rows_read":1,"query":"\ncreate table if not exists renders (\n id integer primary key,\n title varchar(255),\n description text\n)\n"},{"rows_written":0,"rows_read":4,"query":"select id from pages"},{"rows_written":0,"rows_read":5,"query":"select id from pages"},{"rows_written":1,"rows_read":4,"query":"\nalter table pages \nadd column html text\n"},{"rows_written":0,"rows_read":6,"query":"\nselect p.id from pages p where not exists (select r.id from renders r where p.id = r.id)\n"},{"rows_written":0,"rows_read":10,"query":"select id from pages"},{"rows_written":0,"rows_read":11,"query":"select id from pages"},{"rows_written":0,"rows_read":12,"query":"select id from pages"},{"rows_written":0,"rows_read":13,"query":"select id from pages"},{"rows_written":0,"rows_read":14,"query":"select id from pages"}],"slowest_query_threshold":0,"slowest_queries":[{"elapsed_ms":0,"query":"select id, title, description from pages where id=@val","rows_written":0,"rows_read":1},{"elapsed_ms":0,"query":"select title from pages","rows_written":0,"rows_read":1},{"elapsed_ms":0,"query":"select title from pages","rows_written":0,"rows_read":2},{"elapsed_ms":1,"query":"\nalter table pages \nadd column html text\n","rows_written":1,"rows_read":4},{"elapsed_ms":1,"query":"\ncreate table if not exists renders (\n id integer primary key,\n title varchar(255),\n description text\n)\n","rows_written":2,"rows_read":1},{"elapsed_ms":1,"query":"insert into pages (title, description) values (?, ?) returning id","rows_written":1,"rows_read":1},{"elapsed_ms":1,"query":"replace into pages (id, title, description) values (?, ?, ?)","rows_written":1,"rows_read":1},{"elapsed_ms":1,"query":"select * from pages where id=@val","rows_written":0,"rows_read":1},{"elapsed_ms":1,"query":"select count(*) as num_pages from pages","rows_written":0,"rows_read":1},{"elapsed_ms":7,"query":"replace into pages (id, title, description) values (?, ?, ?)","rows_written":1,"rows_read":1}],"embedded_replica_frames_replicated":0,"query_count":877,"query_latency":90259}
|
||||
{"id":"7de13931-444c-4dd2-a19a-5cd1e70b7f36","rows_written":112,"rows_read":2745,"storage_bytes_used":12288,"write_requests_delegated":0,"current_frame_no":111,"top_query_threshold":3,"top_queries":[{"rows_written":2,"rows_read":1,"query":"\ncreate table if not exists renders (\n id integer primary key,\n title varchar(255),\n description text\n)\n"},{"rows_written":0,"rows_read":4,"query":"select id from pages"},{"rows_written":0,"rows_read":5,"query":"select id from pages"},{"rows_written":1,"rows_read":4,"query":"\nalter table pages \nadd column html text\n"},{"rows_written":0,"rows_read":6,"query":"\nselect p.id from pages p where not exists (select r.id from renders r where p.id = r.id)\n"},{"rows_written":0,"rows_read":10,"query":"select id from pages"},{"rows_written":0,"rows_read":11,"query":"select id from pages"},{"rows_written":0,"rows_read":12,"query":"select id from pages"},{"rows_written":0,"rows_read":13,"query":"select id from pages"},{"rows_written":0,"rows_read":14,"query":"select id from pages"}],"slowest_query_threshold":0,"slowest_queries":[{"elapsed_ms":0,"query":"select title from pages","rows_written":0,"rows_read":1},{"elapsed_ms":0,"query":"select title from pages","rows_written":0,"rows_read":2},{"elapsed_ms":1,"query":"\nalter table pages \nadd column html text\n","rows_written":1,"rows_read":4},{"elapsed_ms":1,"query":"\ncreate table if not exists renders (\n id integer primary key,\n title varchar(255),\n description text\n)\n","rows_written":2,"rows_read":1},{"elapsed_ms":1,"query":"insert into pages (title, description) values (?, ?) returning id","rows_written":1,"rows_read":1},{"elapsed_ms":1,"query":"replace into pages (id, title, description) values (?, ?, ?)","rows_written":1,"rows_read":1},{"elapsed_ms":1,"query":"replace into pages (id, title, description, html) values (?, ?, ?, ?)","rows_written":1,"rows_read":1},{"elapsed_ms":1,"query":"select * from pages where id=@val","rows_written":0,"rows_read":1},{"elapsed_ms":1,"query":"select count(*) as num_pages from pages","rows_written":0,"rows_read":1},{"elapsed_ms":7,"query":"replace into pages (id, title, description) values (?, ?, ?)","rows_written":1,"rows_read":1}],"embedded_replica_frames_replicated":0,"query_count":1006,"query_latency":98084}
|
Binary file not shown.
19
server/dbHelper.js
Normal file
19
server/dbHelper.js
Normal file
@ -0,0 +1,19 @@
|
||||
// helper function(s?) to make a query to the database
|
||||
|
||||
const db_url = 'http://localhost:8000'
|
||||
|
||||
async function query(q, params) {
|
||||
return fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: q,
|
||||
params: params
|
||||
}]
|
||||
})
|
||||
}).then((res) => res.json())
|
||||
.then((data) => data[0].results);
|
||||
}
|
||||
|
||||
module.exports = { query: query };
|
@ -1,7 +1,7 @@
|
||||
const express = require('express');
|
||||
const showdown = require('showdown');
|
||||
const { query } = require('./dbHelper.js');
|
||||
|
||||
const db_url = 'http://localhost:8000'
|
||||
const port = process.env.PORT || 3001; // Use the port provided by the host or default to 3000
|
||||
|
||||
const app = express();
|
||||
@ -19,93 +19,41 @@ app.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
});
|
||||
|
||||
// Define a route to handle incoming requests
|
||||
app.post('/', (req, res) => {
|
||||
res.send('Hello, Express!');
|
||||
});
|
||||
|
||||
app.get('/pages', (req, res) => {
|
||||
fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: ['select id from pages']
|
||||
})
|
||||
}).then((rsp) => rsp.json())
|
||||
.then((data) => data[0].results.rows)
|
||||
.then((rows) => rows.map(([id]) => id))
|
||||
.then((ids) => res.json(ids))
|
||||
query('select id from pages', [])
|
||||
.then((r) => r.rows)
|
||||
.then((row) => row.map(([id]) => id))
|
||||
.then((ids) => res.status(200).json(ids))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
});
|
||||
|
||||
app.post('/page/new', (req, res) => {
|
||||
fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: 'insert into pages (title, description) values (?, ?) returning id',
|
||||
params: ["new page", "this page is new!"]
|
||||
}]
|
||||
})
|
||||
}).then((rsp) => rsp.json())
|
||||
.then((data) => data[0].results.rows[0][0])
|
||||
query('insert into pages (title, description) values (?, ?) returning id',
|
||||
["new page", "this page is new!"])
|
||||
.then((r) => r.rows[0][0])
|
||||
.then((row) => res.status(200).json({id: row}))
|
||||
.catch((error) => res.status(500).json({"error": error}))
|
||||
});
|
||||
|
||||
app.get('/page/:id', (req, res) => {
|
||||
fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: 'select * from pages where id=?',
|
||||
params: [req.params.id]
|
||||
}]
|
||||
})
|
||||
}).then((rsp) => rsp.json())
|
||||
.then((data) => {
|
||||
if (data[0].results.rows.length == 0) return res.status(404).json({"error": "page not found in db"});
|
||||
return data[0].results.rows[0];
|
||||
query('select * from pages where id=?', [req.params.id])
|
||||
.then((r) => {
|
||||
if (r.rows.length == 0) return res.status(404).json({"error": "page not found in db"});
|
||||
return r.rows[0];
|
||||
}).then((row) => res.status(200).json(row))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
});
|
||||
|
||||
app.post('/page/:id', (req, res) => {
|
||||
console.log(`got a post for /page/${req.params.id}`, req.body);
|
||||
console.log(`rendering new input ${req.params.id}`);
|
||||
|
||||
const html = converter.makeHtml(req.body.description);
|
||||
console.log(`the output was ${html}`)
|
||||
|
||||
console.log("done rendering");
|
||||
|
||||
fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: 'replace into pages (id, title, description, html) values (?, ?, ?, ?)',
|
||||
params: [Number(req.params.id), req.body.title, req.body.description, html],
|
||||
}]
|
||||
})
|
||||
}).then(() => res.status(200).json({}))
|
||||
query('replace into pages (id, title, description, html) values (?, ?, ?, ?)',
|
||||
[req.params.id, req.body.title, req.body.description, html])
|
||||
.then(() => res.status(200).json({}))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
});
|
||||
|
||||
app.delete('/page/:id', (req, res) => {
|
||||
console.log(`deleting page #${req.params.id}`);
|
||||
|
||||
fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: 'delete from pages where id = ?',
|
||||
params: [Number(req.params.id)]
|
||||
}]
|
||||
})
|
||||
}).then(() => res.status(200).json({id: req.params.id}))
|
||||
query('delete from pages where id = ?', [req.params.id])
|
||||
.then(() => res.status(200).json({id: req.params.id}))
|
||||
.catch((error) => res.status(500).json({"error": error}))
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user