diff --git a/client/src/pages/account.tsx b/client/src/pages/account.tsx index 37341f5..2f9f271 100644 --- a/client/src/pages/account.tsx +++ b/client/src/pages/account.tsx @@ -5,14 +5,17 @@ import {SAPIBase} from "../tools/api"; import "./css/account.css"; const AccountPage = () => { - const [ SAPIKEY, setSAPIKEY ] = React.useState(""); + //const [ SAPIKEY, setSAPIKEY ] = React.useState(""); + const [ SAPIID, setSAPIID ] = React.useState(""); + const [ SAPIPW, setSAPIPW ] = React.useState(""); const [ NBalance, setNBalance ] = React.useState("Not Authorized"); const [ NTransaction, setNTransaction ] = React.useState(0); const getAccountInformation = () => { const asyncFun = async() => { interface IAPIResponse { balance: number }; - const { data } = await axios.post(SAPIBase + '/account/getInfo', { credential: SAPIKEY }); + //const { data } = await axios.post(SAPIBase + '/account/getInfo', { credential: SAPIKEY }); + const { data } = await axios.post(SAPIBase + '/account/getInfo', { ID: SAPIID, PW: SAPIPW }); setNBalance(data.balance); } asyncFun().catch((e) => window.alert(`AN ERROR OCCURED: ${e}`)); @@ -22,7 +25,8 @@ const AccountPage = () => { const asyncFun = async() => { if (amount === '') return; interface IAPIResponse { success: boolean, balance: number, msg: string }; - const { data } = await axios.post(SAPIBase + '/account/transaction', { credential: SAPIKEY, amount: amount }); + //const { data } = await axios.post(SAPIBase + '/account/transaction', { credential: SAPIKEY, amount: amount }); + const { data } = await axios.post(SAPIBase + '/account/transaction', { ID: SAPIID, PW: SAPIPW, amount: amount }); setNTransaction(0); if (!data.success) { window.alert('Transaction Failed:' + data.msg); @@ -39,16 +43,21 @@ const AccountPage = () => {

Account

-
- Enter API Key: setSAPIKEY(e.target.value)}/> - -
+ +

The National Bank of SPARCS API

Current Balance

= 0 ? "balance-positive" : "balance-negative") : "")}>₩ { NBalance }

