connecting to front end

This commit is contained in:
Mikayla Dobson
2023-02-01 13:59:18 -06:00
parent 0d18c1041f
commit d09f4a6145
10 changed files with 238 additions and 25 deletions

1
client/.gitignore vendored
View File

@@ -12,6 +12,7 @@ package-lock.json
dist dist
dist-ssr dist-ssr
*.local *.local
*.env
# Editor directories and files # Editor directories and files
.vscode/* .vscode/*

View File

@@ -9,6 +9,7 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"axios": "^1.3.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0"
}, },
@@ -18,4 +19,4 @@
"@vitejs/plugin-react": "^3.0.0", "@vitejs/plugin-react": "^3.0.0",
"vite": "^4.0.0" "vite": "^4.0.0"
} }
} }

View File

@@ -1,32 +1,52 @@
import { useState } from 'react' import { useEffect, useState } from 'react';
import reactLogo from './assets/react.svg' import Home from './pages/Home'
import API from './util/API';
import './App.css' import './App.css'
import Auth from './pages/Auth';
function App() { 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 ? <Home user={user} handleLogout={handleLogout} /> : <Auth handleLogin={handleLogin} handleRegister={handleRegister} />);
}, [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 ( return (
<div className="App"> <div className="App">
<div> <h1>Auth Testing</h1>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" className="logo" alt="Vite logo" /> { contents }
</a>
<a href="https://reactjs.org" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</div> </div>
) )
} }

View File

@@ -0,0 +1,33 @@
export function LoginForm({ info, setInfo }) {
return (
<form>
<div>
<label>Email</label>
<input type="text" onChange={(e) => setInfo({ ...info, email: e.target.value })} />
</div>
<div>
<label>Password</label>
<input type="password" onChange={(e) => setInfo({ ...info, password: e.target.value })} />
</div>
</form>
)
}
export function RegisterForm({ info, setInfo }) {
return (
<form>
<div>
<label>Username</label>
<input type="text" onChange={(e) => setInfo({ ...info, username: e.target.value })} />
</div>
<div>
<label>Email</label>
<input type="text" onChange={(e) => setInfo({ ...info, email: e.target.value })} />
</div>
<div>
<label>Password</label>
<input type="password" onChange={(e) => setInfo({ ...info, password: e.target.value })} />
</div>
</form>
)
}

View File

@@ -0,0 +1,7 @@
export default function Page({ classes = "", children = <></> }) {
return (
<main className={`page ${classes}`}>
{ children }
</main>
)
}

54
client/src/pages/Auth.jsx Normal file
View File

@@ -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(<LoginForm info={info} setInfo={setInfo} />);
const [button, setButton] = useState(
<>
<button onClick={() => handleLogin(info)}>Login</button>
<aside>Not registered? Click <a onClick={swapForm}>here</a> to register</aside>
</>
);
useEffect(() => {
console.log(mode);
}, [info]);
function swapForm() {
if (mode === "register") {
setMode("login");
setForm(<LoginForm info={info} setInfo={setInfo} />);
setButton(
<>
<button onClick={() => handleLogin(info)}>Login</button>
<aside>Not registered? Click <a onClick={swapForm}>here</a> to register</aside>
</>
)
} else {
setMode("register");
setForm(<RegisterForm info={info} setInfo={setInfo} />);
setButton(
<>
<button onClick={() => handleRegister(info)}>Register</button>
<aside>Looking for the login section? Click <a onClick={swapForm}>here</a></aside>
</>
);
}
}
return (
<section>
<LoginForm info={info} setInfo={setInfo} />
<button onClick={() => handleLogin(info)}>Login</button>
{/* <aside>Not registered? Click <a onClick={swapForm}>here</a> to register</aside> */}
<RegisterForm info={info} setInfo={setInfo} />
<button onClick={() => handleRegister(info)}>Register</button>
{/* <aside>Looking for the login section? Click <a onClick={swapForm}>here</a></aside> */}
</section>
)
}
export default Auth

38
client/src/pages/Home.jsx Normal file
View File

@@ -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 (
<section>
<h1>Testing user auth workflow with PERN stack</h1>
<button onClick={getStatus}>Get status</button>
{ items }
<button onClick={handleLogout}>Log Out</button>
</section>
)
}
export default Home

48
client/src/util/API.js Normal file
View File

@@ -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);
}
}

View File

@@ -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 });
}

View File

@@ -8,7 +8,7 @@ require('dotenv').config();
const secret = process.env.SECRET; const secret = process.env.SECRET;
async function expressLoader(app) { async function expressLoader(app) {
app.use(cors()); app.use(cors({ origin: "http://localhost:5173" }));
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));