diff --git a/client/.gitignore b/client/.gitignore index 2107e24..82e2467 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -12,6 +12,7 @@ package-lock.json dist dist-ssr *.local +*.env # Editor directories and files .vscode/* diff --git a/client/package.json b/client/package.json index 0b52fb1..b6f5742 100644 --- a/client/package.json +++ b/client/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "axios": "^1.3.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -18,4 +19,4 @@ "@vitejs/plugin-react": "^3.0.0", "vite": "^4.0.0" } -} \ No newline at end of file +} diff --git a/client/src/App.jsx b/client/src/App.jsx index ef0adc0..5b44e06 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,32 +1,52 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' +import { useEffect, useState } from 'react'; +import Home from './pages/Home' +import API from './util/API'; import './App.css' +import Auth from './pages/Auth'; function App() { - const [count, setCount] = useState(0) + const [user, setUser] = useState(null); + const [contents, setContents] = useState(); + + useEffect(() => { + (async() => { + const res = await API.validate(); + console.log(res); + + if (res.user) { + setUser(res.user); + } else { + setUser(null); + } + })(); + }, []) + + useEffect(() => { + setContents(user ? : ); + }, [user]); + + async function handleLogout() { + await API.logout(); + setUser(null); + } + + async function handleLogin(info) { + const res = await API.login(info); + if (res.data) setUser(res.data); + return; + } + + async function handleRegister(info) { + const res = await API.register(info); + console.log(res); + return; + } return (
-
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.jsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

+

Auth Testing

+ + { contents }
) } diff --git a/client/src/components/Form.jsx b/client/src/components/Form.jsx new file mode 100644 index 0000000..259afcc --- /dev/null +++ b/client/src/components/Form.jsx @@ -0,0 +1,33 @@ +export function LoginForm({ info, setInfo }) { + return ( +
+
+ + setInfo({ ...info, email: e.target.value })} /> +
+
+ + setInfo({ ...info, password: e.target.value })} /> +
+
+ ) +} + +export function RegisterForm({ info, setInfo }) { + return ( +
+
+ + setInfo({ ...info, username: e.target.value })} /> +
+
+ + setInfo({ ...info, email: e.target.value })} /> +
+
+ + setInfo({ ...info, password: e.target.value })} /> +
+
+ ) +} \ No newline at end of file diff --git a/client/src/components/Page.jsx b/client/src/components/Page.jsx new file mode 100644 index 0000000..dbcf759 --- /dev/null +++ b/client/src/components/Page.jsx @@ -0,0 +1,7 @@ +export default function Page({ classes = "", children = <> }) { + return ( +
+ { children } +
+ ) +} \ No newline at end of file diff --git a/client/src/pages/Auth.jsx b/client/src/pages/Auth.jsx new file mode 100644 index 0000000..ad8eedb --- /dev/null +++ b/client/src/pages/Auth.jsx @@ -0,0 +1,54 @@ +import { useEffect, useState } from "react"; +import { LoginForm, RegisterForm } from "../components/Form"; + +function Auth({ handleLogin, handleRegister }) { + const [info, setInfo] = useState({ username: "", email: "", password: "" }); + const [mode, setMode] = useState("login"); + const [form, setForm] = useState(); + const [button, setButton] = useState( + <> + + + + ); + + useEffect(() => { + console.log(mode); + }, [info]); + + function swapForm() { + if (mode === "register") { + setMode("login"); + setForm(); + setButton( + <> + + + + ) + } else { + setMode("register"); + setForm(); + setButton( + <> + + + + ); + } + } + + return ( +
+ + + {/* */} + + + + {/* */} +
+ ) +} + +export default Auth \ No newline at end of file diff --git a/client/src/pages/Home.jsx b/client/src/pages/Home.jsx new file mode 100644 index 0000000..e285367 --- /dev/null +++ b/client/src/pages/Home.jsx @@ -0,0 +1,38 @@ +import { useEffect, useState } from "react"; +import API from "../util/API"; + +function Home({ user, handleLogout }) { + const [items, setItems] = useState(null); + console.log(user); + + useEffect(() => { + if (user) { + (async() => { + const myItems = await API.getItems(); + + setItems(myItems.map(each => <>{each.id})); + })(); + } else { + setItems(null); + } + + }, []) + + async function getStatus() { + const res = await API.validate(); + console.log(res); + } + + return ( +
+

Testing user auth workflow with PERN stack

+ + + { items } + + +
+ ) +} + +export default Home \ No newline at end of file diff --git a/client/src/util/API.js b/client/src/util/API.js new file mode 100644 index 0000000..d4dbab2 --- /dev/null +++ b/client/src/util/API.js @@ -0,0 +1,48 @@ +import axiosInstance from './axiosInstance'; +const _api = axiosInstance(); + +export default class API { + static async validate() { + try { + const response = await _api.get('/'); + const data = Promise.resolve(response.data); + console.log(data); + return data; + } catch (error) { + console.log(error); + } + } + + static async login(data) { + try { + const response = await _api.post('/auth/login', data); + return Promise.resolve(response.data); + } catch(err) { + console.log(err); + } + } + + static async logout() { + try { + const response = await _api.delete('/auth/logout'); + console.log(response); + return Promise.resolve(response.data); + } catch(err) { + console.log(err); + } + } + + static async register(data) { + try { + const response = await _api.post('/auth/register', data); + return Promise.resolve(response.data); + } catch(err) { + console.log(err); + } + } + + static async getItems() { + const response = await _api.get('/app/item'); + return Promise.resolve(response.data); + } +} \ No newline at end of file diff --git a/client/src/util/axiosInstance.js b/client/src/util/axiosInstance.js new file mode 100644 index 0000000..eded926 --- /dev/null +++ b/client/src/util/axiosInstance.js @@ -0,0 +1,11 @@ +import axios from 'axios' + +const apiUrl = import.meta.env.VITE_APIURL; + +export default function axiosInstance() { + if (!apiUrl) { + throw new Error("API URL not found"); + } + + return axios.create({ baseURL: apiUrl }); +} \ No newline at end of file diff --git a/server/loaders/express.js b/server/loaders/express.js index bbea930..8335178 100644 --- a/server/loaders/express.js +++ b/server/loaders/express.js @@ -8,7 +8,7 @@ require('dotenv').config(); const secret = process.env.SECRET; async function expressLoader(app) { - app.use(cors()); + app.use(cors({ origin: "http://localhost:5173" })); app.use(express.json()); app.use(express.urlencoded({ extended: true }));