diff --git a/client/src/App.tsx b/client/src/App.tsx index c0dc73e..bf125c9 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -3,6 +3,7 @@ import { useEffect } from 'react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { useAuthContext } from './context/AuthContext'; import jwtDecode from 'jwt-decode'; +import API from './util/API'; // pages, ui, components, styles import Subscriptions from './components/pages/Subscriptions/Subscriptions'; @@ -22,7 +23,7 @@ import { TokenType } from './util/types'; import './sass/App.scss'; function App() { - const { setUser, setToken } = useAuthContext(); + const { setUser, token, setToken } = useAuthContext(); useEffect(() => { if (document.cookie) { @@ -30,7 +31,11 @@ function App() { setToken(document.cookie.split("=")[1]); setUser(extractedToken.user); } - }, []); + }, [document.cookie]); + + useEffect(() => { + token && API.Settings.setToken(token); + }, [token]) return ( diff --git a/client/src/components/pages/AddRecipe.tsx b/client/src/components/pages/AddRecipe.tsx index 9cd599b..792e07e 100644 --- a/client/src/components/pages/AddRecipe.tsx +++ b/client/src/components/pages/AddRecipe.tsx @@ -10,7 +10,7 @@ const AddRecipe = () => { const getFormState = useCallback((data: IRecipe) => { setInput(data); - }, []) + }, [input]) const handleCreate = () => { for (let field of Object.keys(input)) { @@ -28,20 +28,6 @@ const AddRecipe = () => { } }) }, [authContext]) - - useEffect(() => { - input.authoruserid && setForm( - new Form({ - parent: "AddRecipe", - keys: ["name", "preptime", "course", "cuisine", "ingredients", "description"], - labels: ["Recipe Name:", "Prep Time:", "Course:", "Cuisine:", "Ingredients:", "Description:"], - dataTypes: ['text', 'text', 'custom picker', 'custom picker', 'custom picker', 'TINYMCE'], - initialState: input, - getState: getFormState, - richTextInitialValue: "

Enter recipe details here!

" - }).mount() - ) - }, [input.authoruserid]) useEffect(() => { console.log(input); @@ -53,7 +39,18 @@ const AddRecipe = () => { +
Enter recipe details here!

" + }} /> + { form ||

