diff --git a/dmwt_session10/package-lock.json b/dmwt_session10/package-lock.json index b2de4bee1cc751c89a86aa9bb4efaa88174946c1..1d8c547fa2648ffd28f981832c535ea2f5ee897c 100644 --- a/dmwt_session10/package-lock.json +++ b/dmwt_session10/package-lock.json @@ -9,8 +9,9 @@ "version": "0.1.0", "dependencies": { "next": "14.2.3", - "react": "^18", - "react-dom": "^18" + "react": "^18.3.1", + "react-dom": "^18.3.1", + "swr": "^2.2.5" }, "devDependencies": { "eslint": "^8", @@ -4272,6 +4273,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", + "dependencies": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/tailwindcss": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", @@ -4527,6 +4540,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/dmwt_session10/package.json b/dmwt_session10/package.json index 3c922178e1d6941cb407249c3d16a47a159db49d..bb2e5d0fc182f2175c59fe1d3b30f46ca840594e 100644 --- a/dmwt_session10/package.json +++ b/dmwt_session10/package.json @@ -9,14 +9,15 @@ "lint": "next lint" }, "dependencies": { - "react": "^18", - "react-dom": "^18", - "next": "14.2.3" + "next": "14.2.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "swr": "^2.2.5" }, "devDependencies": { - "postcss": "^8", - "tailwindcss": "^3.4.1", "eslint": "^8", - "eslint-config-next": "14.2.3" + "eslint-config-next": "14.2.3", + "postcss": "^8", + "tailwindcss": "^3.4.1" } } diff --git a/dmwt_session10/public/next.svg b/dmwt_session10/public/next.svg deleted file mode 100644 index 5174b28c565c285e3e312ec5178be64fbeca8398..0000000000000000000000000000000000000000 --- a/dmwt_session10/public/next.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg> \ No newline at end of file diff --git a/dmwt_session10/public/vercel.svg b/dmwt_session10/public/vercel.svg deleted file mode 100644 index d2f84222734f27b623d1c80dda3561b04d1284af..0000000000000000000000000000000000000000 --- a/dmwt_session10/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg> \ No newline at end of file diff --git a/dmwt_session10/src/components/AddFruit.js b/dmwt_session10/src/components/AddFruit.js new file mode 100644 index 0000000000000000000000000000000000000000..4294ab23b6ddf2a877338d162f3fcdcb72c9e3aa --- /dev/null +++ b/dmwt_session10/src/components/AddFruit.js @@ -0,0 +1,90 @@ +import React, { useState } from 'react'; + +const AddFruit = () => { + const [germanName, setGermanName] = useState(''); + const [latinName, setLatinName] = useState(''); + const [color, setColor] = useState(''); + const [origin, setOrigin] = useState(''); + const [calories, setCalories] = useState(''); + + const handleSubmit = async (e) => { + e.preventDefault(); + + const newFruit = { + germanName, + latinName, + color, + origin, + calories, + }; + + const response = await fetch('/api/add-fruit', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(newFruit), + }); + + if (!response.ok) { + console.error('Failed to add fruit'); + return; + } + + const data = await response.json(); + console.log(JSON.stringify(data)); + }; + + return ( + <form onSubmit={handleSubmit}> + <div> + <label htmlFor="germanName">German Name</label> + <input + id="germanName" + type="text" + value={germanName} + onChange={(e) => setGermanName(e.target.value)} + /> + </div> + <div> + <label htmlFor="latinName">Latin Name</label> + <input + id="latinName" + type="text" + value={latinName} + onChange={(e) => setLatinName(e.target.value)} + /> + </div> + <div> + <label htmlFor="color">Color</label> + <input + id="color" + type="text" + value={color} + onChange={(e) => setColor(e.target.value)} + /> + </div> + <div> + <label htmlFor="origin">Origin</label> + <input + id="origin" + type="text" + value={origin} + onChange={(e) => setOrigin(e.target.value)} + /> + </div> + <div> + <label htmlFor="calories">Calories</label> + <input + id="calories" + type="text" + value={calories} + onChange={(e) => setCalories(e.target.value)} + /> + </div> + <button type="submit">Submit</button> + </form> + ); +}; + +export default AddFruit; diff --git a/dmwt_session10/src/components/FruitList.js b/dmwt_session10/src/components/FruitList.js new file mode 100644 index 0000000000000000000000000000000000000000..2cd0bedbe57e936e31fd0f5328f8d9e8399de261 --- /dev/null +++ b/dmwt_session10/src/components/FruitList.js @@ -0,0 +1,35 @@ +import React from 'react'; +import useSWR from 'swr'; + +const fetcher = url => fetch(url).then(res => res.json()); + +const FruitList = () => { + const { data: fruits, isLoading, error } = useSWR('/api/list-fruits', fetcher, { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }); + + if (error) { + return <p>Failed to fetch</p>; + } + + if (isLoading) { + return <p>Loading fruits...</p>; + } + + return ( + <ul> + {fruits && fruits.length > 0 ? ( + fruits.map((fruit, index) => ( + <li key={index}> + {fruit.germanName} ({fruit.latinName}), {fruit.color}, {fruit.origin}, {fruit.calories} kcal + </li> + )) + ) : ( + <li>No fruits available</li> + )} + </ul> + ); +}; + +export default FruitList; diff --git a/dmwt_session10/src/pages/API/add-fruit.js b/dmwt_session10/src/pages/API/add-fruit.js index 6483780878402c3d7a51d1b3c8bbee3891240ffb..3e204d4bacf627ce0f2a92096f539b4138dca11b 100644 --- a/dmwt_session10/src/pages/API/add-fruit.js +++ b/dmwt_session10/src/pages/API/add-fruit.js @@ -2,8 +2,8 @@ import { sql } from '@vercel/postgres'; export default async function handler(request, response) { try { - const { id, DeutscherName, LateinischerName, Farbe, Herkunft, Kalorien} = JSON.parse(request.body); - if (!id || !DeutscherName || !LateinischerName || !Farbe || !Herkunft || !Kalorien) throw new Error ('Irgendwas muss hier stehen') ; + const {DeutscherName, LateinischerName, Farbe, Herkunft, Kalorien} = JSON.parse(request.body); + if (!DeutscherName || !LateinischerName || !Farbe || !Herkunft || !Kalorien) throw new Error ('Irgendwas muss hier stehen') ; await sql `INSERT INTO Obst (id, Deutscher Name ,Lateinischer Name, Farbe, Herkunft, Kalorien) VALUES (${id}, ${DeutscherName}, ${LateinischerName}, ${Farbe}, ${Herkunft}, ${Kalorien});`; const Obst = await sql `SELECT * FROM Obst;`; return response.status(200).json(Obst.rows); diff --git a/dmwt_session10/src/pages/API/fruit-table.js b/dmwt_session10/src/pages/API/fruit-table.js index d61bb8cff5aa57973ee90b78724afa6636ce58b1..604a1f936b8096556ee6330cac5052bcb6fd9d38 100644 --- a/dmwt_session10/src/pages/API/fruit-table.js +++ b/dmwt_session10/src/pages/API/fruit-table.js @@ -4,7 +4,6 @@ export default async function handler(request, response) { const result = await sql `CREATE TABLE Obst ( - id int(11) NOT NULL, Deutscher Name varchar(50) NOT NULL, Lateinischer Name varchar(50) NOT NULL, Farbe varchar(50) NOT NULL, diff --git a/dmwt_session10/src/pages/API/list-fruits.js b/dmwt_session10/src/pages/API/list-fruits.js index 89d86960bba4d1911f0fe390dd3f86cfe4b88cfa..ac6b751646c755350aaafec2e6ff3c4cfac0c826 100644 --- a/dmwt_session10/src/pages/API/list-fruits.js +++ b/dmwt_session10/src/pages/API/list-fruits.js @@ -2,8 +2,8 @@ import { sql } from '@vercel/postgres' export default async function handler(request, response) { try { - const pets = await sql `SELECT * FROM Obst;`; - return response.status(200).json(pets.rows); + const fruits = await sql `SELECT * FROM Obst;`; + return response.status(200).json(fruits.rows); } catch (error) { return response.status(500).json({ error }) } diff --git a/dmwt_session10/src/pages/food.js b/dmwt_session10/src/pages/food.js index 11c3c3bf3b6fa074e071d648c31f19baa3df3c6a..dc7d2004480e215a5f7d62d6d3ba83744d48e5b3 100644 --- a/dmwt_session10/src/pages/food.js +++ b/dmwt_session10/src/pages/food.js @@ -1,10 +1,12 @@ - +import FruitList from '@/components/FruitList'; import Navbar from '../components/Navbar'; const Food = () => { return ( <div> <Navbar /> + <h1>Fruit List</h1> + <FruitList /> </div> ); diff --git a/dmwt_session10/src/pages/index.js b/dmwt_session10/src/pages/index.js index 7e50c71497f0a9fd65de99aede41b121f2bfaebf..20e9be71d1bee20019af2dddf08ad66304216143 100644 --- a/dmwt_session10/src/pages/index.js +++ b/dmwt_session10/src/pages/index.js @@ -1,10 +1,12 @@ +import AddFruit from '@/components/AddFruit'; import Navbar from '../components/Navbar'; const Home = () => { return ( <div> <Navbar /> - + <h1>Add a New Fruit</h1> + <AddFruit /> </div> ); }; diff --git a/dmwt_session10/src/pages/post.js b/dmwt_session10/src/pages/post.js new file mode 100644 index 0000000000000000000000000000000000000000..2d95c08ab9a2eec99639c288bb5b443a5ba3ad40 --- /dev/null +++ b/dmwt_session10/src/pages/post.js @@ -0,0 +1,119 @@ +import React, { useState } from 'react'; +import useSWR from 'swr'; + +const fetcher = url => fetch(url).then(res => res.json()); + +const Post = () => { + const [germanName, setGermanName] = useState(''); + const [latinName, setLatinName] = useState(''); + const [color, setColor] = useState(''); + const [origin, setOrigin] = useState(''); + const [calories, setCalories] = useState(''); + + const { data: fruits, isLoading, error } = useSWR('/api/list-fruits', fetcher, { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }); + + if (error) { + return <p>Failed to fetch</p>; + } + + if (isLoading) { + return <p>Loading fruits...</p>; + } + + const handleSubmit = async (e) => { + e.preventDefault(); + + const newFruit = { + germanName, + latinName, + color, + origin, + calories, + }; + + const response = await fetch('/api/add-fruit', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(newFruit), + }); + + if (!response.ok) { + console.error('Failed to add fruit'); + return; + } + + const data = await response.json(); + console.log(JSON.stringify(data)); + }; + + return ( + <div> + <form onSubmit={handleSubmit}> + <div> + <label htmlFor="germanName">German Name</label> + <input + id="germanName" + type="text" + value={germanName} + onChange={(e) => setGermanName(e.target.value)} + /> + </div> + <div> + <label htmlFor="latinName">Latin Name</label> + <input + id="latinName" + type="text" + value={latinName} + onChange={(e) => setLatinName(e.target.value)} + /> + </div> + <div> + <label htmlFor="color">Color</label> + <input + id="color" + type="text" + value={color} + onChange={(e) => setColor(e.target.value)} + /> + </div> + <div> + <label htmlFor="origin">Origin</label> + <input + id="origin" + type="text" + value={origin} + onChange={(e) => setOrigin(e.target.value)} + /> + </div> + <div> + <label htmlFor="calories">Calories</label> + <input + id="calories" + type="text" + value={calories} + onChange={(e) => setCalories(e.target.value)} + /> + </div> + <button type="submit">Submit</button> + </form> + <ul> + {fruits && fruits.length > 0 ? ( + fruits.map((fruit, index) => ( + <li key={index}> + {fruit.germanName} ({fruit.latinName}), {fruit.color}, {fruit.origin}, {fruit.calories} kcal + </li> + )) + ) : ( + <li>No fruits available</li> + )} + </ul> + </div> + ); +}; + +export default Post; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..3bb38a28ef41726cfcfd50ac825954d81af8866f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,257 @@ +{ + "name": "dmwt_season10_group_2", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@vercel/postgres": "^0.8.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "swr": "^2.2.5" + } + }, + "node_modules/@neondatabase/serverless": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.7.2.tgz", + "integrity": "sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==", + "dependencies": { + "@types/pg": "8.6.6" + } + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pg": { + "version": "8.6.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", + "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@vercel/postgres": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@vercel/postgres/-/postgres-0.8.0.tgz", + "integrity": "sha512-/QUV9ExwaNdKooRjOQqvrKNVnRvsaXeukPNI5DB1ovUTesglfR/fparw7ngo1KUWWKIVpEj2TRrA+ObRHRdaLg==", + "dependencies": { + "@neondatabase/serverless": "0.7.2", + "bufferutil": "4.0.8", + "utf-8-validate": "6.0.3", + "ws": "8.14.2" + }, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/swr": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", + "dependencies": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/utf-8-validate": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", + "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..baf52452f88589910981ed5683c7aed40a3fea3d --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "@vercel/postgres": "^0.8.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "swr": "^2.2.5" + } +}