+
+ Enter your ID: setSAPIID(e.target.value)}/> +
+
+ Enter your Password: setSAPIPW(e.target.value)}/> +
+
setNTransaction(e.target.value === '' ? '' : parseInt(e.target.value))}/> diff --git a/client/src/pages/feed.tsx b/client/src/pages/feed.tsx index b64c53b..7a162ce 100644 --- a/client/src/pages/feed.tsx +++ b/client/src/pages/feed.tsx @@ -4,7 +4,7 @@ import { SAPIBase } from "../tools/api"; import Header from "../components/header"; import "./css/feed.css"; -interface IAPIResponse { id: number, title: string, content: string } +interface IAPIResponse { id: number, title: string, content: string, rating: number } const FeedPage = (props: {}) => { const [ LAPIResponse, setLAPIResponse ] = React.useState([]); @@ -38,11 +38,40 @@ const FeedPage = (props: {}) => { const deletePost = (id: string) => { const asyncFun = async () => { // One can set X-HTTP-Method header to DELETE to specify deletion as well - await axios.post( SAPIBase + '/feed/deleteFeed', { id: id } ); - setNPostCount(Math.max(NPostCount - 1, 0)); + const confirmed =window.confirm("Really want to DELETE ?!?!"); + if (confirmed){ + await axios.post( SAPIBase + '/feed/deleteFeed', { id: id } ); + setNPostCount(Math.max(NPostCount - 1, 0));} } asyncFun().catch(e => window.alert(`AN ERROR OCCURED! ${e}`)); } + const editPost = (id: string, newTitle: string, newContent: string) => { + const asyncFun = async () => { + await axios.post( SAPIBase + '/feed/editFeed', { id: id, title: newTitle, content: newContent } ); + const updatedPosts = LAPIResponse.map( (val) => { + if (val.id === parseInt(id)) { + val.title = newTitle; + val.content = newContent; + } + return val; + }); + setLAPIResponse(updatedPosts); + } + asyncFun().catch(e => window.alert(`AN ERROR OCCURED! ${e}`)); + } + const ratePost = (id: string, rating: number) => { + const asyncFun = async () => { + await axios.post( SAPIBase + '/feed/rateFeed', { id: id, rating: rating } ); + const updatedPosts = LAPIResponse.map( (val) => { + if (val.id === parseInt(id)) { + val.rating = rating; + } + return val; + }); + setLAPIResponse(updatedPosts); + } + asyncFun().catch(e => window.alert(`AN ERROR OCCURRED! ${e}`)); + } return (
@@ -57,11 +86,30 @@ const FeedPage = (props: {}) => {
{ LAPIResponse.map( (val, i) =>
+
+ { const editedTitle = window.prompt("Edit the title to ~ ", val.title); + const editedContent = window.prompt("Edit the content to ~", val.content); + if (editedContent&& editedTitle) editPost(`${val.id}`, editedTitle, editedContent); + }}>Press here to Edit !
deletePost(`${val.id}`)}>ⓧ

{ val.title }

{ val.content }

+
+ Rating: {val.rating} + {[1, 2, 3, 4, 5].map((ratingValue) => ( + ratePost(`${val.id}`, ratingValue)} + > + {ratingValue <= val.rating ? "★" : "☆"} + + ))} +
+ ) } +
Title: setSNewPostTitle(e.target.value)}/>      diff --git a/seminar/.env.example b/seminar/.env.example index f84e5b2..b425892 100644 --- a/seminar/.env.example +++ b/seminar/.env.example @@ -1,3 +1,5 @@ PORT=8080 NODE_ENV=DEVELOPMENT -API_KEY= \ No newline at end of file +API_KEY= +API_ID=oosoi +API_PW=OOSOI diff --git a/seminar/index.js b/seminar/index.js new file mode 100644 index 0000000..9343dad --- /dev/null +++ b/seminar/index.js @@ -0,0 +1,30 @@ +const express = require('express'); +const cors = require('cors'); +const app = express(); +const port = 8080; + +app.use(express.json()); + +const whitelist = ['http://localhost:3000']; +const corsOptions = { + origin: (origin, callback) => { + console.log('[REQUEST-CORS] Request from origin: ', origin); + if (!origin || whitelist.indexOf(origin) !== -1) callback(null, true) + else callback(new Error('Not Allowed by CORS')); + }, + credentials: true, +} + +app.use(cors(corsOptions)); + +app.get('/', (req, res) => { + res.status(200).send('Hello, World!'); +}); + +app.get('/status', (req, res) => { + res.status(200).json({ isOnline: true }); +}) + +app.listen(port, () => { + console.log(`Example App Listening @ http://localhost:${ port }`); +}); diff --git a/seminar/src/middleware/auth.js b/seminar/src/middleware/auth.js index 480f41d..3d13f27 100644 --- a/seminar/src/middleware/auth.js +++ b/seminar/src/middleware/auth.js @@ -1,12 +1,10 @@ const authMiddleware = (req, res, next) => { - if (req.body.credential === process.env.API_KEY) { + const {ID, PW }=req.body; + if (ID === process.env.API_ID && PW === process.env.API_PW){ console.log("[AUTH-MIDDLEWARE] Authorized User"); next(); } - else { - console.log("[AUTH-MIDDLEWARE] Not Authorized User"); - res.status(401).json({ error: "Not Authorized" }); - } + } module.exports = authMiddleware; \ No newline at end of file diff --git a/seminar/src/routes/feed.js b/seminar/src/routes/feed.js index f9c19d9..d696fc9 100644 --- a/seminar/src/routes/feed.js +++ b/seminar/src/routes/feed.js @@ -36,6 +36,23 @@ class FeedDB { if (BItemDeleted) id--; return BItemDeleted; } + + editItem=(id, title, content)=> { + this.#LDataDB =this.#LDataDB.map((value)=>{ + if(value.id===id) { + value.title =title; + value.content =content; + } + return value; + }) + } + rateItem = (id, rating) => { + const itemToUpdate = this.#LDataDB.find(item => item.id === id); + if (!itemToUpdate) return false; + itemToUpdate.rating = rating; + return true; + }; + } const feedDBInst = FeedDB.getInst(); @@ -72,5 +89,25 @@ router.post('/deleteFeed', (req, res) => { return res.status(500).json({ error: e }); } }) +router.post('/editFeed', (req, res) => { + try { + const { id, title, content } = req.body; + feedDBInst.editItem(parseInt(id), title, content); + return res.status(200).json({ isOK: true }); + } catch (e) { + return res.status(500).json({ error: e }); + } +}) +router.post('/rateFeed', (req, res) => { + try { + const { id, rating } = req.body; + const updateResult = feedDBInst.rateItem(parseInt(id), rating); + if (!updateResult) return res.status(500).json({ error: "Failed to update rating" }); + else return res.status(200).json({ isOK: true }); + } catch (e) { + return res.status(500).json({ error: e }); + } +}); + module.exports = router; \ No newline at end of file