Loading...

} + diff --git a/client/src/components/pages/Login.tsx b/client/src/components/pages/Login.tsx index 0fe25bd..4ad816a 100644 --- a/client/src/components/pages/Login.tsx +++ b/client/src/components/pages/Login.tsx @@ -9,8 +9,7 @@ import API from "../../util/API"; export default function Login() { const params = new URLSearchParams(window.location.search); const redirect = params.get("redirect"); - const { user, setUser } = useContext(AuthContext); - const [form, setForm] = useState(); + const { user, setToken } = useContext(AuthContext); // setup and local state const navigate = useNavigate(); @@ -25,11 +24,12 @@ export default function Login() { const handleLogin = async () => { if (!input.email || !input.password) return; const result = await new API.Auth().login(input); - console.log(result); - // const { data, ok } = await attemptLogin(input); - // if (ok) setUser(data); - // navigate(`/${redirect ?? ''}`); + // setting token will trigger ui update + setToken(result.token); + + // if there is a redirect, go there, else go home + navigate(`/${redirect ?? ''}`); } // check for logged in user and mount form @@ -37,10 +37,6 @@ export default function Login() { if (user) navigate('/'); }, []) - useEffect(() => { - console.log(input); - }, [getFormState]) - return (

Hello! Nice to see you again.

@@ -54,7 +50,7 @@ export default function Login() { dataTypes: Object.keys(input), initialState: input, getState: getFormState - } as FormConfig} /> + }} /> diff --git a/client/src/components/pages/Profile.tsx b/client/src/components/pages/Profile.tsx index 73077a6..d319d30 100644 --- a/client/src/components/pages/Profile.tsx +++ b/client/src/components/pages/Profile.tsx @@ -14,8 +14,7 @@ export default function Profile() { return (
-

{user?.firstname}'s Profile

-

Things and stuff!

+

{user && user.firstname}'s Profile

diff --git a/client/src/components/pages/Register/aboutyou.tsx b/client/src/components/pages/Register/aboutyou.tsx index 3b6ad87..05865ce 100644 --- a/client/src/components/pages/Register/aboutyou.tsx +++ b/client/src/components/pages/Register/aboutyou.tsx @@ -5,9 +5,10 @@ import { RegisterVariantType, VariantLabel } from "."; import { useAuthContext } from "../../../context/AuthContext"; import { IUser, IUserAuth } from "../../../schemas"; import { attemptLogin, attemptRegister } from "../../../util/apiUtils"; +import API from "../../../util/API"; import { Button, Page, Panel } from "../../ui"; import Divider from "../../ui/Divider"; -import Form, { FormConfig } from "../../ui/Form"; +import Form from "../../ui/Form"; const blankUser: IUser = { firstname: '', @@ -20,51 +21,31 @@ const blankUser: IUser = { } const AboutYou: RegisterVariantType = ({ transitionDisplay }) => { + const auth = new API.Auth(); const navigate = useNavigate(); - const authContext = useAuthContext(); - const [form, setForm] = useState(

Loading content...

); + const { user, setToken } = useAuthContext(); const [input, setInput] = useState(blankUser); - const [regSuccess, setRegSuccess] = useState(); const getFormState = useCallback((received: IUser) => { setInput(received); }, []); useEffect(() => { - if (authContext.user) navigate('/'); - }, [authContext]); + if (user) navigate('/'); + }, [user]); async function handleRegister() { - const res = await attemptRegister(input); + const res = await auth.register(input); if (res.ok) { + setTimeout(async () => { + const result = await auth.login(input); + setToken(result.token); + }, 750); + transitionDisplay(VariantLabel.InitialCollection, input); } } - async function unwrapLogin() { - const data: IUserAuth = { email: input.email, password: input.password || "" } - const login = await attemptLogin(data); - if (login) { - authContext.user = login.user; - } - navigate('/'); - } - - useEffect(() => { - setForm(new Form({ - parent: "register", - keys: ['firstname', 'lastname', 'handle', 'email', 'password'], - initialState: input, - labels: ['First Name', 'Last Name', 'Handle', 'Email', "Password"], - dataTypes: ['text', 'text', 'text', 'email', 'password'], - getState: getFormState - }).mount()); - }, []) - - useEffect(() => { - if (regSuccess) unwrapLogin(); - }, [regSuccess]) - return (

Hi! Thanks for being here.

@@ -74,7 +55,16 @@ const AboutYou: RegisterVariantType = ({ transitionDisplay }) => {

Tell us a bit about yourself:

- { form ||

Loading...

} + + +
diff --git a/client/src/components/pages/Register/collection.tsx b/client/src/components/pages/Register/collection.tsx index 5a41012..70be071 100644 --- a/client/src/components/pages/Register/collection.tsx +++ b/client/src/components/pages/Register/collection.tsx @@ -3,33 +3,23 @@ import { RegisterVariantType, VariantLabel } from "."; import { useNow } from "../../../hooks/useNow"; import { ICollection, IUser, IUserAuth } from "../../../schemas"; import { attemptLogin, createNewCollection } from "../../../util/apiUtils"; +import API from "../../../util/API"; import { Button, Divider, Page, Panel } from "../../ui"; import TextField from "../../ui/TextField"; +import { useAuthContext } from "../../../context/AuthContext"; const InitialCollection: RegisterVariantType = ({ transitionDisplay, input }) => { + const { user, setUser } = useAuthContext(); const [collectionName, setCollectionName] = useState(); const [view, setView] = useState(

Loading...

); - const [user, setUser] = useState(); const now = useNow(); - async function unwrapLogin(data: IUser) { - const userInfo: IUserAuth = { email: data.email, password: data.password! } - const login = await attemptLogin(userInfo); - setUser(login.user); - } - - useEffect(() => { - if (input) { - setTimeout(() => { - unwrapLogin(input); - }, 750); - } - }, []) + const collectionAPI = new API.Collection(); const handleClick = async () => { if (!user) return; const collection: ICollection = { - name: collectionName || (user.firstname + "'s Collection"), + name: collectionName ?? (user.firstname + "'s Collection"), active: true, ismaincollection: true, ownerid: user.id!.toString(), @@ -39,7 +29,7 @@ const InitialCollection: RegisterVariantType = ({ transitionDisplay, input }) => console.log(collection); - const result = await createNewCollection(collection); + const result = await collectionAPI.post(collection); console.log(result); if (result) transitionDisplay(VariantLabel.AddFriends); } @@ -58,7 +48,8 @@ const InitialCollection: RegisterVariantType = ({ transitionDisplay, input }) =>

What would you like to call your main collection?

- ) => setCollectionName(e.target.value)} placeholder={user.firstname + 's Collection'} /> + {/* ) => setCollectionName(e.target.value)} placeholder={user.firstname + 's Collection'} /> */} + setCollectionName(e.target.value)} placeholder={user.firstname + 's Collection'}> diff --git a/client/src/components/ui/Navbar/variants.tsx b/client/src/components/ui/Navbar/variants.tsx index e76694c..923582d 100644 --- a/client/src/components/ui/Navbar/variants.tsx +++ b/client/src/components/ui/Navbar/variants.tsx @@ -1,7 +1,7 @@ import API from "../../../util/API"; import { NavbarType } from "../../../util/types"; import { Button, Dropdown } from '..' -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useAuthContext } from "../../../context/AuthContext"; import { useNavigate } from "react-router-dom"; @@ -40,6 +40,10 @@ const LoggedIn = () => { navigate(payload); } + useEffect(() => { + console.log(user); + }, []) + return (
-

Hi, {user?.firstname}.

+

Hi, {user && user.firstname}.

diff --git a/client/src/components/ui/Widgets/FriendSearchWidget.tsx b/client/src/components/ui/Widgets/FriendSearchWidget.tsx index 101c716..e2ec89b 100644 --- a/client/src/components/ui/Widgets/FriendSearchWidget.tsx +++ b/client/src/components/ui/Widgets/FriendSearchWidget.tsx @@ -3,12 +3,15 @@ import { IUser } from "../../../schemas"; import { TextField, UserCard } from ".."; import { v4 } from "uuid"; import { getAllUsers } from "../../../util/apiUtils"; +import API from "../../../util/API"; const FriendSearchWidget: FC<{}> = () => { const [searchTerm, setSearchTerm] = useState(); const [userPool, setUserPool] = useState([]); const [friendResults, setFriendResults] = useState([]); + const users = new API.User(); + // this isn't really working right now i don't think const handleRequestSent = useCallback((targetid: string | number) => { setUserPool((prev: IUser[]) => { @@ -23,7 +26,7 @@ const FriendSearchWidget: FC<{}> = () => { // load available user pool on mount useEffect(() => { (async function() { - const result = await getAllUsers(); + const result = await users.getAll(); if (result) setUserPool(result); })(); }, []) diff --git a/client/src/util/API.ts b/client/src/util/API.ts index 5265001..f820f16 100644 --- a/client/src/util/API.ts +++ b/client/src/util/API.ts @@ -3,57 +3,61 @@ import { IUser, IUserAuth, IFriendship, IRecipe, IIngredient, ICollection, IGroc import { default as _instance } from "./axiosInstance"; module API { - const APISTRING = import.meta.env.APISTRING || "http://localhost:8080"; + export class Settings { + private static APISTRING = import.meta.env.APISTRING || "http://localhost:8080"; + private static token?: string; + + public static getAPISTRING() { + return Settings.APISTRING; + } + + public static getToken() { + return Settings.token; + } + + public static setToken(newToken: string) { + Settings.token = newToken; + } + } abstract class RestController { protected instance = _instance; protected endpoint: string; - protected token?: string; protected headers?: any - constructor(endpoint: string, token?: string) { + constructor(endpoint: string) { this.endpoint = endpoint; - this.token = token; - if (token) { + if (Settings.getToken()) { this.headers = { "Content-Type": "application/json", - "Authorization": ("Bearer " + token) + "Authorization": ("Bearer " + Settings.getToken()) }; } } async getAll() { - if (!this.token) return null; - const response = await this.instance.get(this.endpoint, this.headers); return Promise.resolve(response.data); } async getByID(id: string) { - if (!this.token) return null; - const response = await this.instance.get(this.endpoint + "/" + id, this.headers); return Promise.resolve(response.data); } - async postOne(data: T) { - if (!this.token) return null; - + async post(data: T) { + console.log(data); const response = await this.instance.post(this.endpoint, data, this.headers); return Promise.resolve(response.data); } async put(id: string, data: T | Partial) { - if (!this.token) return null; - - const response = await this.instance.put(this.endpoint + "/" + id, data, this.headers); + const response = await this.instance.put(this.endpoint + "/" + id, JSON.stringify(data), this.headers); return Promise.resolve(response.data); } async delete(id: string) { - if (!this.token) return null; - const response = await this.instance.delete(this.endpoint + '/' + id, this.headers); return Promise.resolve(response.data); } @@ -61,7 +65,7 @@ module API { export class Auth { private instance = _instance; - private endpoint = APISTRING + "/auth"; + private endpoint = Settings.getAPISTRING() + "/auth"; async login(data: IUserAuth | Partial) { try { @@ -109,18 +113,16 @@ module API { export class User extends RestController { constructor() { - super(APISTRING + "/app/users"); + super(Settings.getAPISTRING() + "/app/users"); } } export class Friendship extends RestController { constructor() { - super(APISTRING + "/app/friends"); + super(Settings.getAPISTRING() + "/app/friends"); } async getPendingFriendRequests() { - if (!this.token) return null; - const response = await this.instance.get(this.endpoint + "?pending=true", this.headers); return Promise.resolve(response.data); } @@ -128,25 +130,25 @@ module API { export class Recipe extends RestController { constructor() { - super(APISTRING + "/app/recipes"); + super(Settings.getAPISTRING() + "/app/recipes"); } } export class Ingredient extends RestController { constructor() { - super(APISTRING + "/app/ingredients"); + super(Settings.getAPISTRING() + "/app/ingredients"); } } export class Collection extends RestController { constructor() { - super(APISTRING + "/app/collections"); + super(Settings.getAPISTRING() + "/app/collection"); } } export class GroceryList extends RestController { constructor() { - super(APISTRING + "/app/grocery-list") + super(Settings.getAPISTRING() + "/app/grocery-list") } } } diff --git a/server/loaders/express.ts b/server/loaders/express.ts index f66098b..9092b0d 100644 --- a/server/loaders/express.ts +++ b/server/loaders/express.ts @@ -1,4 +1,4 @@ -import { Express } from 'express'; +import express, { Express } from 'express'; import bodyParser from 'body-parser'; import cookieParser from 'cookie-parser'; import morgan from 'morgan'; @@ -19,8 +19,8 @@ declare module 'express-session' { export const expressLoader = async (app: Express) => { app.use(cors({ origin: origin })); - app.use(bodyParser.json()); - app.use(bodyParser.urlencoded({ extended: true })); + app.use(express.json()); + app.use(express.urlencoded({ extended: true })); app.use(cookieParser()); app.use(morgan('tiny')); app.use(requireSessionSecret); diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 73fe157..43c0be2 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -56,6 +56,8 @@ export const authRoute = (app: Express) => { const safeUserData = { id: user.id, + firstname: user.firstname, + lastname: user.lastname, handle: user.handle, email: user.email, datecreated: user.datecreated, diff --git a/server/routes/collection.ts b/server/routes/collection.ts index 8654504..5682ff9 100644 --- a/server/routes/collection.ts +++ b/server/routes/collection.ts @@ -8,6 +8,12 @@ const router = Router(); export const collectionRoute = (app: Express) => { app.use('/app/collection', router); + router.use((req, res, next) => { + console.log('what gives'); + console.log(req.body); + next(); + }) + router.get('/:id', async (req, res, next) => { const { id } = req.params; try { @@ -30,7 +36,7 @@ export const collectionRoute = (app: Express) => { router.post('/', async (req, res, next) => { const data = req.body; - console.log(data); + console.log(req.body ?? "sanity check"); try { const result = await CollectionInstance.post(data); diff --git a/server/routes/index.ts b/server/routes/index.ts index a971eb3..0c9743d 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -25,7 +25,7 @@ export const routes = async (app: Express) => { console.log(token); if (!token) { - res.status(403).send("Unauthorized"); + res.status(403).send("Unauthorized, did not receive token"); } else { jwt.verify(token, process.env.SESSIONSECRET as string, (err, data) => { if (err) {