experimental build, context with reducer
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { useContext } from 'react';
|
||||
import { AppContext } from './store/store';
|
||||
import { useReducer } from 'react';
|
||||
import { AppContext, initialState, reducer } from './store/store';
|
||||
|
||||
import NavBar from './components/Navbar';
|
||||
import LandingPage from './components/LandingPage';
|
||||
@@ -11,11 +11,11 @@ import Register from './components/User/Register';
|
||||
import './App.scss'
|
||||
|
||||
function App() {
|
||||
const context = useContext(AppContext);
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<AppContext.Provider value={context}>
|
||||
<AppContext.Provider value={[state, dispatch]}>
|
||||
<NavBar/>
|
||||
|
||||
<Routes>
|
||||
|
||||
@@ -1,29 +1,41 @@
|
||||
import { useReducer, useState } from "react";
|
||||
import { initialState, reducer } from "../store/store";
|
||||
import { useReducer, useState, useEffect, useContext } from "react";
|
||||
import { AppContext, initialState, reducer } from "../store/store";
|
||||
import { ActionType } from "../store/store_types";
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
function NavBar() {
|
||||
const [loggedIn, setLoggedIn] = useState(false);
|
||||
const [userID, setUserID] = useState(null);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const [searchInput, setSearchInput] = useState('');
|
||||
|
||||
const [state, dispatch] = useContext(AppContext);
|
||||
// const { searchTerm, user, cart } = useContext(AppContext);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSearch = () => {
|
||||
if (searchTerm === '') return;
|
||||
if (searchInput === '') return;
|
||||
|
||||
dispatch({ type: ActionType.SEARCH, payload: searchTerm });
|
||||
navigate(`/products?query=${searchTerm}`);
|
||||
dispatch({ type: ActionType.SEARCH, payload: searchInput });
|
||||
navigate(`/products?query=${searchInput}`);
|
||||
}
|
||||
|
||||
// const forceRender = () => {
|
||||
// console.log(searchTerm);
|
||||
// console.log(user);
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log('state updated!');
|
||||
// }, [user])
|
||||
|
||||
return (
|
||||
<nav>
|
||||
<a href="/">Logo</a>
|
||||
<div className="searchbar">
|
||||
<input type="text" placeholder="Search products" onChange={(e) => setSearchTerm(e.target.value)}/>
|
||||
<input type="text" placeholder="Search products" onChange={(e) => setSearchInput(e.target.value)}/>
|
||||
<button onClick={handleSearch}>Search</button>
|
||||
<button onClick={() => console.log(state)}>Render</button>
|
||||
</div>
|
||||
{loggedIn ? <a href={`/users/${userID}`}>Profile info</a> : <a href="/login">Log In</a>}
|
||||
</nav>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useState, useReducer } from "react";
|
||||
import { reducer, initialState } from "../../store/store";
|
||||
import { ActionType, undefinedUser } from "../../store/store_types";
|
||||
import { userInfo, LoginHeaders } from "../../types/main";
|
||||
import { handleLogin, getOneUser } from "../../util/apiUtils";
|
||||
import { useState, useEffect, useContext } from "react";
|
||||
import { AppContext } from "../../store/store";
|
||||
import { ActionType } from "../../store/store_types";
|
||||
import { userInfo } from "../../types/main";
|
||||
import { handleLogin } from "../../util/apiUtils";
|
||||
import Page from "../../util/Page";
|
||||
|
||||
enum PassVisible {
|
||||
@@ -11,11 +11,12 @@ enum PassVisible {
|
||||
}
|
||||
|
||||
function LoginForm() {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const [state, dispatch] = useContext(AppContext);
|
||||
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [showPass, setShowPass] = useState(PassVisible.hide);
|
||||
const [toDispatch, setToDispatch] = useState<userInfo>();
|
||||
|
||||
const displaySession = async () => {
|
||||
if (username === '' || password === '') return;
|
||||
@@ -33,10 +34,15 @@ function LoginForm() {
|
||||
headers: json
|
||||
}
|
||||
|
||||
dispatch({ type: ActionType.UPDATEONE, payload: thisUser });
|
||||
setToDispatch(thisUser);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('thing?');
|
||||
dispatch({ type: ActionType.USERLOGIN, payload: toDispatch });
|
||||
}, [toDispatch]);
|
||||
|
||||
return (
|
||||
<Page classes="login light-page">
|
||||
<h1>Welcome back to my store!</h1>
|
||||
|
||||
@@ -61,7 +61,8 @@ function Register() {
|
||||
let newInfo: userInfo = {
|
||||
name: name,
|
||||
email: email,
|
||||
password: password
|
||||
password: password,
|
||||
headers: {}
|
||||
}
|
||||
|
||||
setUserData(newInfo);
|
||||
@@ -80,7 +81,8 @@ function Register() {
|
||||
|
||||
// allows registration submission if warning text has correct value and userData is defined with all required values
|
||||
const handleRegistration = async () => {
|
||||
warningText === "Conditions met!" && userData && await registerNewUser(userData);
|
||||
if (!userData) return;
|
||||
warningText === "Conditions met!" && await registerNewUser(userData);
|
||||
|
||||
setName('');
|
||||
setEmail('');
|
||||
|
||||
@@ -19,11 +19,15 @@ export const reducer = (state: appState, action: userAction) => {
|
||||
case ActionType.UPDATEONE:
|
||||
return state;
|
||||
case ActionType.SEARCH:
|
||||
console.log(payload);
|
||||
|
||||
return {
|
||||
...state,
|
||||
searchTerm: payload
|
||||
}
|
||||
case ActionType.USERLOGIN:
|
||||
console.log(payload);
|
||||
|
||||
return {
|
||||
...state,
|
||||
user: payload
|
||||
@@ -33,4 +37,4 @@ export const reducer = (state: appState, action: userAction) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const AppContext = createContext(initialState)
|
||||
export const AppContext = createContext<appState | any>(initialState)
|
||||
|
||||
@@ -21,12 +21,23 @@ export interface appState {
|
||||
cart: Cart
|
||||
}
|
||||
|
||||
export type SessionHeader = {
|
||||
authenticated: boolean
|
||||
cookie: {
|
||||
expires: string
|
||||
httpOnly: boolean
|
||||
originalMaxAge: number
|
||||
path: string
|
||||
secure: boolean
|
||||
}
|
||||
user?: userInfo
|
||||
}
|
||||
|
||||
// empty object templates for initial state
|
||||
export const undefinedUser: userInfo = {
|
||||
email: '',
|
||||
name: '',
|
||||
password: '',
|
||||
headers: {}
|
||||
}
|
||||
|
||||
export const emptyCart: Cart = {
|
||||
@@ -34,4 +45,4 @@ export const emptyCart: Cart = {
|
||||
userInfo: undefinedUser,
|
||||
checkedOut: false,
|
||||
contents: []
|
||||
}
|
||||
}
|
||||
4
client/src/types/main.d.ts
vendored
4
client/src/types/main.d.ts
vendored
@@ -1,10 +1,12 @@
|
||||
import { SessionHeader } from "../store/store_types";
|
||||
|
||||
// user details and metadata
|
||||
export type userInfo = {
|
||||
email: string;
|
||||
id?: number;
|
||||
name?: string;
|
||||
password: string;
|
||||
headers: object
|
||||
headers?: SessionHeader
|
||||
}
|
||||
|
||||
export type LoginHeaders = {
|
||||
|
||||
Reference in New Issue
Block a user