From af16c7f8f0a08e1eeca9e6bd077d09a0c026ce4f Mon Sep 17 00:00:00 2001 From: slynn1324 Date: Thu, 21 Jan 2021 17:55:24 -0600 Subject: [PATCH] more work --- server.js | 64 ++++- static/client.css | 98 ++++++++ static/client.js | 630 +++++++++++++++++++++++++++++++++------------- 3 files changed, 607 insertions(+), 185 deletions(-) diff --git a/server.js b/server.js index 33799aa..766deb6 100644 --- a/server.js +++ b/server.js @@ -47,8 +47,9 @@ app.get("/api/boards", (req, res) => { }); // get board -app.get("/api/boards/:boardId", (req, res) => { +app.get("/api/boards/:boardId", async (req, res) => { try{ + await sleep(1000); let board = db.prepare("SELECT * FROM boards WHERE id = ?").get(req.params.boardId); if ( board ){ @@ -70,6 +71,7 @@ app.post('/api/boards', (req, res) => { let result = db.prepare("INSERT INTO boards (name, createDate) VALUES (@name, @createDate)").run({name: req.body.name, createDate: new Date().toISOString()}); let id = result.lastInsertRowid; let board = db.prepare("SELECT * FROM boards WHERE id = ?").get(id); + board.titlePinId = 0; res.send(board); console.log(`Created board#${id} ${req.body.name}`); @@ -99,9 +101,19 @@ app.post("/api/boards/:boardId", (req, res) =>{ }); // delete board -app.delete("/api/boards/:boardId", (req, res) => { +app.delete("/api/boards/:boardId", async (req, res) => { try{ - let result = db.prepare("DELETE FROM boards WHERE id = ?").run(req.params.boardId); + await sleep(1000); + + let pins = db.prepare("SELECT id FROM pins WHERE boardId = ?").all(req.params.boardId); + for ( let i = 0; i < pins.length; ++i ){ + await fs.unlink(getThumbnailImagePath(pins[i].id).file); + await fs.unlink(getOriginalImagePath(pins[i].id).file); + } + + let result = db.prepare("DELETE FROM pins WHERE boardId = ?").run(req.params.boardId); + result = db.prepare("DELETE FROM boards WHERE id = ?").run(req.params.boardId); + if ( result.changes == 1 ){ res.send(OK); } else { @@ -128,10 +140,20 @@ app.get("/api/pins/:pinId", (req, res) => { } }); +async function sleep(millis){ + return new Promise( (resolve,reject) => { + setTimeout(() => { + resolve(); + }, millis) + }); +} + // create pin app.post("/api/pins", async (req, res) => { try { + await sleep(1000); + console.log(req.body); let image = await downloadImage(req.body.imageUrl); @@ -212,6 +234,7 @@ app.post("/api/pins/:pinId", (req,res) => { }); if ( result.changes == 1 ){ + console.log(`updated pin#${req.params.pinId}`) res.send(OK); } else { res.status(404).send(NOT_FOUND); @@ -223,6 +246,29 @@ app.post("/api/pins/:pinId", (req,res) => { }); +app.delete("/api/pins/:pinId", async (req, res) => { + + await sleep(1000); + + try { + + await fs.unlink(getThumbnailImagePath(req.params.pinId).file); + await fs.unlink(getOriginalImagePath(req.params.pinId).file); + + let result = db.prepare('DELETE FROM pins WHERE id = ?').run(req.params.pinId); + + if ( result.changes == 1 ){ + console.log(`deleted pin#${req.params.pinId}`); + res.send(OK); + } else { + res.status(404).send(NOT_FOUND); + } + } catch (err){ + console.log(`Error deleting pin#${req.params.pinId}`, err); + res.status(500).send(SERVER_ERROR); + } +}); + // start listening app.listen(port, () => { @@ -269,6 +315,10 @@ function initDb(){ ) `).run(); + db.prepare(` + INSERT INTO boards (id, name, createDate) VALUES (0, 'Default Board', ?) + `).run(new Date().toISOString()); + db.prepare("INSERT INTO migrations (id, createDate) VALUES ( @id, @createDate )").run({id:1, createDate: new Date().toISOString()}); } else { @@ -309,13 +359,7 @@ async function downloadImage(imageUrl){ } } -// function padId(id){ -// let result = id.toString(); -// while ( result.length < 12 ) { -// result = '0' + result; -// } -// return result; -// } + function getOriginalImagePath(pinId){ let paddedId = pinId.toString().padStart(12, '0'); diff --git a/static/client.css b/static/client.css index 40d6a6e..9c55326 100644 --- a/static/client.css +++ b/static/client.css @@ -101,4 +101,102 @@ .section { flex: 1; +} + + +/* + * loader - https://loading.io/css/ + */ + .lds-ring { + display: inline-block; + position: relative; + width: 80px; + height: 80px; + } + .lds-ring div { + box-sizing: border-box; + display: block; + position: absolute; + width: 64px; + height: 64px; + margin: 8px; + border: 8px solid #fff; + border-radius: 50%; + animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + border-color: #fff transparent transparent transparent; + } + .lds-ring div:nth-child(1) { + animation-delay: -0.45s; + } + .lds-ring div:nth-child(2) { + animation-delay: -0.3s; + } + .lds-ring div:nth-child(3) { + animation-delay: -0.15s; + } + @keyframes lds-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + + + +.pin-zoom-modal-delete { + position: fixed; + width: 24px; + height: 24px; + bottom: 20px; + right: 20px; + background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjRkZGRkZGIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHg9IjBweCIgeT0iMHB4Ij48dGl0bGU+dHJhc2g8L3RpdGxlPjxwYXRoIGQ9Ik05MC42OSwxMi4yMlYxOGEyLjkxLDIuOTEsMCwwLDEtMi45MSwyLjkxSDEyLjIyQTIuOTEsMi45MSwwLDAsMSw5LjMxLDE4VjEyLjIyYTIuOTEsMi45MSwwLDAsMSwyLjkxLTIuOTFIMzRsMS43MS0zLjRBNC43Miw0LjcyLDAsMCwxLDM5LjU5LDMuNUg2MC4zOGE0Ljc4LDQuNzgsMCwwLDEsMy45LDIuNDFMNjYsOS4zMWgyMS44QTIuOTEsMi45MSwwLDAsMSw5MC42OSwxMi4yMlpNMTUuMTMsMjYuNzVIODQuODh2NjFhOC43Miw4LjcyLDAsMCwxLTguNzIsOC43MkgyMy44NGE4LjcyLDguNzIsMCwwLDEtOC43Mi04LjcyWk0yOS42Niw4MmEyLjkxLDIuOTEsMCwwLDAsNS44MSwwVjQxLjI4YTIuOTEsMi45MSwwLDAsMC01LjgxLDBabTE3LjQ0LDBhMi45MSwyLjkxLDAsMCwwLDUuODEsMFY0MS4yOGEyLjkxLDIuOTEsMCwwLDAtNS44MSwwWm0xNy40NCwwYTIuOTEsMi45MSwwLDAsMCw1LjgxLDBWNDEuMjhhMi45MSwyLjkxLDAsMCwwLTUuODEsMFoiPjwvcGF0aD48L3N2Zz4="); + background-repeat: no-repeat; + background-size: 24px 24px; + border: none; + opacity: 0.8; +} +.pin-zoom-modal-delete:hover{ + opacity: 1; +} + +.pin-zoom-modal-site-link { + position: fixed; + width: 24px; + height: 24px; + bottom: 20px; + right: 100px; + background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjRkZGRkZGIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczp4b2RtPSJodHRwOi8vd3d3LmNvcmVsLmNvbS9jb3JlbGRyYXcvb2RtLzIwMDMiIHhtbDpzcGFjZT0icHJlc2VydmUiIHZlcnNpb249IjEuMSIgc3R5bGU9InNoYXBlLXJlbmRlcmluZzpnZW9tZXRyaWNQcmVjaXNpb247dGV4dC1yZW5kZXJpbmc6Z2VvbWV0cmljUHJlY2lzaW9uO2ltYWdlLXJlbmRlcmluZzpvcHRpbWl6ZVF1YWxpdHk7IiB2aWV3Qm94PSIwIDAgMzIwIDMxOS45OSIgeD0iMHB4IiB5PSIwcHgiIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIj48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAKICAgIC5maWwwIHtmaWxsOiNGRkZGRkY7ZmlsbC1ydWxlOm5vbnplcm99CiAgIAogIDwvc3R5bGU+PC9kZWZzPjxnPjxwYXRoIGNsYXNzPSJmaWwwIiBkPSJNMTYwIDI4My4zM2MzNC4wNiwwIDY0LjksLTEzLjgxIDg3LjIxLC0zNi4xMiAyMi4zMSwtMjIuMzEgMzYuMTIsLTUzLjE2IDM2LjEyLC04Ny4yMSAwLC0zNC4wNiAtMTMuODEsLTY0Ljg5IC0zNi4xMiwtODcuMjEgLTIyLjMxLC0yMi4zMSAtNTMuMTYsLTM2LjEzIC04Ny4yMSwtMzYuMTMgLTM0LjA2LDAgLTY0LjksMTMuODEgLTg3LjIxLDM2LjEzIC0yMi4zMSwyMi4zMSAtMzYuMTMsNTMuMTUgLTM2LjEzLDg3LjIxIDAsMzQuMDYgMTMuODEsNjQuOSAzNi4xMyw4Ny4yMSAyMi4zMSwyMi4zMSA1My4xNSwzNi4xMiA4Ny4yMSwzNi4xMnptMTAxLjM1IC0yMS45OGMtMjUuOTQsMjUuOTMgLTYxLjc4LDQxLjk4IC0xMDEuMzUsNDEuOTggLTM5LjU4LDAgLTc1LjQyLC0xNi4wNSAtMTAxLjM1LC00MS45OCAtMjUuOTQsLTI1Ljk0IC00MS45OCwtNjEuNzggLTQxLjk4LC0xMDEuMzUgMCwtMzkuNTggMTYuMDUsLTc1LjQyIDQxLjk4LC0xMDEuMzUgMjUuOTMsLTI1Ljk0IDYxLjc3LC00MS45OCAxMDEuMzUsLTQxLjk4IDM5LjU4LDAgNzUuNDIsMTYuMDUgMTAxLjM1LDQxLjk4IDI1LjkzLDI1LjkzIDQxLjk4LDYxLjc3IDQxLjk4LDEwMS4zNSAwLDM5LjU4IC0xNi4wNSw3NS40MiAtNDEuOTgsMTAxLjM1eiI+PC9wYXRoPjxwYXRoIGNsYXNzPSJmaWwwIiBkPSJNMjYuNjYgMTY5Ljg2Yy01LjUsMCAtOS45NiwtNC40NiAtOS45NiwtOS45NiAwLC01LjUgNC40NiwtOS45NiA5Ljk2LC05Ljk2bDI2Ni42NyAtMS4wNGM1LjUsMCA5Ljk2LDQuNDYgOS45Niw5Ljk2IDAsNS41IC00LjQ2LDkuOTYgLTkuOTYsOS45NmwtMjY2LjY3IDEuMDR6Ij48L3BhdGg+PHBhdGggY2xhc3M9ImZpbDAiIGQ9Ik0xNDkuNTIgMjYuNjZjMCwtNS41IDQuNDYsLTkuOTYgOS45NiwtOS45NiA1LjUsMCA5Ljk2LDQuNDYgOS45Niw5Ljk2bDEuMDQgMjY2LjY3YzAsNS41IC00LjQ2LDkuOTYgLTkuOTYsOS45NiAtNS41LDAgLTkuOTYsLTQuNDYgLTkuOTYsLTkuOTZsLTEuMDQgLTI2Ni42N3oiPjwvcGF0aD48cGF0aCBjbGFzcz0iZmlsMCIgZD0iTTE2MCAyODMuMzNjMTQuMzIsMCAyNy44OSwtMTIuODEgMzguMjQsLTMzLjUxIDExLjM5LC0yMi43NyAxOC40MywtNTQuNTIgMTguNDMsLTg5LjgzIDAsLTM1LjMxIC03LjA1LC02Ny4wNiAtMTguNDMsLTg5LjgzIC0xMC4zNSwtMjAuNyAtMjMuOTEsLTMzLjUxIC0zOC4yNCwtMzMuNTEgLTE0LjMyLDAgLTI3Ljg5LDEyLjgxIC0zOC4yNCwzMy41MSAtMTEuMzksMjIuNzcgLTE4LjQzLDU0LjUyIC0xOC40Myw4OS44MyAwLDM1LjMxIDcuMDUsNjcuMDYgMTguNDMsODkuODMgMTAuMzUsMjAuNyAyMy45MSwzMy41MSAzOC4yNCwzMy41MXptNTYuMDUgLTI0LjZjLTEzLjc3LDI3LjU2IC0zMy41NSw0NC42IC01Ni4wNSw0NC42IC0yMi41LDAgLTQyLjI4LC0xNy4wNSAtNTYuMDUsLTQ0LjYgLTEyLjc0LC0yNS40NyAtMjAuNjIsLTYwLjQxIC0yMC42MiwtOTguNzMgMCwtMzguMzMgNy44OCwtNzMuMjYgMjAuNjIsLTk4LjczIDEzLjc3LC0yNy41NiAzMy41NSwtNDQuNiA1Ni4wNSwtNDQuNiAyMi41LDAgNDIuMjgsMTcuMDUgNTYuMDUsNDQuNiAxMi43NCwyNS40NyAyMC42Miw2MC40MSAyMC42Miw5OC43MyAwLDM4LjMzIC03Ljg4LDczLjI2IC0yMC42Miw5OC43M3oiPjwvcGF0aD48cGF0aCBjbGFzcz0iZmlsMCIgZD0iTTQ1LjcgMTA0LjA0Yy01LjUsMC4wMiAtOS45OCwtNC40MiAtMTAsLTkuOTIgLTAuMDIsLTUuNSA0LjQyLC05Ljk4IDkuOTIsLTEwbDIyOC42OCAtMS4wNGM1LjUsLTAuMDIgOS45OCw0LjQyIDEwLDkuOTIgMC4wMiw1LjUgLTQuNDIsOS45OCAtOS45MiwxMGwtMjI4LjY4IDEuMDR6Ij48L3BhdGg+PHBhdGggY2xhc3M9ImZpbDAiIGQ9Ik00NS43IDIzNy40MmMtNS41LDAuMDIgLTkuOTgsLTQuNDIgLTEwLC05LjkyIC0wLjAyLC01LjUgNC40MiwtOS45OCA5LjkyLC0xMGwyMjguNjggLTEuMDRjNS41LC0wLjAyIDkuOTgsNC40MiAxMCw5LjkyIDAuMDIsNS41IC00LjQyLDkuOTggLTkuOTIsMTBsLTIyOC42OCAxLjA0eiI+PC9wYXRoPjwvZz48L3N2Zz4="); + background-repeat: no-repeat; + background-size: 24px 24px; + border: none; + opacity: 0.8; +} + +.pin-zoom-modal-site-link:hover{ + opacity: 1; +} + +.pin-zoom-modal-edit { + position: fixed; + width: 24px; + height: 24px; + bottom: 20px; + right: 60px; + background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjRkZGRkZGIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHg9IjBweCIgeT0iMHB4Ij48dGl0bGU+NTE8L3RpdGxlPjxwYXRoIGQ9Ik04NC44NTAxMiw1MFY4MS43NDUxMkExMy4yNzAxMiwxMy4yNzAxMiwwLDAsMSw3MS41OTUyNCw5NUgxOC4yNTQ5MUExMy4yNzAxMiwxMy4yNzAxMiwwLDAsMSw1LDgxLjc0NTEyVjI4LjQwNTI4QTEzLjI3MDEyLDEzLjI3MDEyLDAsMCwxLDE4LjI1NDkxLDE1LjE1MDRINTBhMi41LDIuNSwwLDAsMSwwLDVIMTguMjU0OTFBOC4yNjQyMyw4LjI2NDIzLDAsMCwwLDEwLDI4LjQwNTI4VjgxLjc0NTEyQTguMjY0MjQsOC4yNjQyNCwwLDAsMCwxOC4yNTQ5MSw5MEg3MS41OTUyNGE4LjI2NDIzLDguMjY0MjMsMCwwLDAsOC4yNTQ4OC04LjI1NDg5VjUwYTIuNSwyLjUsMCwwLDEsNSwwWk04OS4xNDg0Niw2LjIzNzkyYTQuMjI2NjEsNC4yMjY2MSwwLDAsMC01Ljk3NzI5LDBsLTMzLjk2MjksMzMuOTYzTDU5Ljc5OTE2LDUwLjc5MTc2bDMzLjk2Mjg5LTMzLjk2M2E0LjIyNjUzLDQuMjI2NTMsMCwwLDAsMC01Ljk3NzIzWk00My42MjM4LDU4LjMxMjg3bDEzLjAwOTQtNC4zNTUxNkw0Ni4wNDIyNiw0My4zNjY4M2wtNC4zNTUxLDEzLjAwOTRBMS41MzAwNSwxLjUzMDA1LDAsMCwwLDQzLjYyMzgsNTguMzEyODdaIj48L3BhdGg+PC9zdmc+"); + background-repeat: no-repeat; + background-size: 24px 24px; + border: none; + opacity: 0.8; +} + +.pin-zoom-modal-edit { + opacity: 1; +} + +#loader:after { + border-left-color: #3273dc; + border-bottom-color: #3273dc; } \ No newline at end of file diff --git a/static/client.js b/static/client.js index 459a9fe..8e108ed 100644 --- a/static/client.js +++ b/static/client.js @@ -2,27 +2,94 @@ Reef.debug(true); const store = new Reef.Store({ data: { + hash: { + board: null + }, + loading: false, boards: [], board: null, addPin: { active: false, boardId: "", + newBoardName: null, imageUrl: "", previewReady: false, previewImageUrl: null, siteUrl: "", - description: "" + description: "", + saveInProgress: false }, pinZoom: { active: false, - pinId: null + pin: null }, about: { active: false + }, + editBoard: { + active: false, + name: "" + } + }, + getters: { + isAddPinValid: (data) => { + + if ( data.addPin.boardId == "new"){ + if ( !data.addPin.newBoardName ){ + return false; + } else if ( data.addPin.newBoardName.trim().length < 1 ){ + return false; + } + } + + if ( !data.addPin.previewImageUrl ){ + return false; + } + + return true; + }, + isEditBoardValid: (data) => { + if (!data.editBoard.name){ + return false; + } + + if ( data.editBoard.name.trim().length < 1 ){ + return false; + } + + return true; } } }); +function getBoardIndexById(id){ + let idx = -1; + for ( let i = 0; i < store.data.boards.length; ++i ){ + if ( store.data.boards[i].id == id ){ + idx = i; + } + } + return idx; +} + +function getBoardById(id){ + return store.data.boards[getBoardIndexById(id)]; +} + +function getPinIndexById(id){ + let idx = -1; + for ( let i = 0; i < store.data.board.pins.length; ++i ){ + if ( store.data.board.pins[i].id == id ){ + idx = i; + } + } + return idx; +} + +function getPinById(id){ + return store.data.board.pins[getPinIndexById(id)]; +} + const actions = { openAddPinModal: () => { @@ -31,7 +98,7 @@ const actions = { } else if ( store.data.boards && store.data.boards.length > 0 ){ store.data.addPin.boardId = store.data.boards[0].id; } else { - store.data.addPin.boardId = 0; + store.data.addPin.boardId = "new"; } store.data.addPin.active = true; @@ -42,11 +109,35 @@ const actions = { store.data.addPin.previewImageUrl = ""; store.data.addPin.siteUrl = ""; store.data.addPin.description = ""; + store.data.addPin.newBoardName = ""; + store.data.addPin.saveInProgress = false; }, saveAddPin: async () => { + store.data.addPin.saveInProgress = true; + + let boardId = store.data.addPin.boardId; + + let newBoard = null; + + if ( boardId == "new" ){ + let res = await fetch('api/boards', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + "name": store.data.addPin.newBoardName + }) + }); + + if ( res.status == 200 ){ + newBoard = await res.json(); + boardId = newBoard.id; + store.data.boards.push(newBoard); + } + } + let postData = { - boardId: store.data.addPin.boardId, + boardId: boardId, imageUrl: store.data.addPin.imageUrl, siteUrl: store.data.addPin.siteUrl, description: store.data.addPin.description @@ -61,11 +152,19 @@ const actions = { }); if ( res.status == 200 ){ - actions.closeAddPinModal(); - + let body = await res.json(); - store.data.board.pins.push(body); - } + if ( store.data.board && store.data.board.id == boardId ){ + store.data.board.pins.push(body); + } + + if ( newBoard ){ + newBoard.titlePinId = body.id; + } + + actions.closeAddPinModal(); + } + }, updateAddPinPreview: () => { if ( store.data.addPin.imageUrl.startsWith("http") ){ @@ -87,7 +186,7 @@ const actions = { let pinId = el.getAttribute("data-pinid"); if( pinId ){ - store.data.pinZoom.pinId = pinId; + store.data.pinZoom.pin = getPinById(pinId); store.data.pinZoom.active = true; } @@ -98,29 +197,47 @@ const actions = { }, movePinZoomModalLeft: () => { - let idx = 0; - for ( let i = 0; i < store.data.board.pins.length; ++i ){ - if ( store.data.board.pins[i].id == store.data.pinZoom.pinId ){ - idx = i; - } - } + let idx = getPinIndexById(store.data.pinZoom.pin.id); if ( idx > 0 ){ - store.data.pinZoom.pinId = store.data.board.pins[idx-1].id; + store.data.pinZoom.pin = store.data.board.pins[idx-1]; } }, movePinZoomModalRight: () => { - let idx = -1; - for ( let i = 0; i < store.data.board.pins.length; ++i ){ - if ( store.data.board.pins[i].id == store.data.pinZoom.pinId ){ - idx = i; - } - } - + let idx = getPinIndexById(store.data.pinZoom.pin.id); + if ( idx >= 0 && (idx < store.data.board.pins.length-1) ){ - store.data.pinZoom.pinId = store.data.board.pins[idx+1].id + store.data.pinZoom.pin = store.data.board.pins[idx+1]; + } + }, + deletePin: async () => { + if ( confirm("Are you sure you want to delete this pin?") ){ + + store.data.loading++; + + let pinId = store.data.pinZoom.pin.id; + + let idx = getPinIndexById(pin.id); + if ( idx >= 0 ){ + store.data.board.pins.splice(idx,1); + } + + actions.closePinZoomModal(); + + let res = await fetch(`/api/pins/${pinId}`, { + method: "DELETE" + }); + + if ( res.status == 200 ){ + console.log(`deleted pin#${pinId}`); + } else { + console.error(`error deleting pin#${pinId}`); + } + + store.data.loading--; + } }, showAboutModal: () => { @@ -128,12 +245,85 @@ const actions = { }, closeAboutModal: () => { store.data.about.active = false; + }, + openEditBoardModal: () => { + store.data.editBoard.name = store.data.board.name; + store.data.editBoard.active = true; + }, + closeEditBoardModal: () => { + store.data.editBoard.name = ""; + store.data.editBoard.active = false; + }, + saveEditBoard: async () => { + + store.data.loading++ + + let boardId = store.data.board.id; + let name = store.data.editBoard.name; + + let idx = getBoardIndexById(boardId); + console.log("idx=" + idx); + if ( idx >= 0 ){ + store.data.boards[idx].name = name; + store.data.board.name = name; + } + + let res = await fetch(`/api/boards/${boardId}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: name + }) + }); + + if ( res.status == 200 ){ + console.log(`updated board#${boardId}`); + store.data.editBoard.active = false; + } else { + console.error(`error updating board#${boardId}`); + } + + + store.data.loading--; + }, + editBoardDelete: async () => { + + if ( !confirm("Are you sure you want to delete this board and all pins on it?") ){ + return; + } + + store.data.loading++; + + let boardId = store.data.board.id; + + + let idx = getBoardIndexById(boardId); + if ( idx >= 0 ){ + store.data.boards.splice(idx, 1); + } + store.data.editBoard.active = false; + window.location.hash = ""; + + + let res = await fetch(`/api/boards/${boardId}`, { + method: 'DELETE' + }); + + if ( res.status == 200 ){ + console.log(`deleted board#${boardId}`); + } else { + console.log(`error deleting board#${boardId}`); + } + + store.data.loading--; } } const app = new Reef("#app", { store: store, - template: (store) => { + template: (data) => { return /*html*/`
@@ -142,79 +332,47 @@ const app = new Reef("#app", {
+
` } }); -const aboutModal = new Reef("#about-modal", { - store: store, - template: (data) => { - return /*html*/` - - `; - }, - attachTo: app -}); - const navbar = new Reef("#navbar", { store: store, template: (data) => { + let boardName = ""; + + if ( data.board ){ + boardName = /*html*/` + ${data.board.name}   + edit + `; + } else if ( !data.hash.board ) { + boardName = /*html*/`Boards`; + } + return /*html*/`