Skip to content

Commit bcd1cba

Browse files
committed
merged with current dev, working state
2 parents 9ad19c6 + 20a5052 commit bcd1cba

File tree

18 files changed

+632
-194
lines changed

18 files changed

+632
-194
lines changed

demo-app/src/client/Components/FunctionalReducerCounter.tsx

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,22 @@ type CounterAction =
2121
| { type: 'DECREMENT' }
2222
| { type: 'DOUBLE' }
2323
| { type: 'RESET' }
24-
| { type: 'ADD'; payload: number };
24+
| { type: 'ADD'; payload: number }
25+
| { type: 'SET_STATE'; payload: CounterState };
26+
27+
type SecondaryCounterState = {
28+
count: number;
29+
multiplier: number;
30+
lastOperation: string;
31+
history: number[];
32+
};
33+
34+
type SecondaryCounterAction =
35+
| { type: 'MULTIPLY' }
36+
| { type: 'DIVIDE' }
37+
| { type: 'SET_MULTIPLIER'; payload: number }
38+
| { type: 'RESET' }
39+
| { type: 'SET_STATE'; payload: SecondaryCounterState };
2540

2641
function counterReducer(state: CounterState, action: CounterAction, step: number): CounterState {
2742
switch (action.type) {
@@ -59,6 +74,54 @@ function counterReducer(state: CounterState, action: CounterAction, step: number
5974
history: [...state.history, state.count + action.payload],
6075
lastAction: `ADD ${action.payload}`,
6176
};
77+
case 'SET_STATE':
78+
return {
79+
...action.payload,
80+
lastAction: 'SET_STATE',
81+
};
82+
default:
83+
return state;
84+
}
85+
}
86+
87+
function secondaryCounterReducer(
88+
state: SecondaryCounterState,
89+
action: SecondaryCounterAction,
90+
): SecondaryCounterState {
91+
switch (action.type) {
92+
case 'MULTIPLY':
93+
return {
94+
...state,
95+
count: state.count * state.multiplier,
96+
history: [...state.history, state.count * state.multiplier],
97+
lastOperation: `Multiplied by ${state.multiplier}`,
98+
};
99+
case 'DIVIDE':
100+
return {
101+
...state,
102+
count: state.count / state.multiplier,
103+
history: [...state.history, state.count / state.multiplier],
104+
lastOperation: `Divided by ${state.multiplier}`,
105+
};
106+
case 'SET_MULTIPLIER':
107+
return {
108+
...state,
109+
multiplier: action.payload,
110+
history: [...state.history],
111+
lastOperation: `Set multiplier to ${action.payload}`,
112+
};
113+
case 'RESET':
114+
return {
115+
count: 0,
116+
multiplier: 2,
117+
history: [],
118+
lastOperation: 'Reset',
119+
};
120+
case 'SET_STATE':
121+
return {
122+
...action.payload,
123+
lastOperation: 'SET_STATE',
124+
};
62125
default:
63126
return state;
64127
}
@@ -76,6 +139,7 @@ function FunctionalReducerCounter({
76139
const [clickCount, setClickCount] = useState(0);
77140
const [lastClickTime, setLastClickTime] = useState<Date | null>(null);
78141
const [averageTimeBetweenClicks, setAverageTimeBetweenClicks] = useState<number>(0);
142+
79143
const [state, dispatch] = useReducer(
80144
(state: CounterState, action: CounterAction) => counterReducer(state, action, step),
81145
{
@@ -85,6 +149,13 @@ function FunctionalReducerCounter({
85149
},
86150
);
87151

152+
const [secondaryState, secondaryDispatch] = useReducer(secondaryCounterReducer, {
153+
count: initialCount,
154+
multiplier: 2,
155+
history: [],
156+
lastOperation: 'none',
157+
});
158+
88159
return (
89160
<div
90161
className='reducer-counter'
@@ -94,8 +165,9 @@ function FunctionalReducerCounter({
94165
}}
95166
>
96167
<h2>{title}</h2>
168+
97169
<div className='counter-value'>
98-
<h3>Current Count: {state.count}</h3>
170+
<h3>Primary Counter: {state.count}</h3>
99171
</div>
100172

101173
<div className='counter-buttons'>
@@ -107,7 +179,6 @@ function FunctionalReducerCounter({
107179
</div>
108180

109181
<div className='counter-info'>
110-
<h4>Last Action: {state.lastAction}</h4>
111182
<h4>History:</h4>
112183
<div className='history-list'>
113184
{state.history.map((value, index) => (
@@ -118,7 +189,43 @@ function FunctionalReducerCounter({
118189
))}
119190
</div>
120191
</div>
192+
193+
<div
194+
className='secondary-counter'
195+
style={{ marginTop: '2rem', borderTop: '1px solid #ccc', paddingTop: '1rem' }}
196+
>
197+
<h3>Secondary Counter: {secondaryState.count}</h3>
198+
<div className='counter-buttons'>
199+
<button onClick={() => secondaryDispatch({ type: 'MULTIPLY' })}>
200+
Multiply by {secondaryState.multiplier}
201+
</button>
202+
<button onClick={() => secondaryDispatch({ type: 'DIVIDE' })}>
203+
Divide by {secondaryState.multiplier}
204+
</button>
205+
<button
206+
onClick={() =>
207+
secondaryDispatch({ type: 'SET_MULTIPLIER', payload: secondaryState.multiplier + 1 })
208+
}
209+
>
210+
Increase Multiplier
211+
</button>
212+
<button onClick={() => secondaryDispatch({ type: 'RESET' })}>Reset</button>
213+
</div>
214+
<div className='counter-info'>
215+
<h4>Current Multiplier: {secondaryState.multiplier}</h4>
216+
<h4>History:</h4>
217+
<div className='history-list'>
218+
{secondaryState.history.map((value, index) => (
219+
<span key={index}>
220+
{value}
221+
{index < secondaryState.history.length - 1 ? ' → ' : ''}
222+
</span>
223+
))}
224+
</div>
225+
</div>
226+
</div>
121227
</div>
122228
);
123229
}
230+
124231
export default FunctionalReducerCounter;

demo-app/src/client/Components/FunctionalStateCounter.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ function FunctionalStateCounter({
8080
</div>
8181

8282
<div className='counter-info'>
83-
<h4>Last Action: {lastAction}</h4>
8483
<h4>History:</h4>
8584
<div className='history-list'>
8685
{history.map((value, index) => (

demo-app/src/client/Components/Home.tsx

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,74 @@
11
import React from 'react';
2+
import { useTheme } from '../../contexts/ThemeContext';
3+
import { useAuth } from '../../contexts/AuthContext';
24

35
function Home(): JSX.Element {
6+
const { theme } = useTheme();
7+
const { user, login, logout } = useAuth();
8+
49
return (
5-
<div className='about'>
10+
<div
11+
className='about'
12+
style={{
13+
backgroundColor: theme.backgroundColor,
14+
color: theme.textColor,
15+
}}
16+
>
617
<h2>REACTIME - DEMO APP</h2>
18+
19+
{user ? (
20+
<div>
21+
<p>Welcome, {user.username}!</p>
22+
<button
23+
onClick={logout}
24+
style={{
25+
backgroundColor: theme.primaryColor,
26+
color: theme.backgroundColor,
27+
padding: '8px 16px',
28+
border: 'none',
29+
borderRadius: '4px',
30+
cursor: 'pointer',
31+
}}
32+
>
33+
Logout
34+
</button>
35+
</div>
36+
) : (
37+
<div>
38+
<p>Please log in:</p>
39+
<button
40+
onClick={() => login('testUser')}
41+
style={{
42+
backgroundColor: theme.primaryColor,
43+
color: theme.backgroundColor,
44+
padding: '8px 16px',
45+
border: 'none',
46+
borderRadius: '4px',
47+
cursor: 'pointer',
48+
}}
49+
>
50+
Login as Test User
51+
</button>
52+
<button
53+
onClick={() => login('admin')}
54+
style={{
55+
backgroundColor: theme.secondaryColor,
56+
color: theme.backgroundColor,
57+
padding: '8px 16px',
58+
border: 'none',
59+
borderRadius: '4px',
60+
marginLeft: '8px',
61+
cursor: 'pointer',
62+
}}
63+
>
64+
Login as Admin
65+
</button>
66+
</div>
67+
)}
68+
769
<p>
870
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
9-
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
10-
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
11-
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
12-
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
13-
</p>
14-
<p>
15-
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
16-
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
17-
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
18-
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
19-
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
71+
ut labore et dolore magna aliqua..."
2072
</p>
2173
</div>
2274
);

demo-app/src/client/Components/ReducerCounter.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ class ReducerCounter extends Component<CounterProps, CounterState> {
123123
</div>
124124

125125
<div className='counter-info'>
126-
<h4>Last Action: {this.state.lastAction}</h4>
127126
<h4>History:</h4>
128127
<div className='history-list'>
129128
{this.state.history.map((value, index) => (
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
import { useTheme } from '../../contexts/ThemeContext';
3+
4+
const ThemeToggle = (): JSX.Element => {
5+
const { theme, toggleTheme } = useTheme();
6+
7+
return (
8+
<button
9+
onClick={toggleTheme}
10+
style={{
11+
backgroundColor: theme.primaryColor,
12+
color: theme.backgroundColor,
13+
padding: '8px 16px',
14+
border: 'none',
15+
borderRadius: '4px',
16+
cursor: 'pointer',
17+
position: 'fixed',
18+
top: '10px',
19+
right: '10px',
20+
}}
21+
>
22+
Toggle Theme
23+
</button>
24+
);
25+
};
26+
27+
export default ThemeToggle;

demo-app/src/client/Router.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1+
// src/client/Router.tsx
12
import * as React from 'react';
23
import * as ReactDOM from 'react-dom';
34
import { createRoot } from 'react-dom/client';
45
import { BrowserRouter, Routes, Route } from 'react-router-dom';
6+
import { ThemeProvider } from '../contexts/ThemeContext';
7+
import { AuthProvider } from '../contexts/AuthContext';
58
import Nav from './Components/Nav';
69
import Board from './Components/Board';
710
import Home from './Components/Home';
811
import Buttons from './Components/Buttons';
912
import ReducerCounter from './Components/ReducerCounter';
1013
import FunctionalReducerCounter from './Components/FunctionalReducerCounter';
11-
// import ButtonsWithMoreHooks from './Components/ButtonsWithMoreHooks';
1214
import FunctionalStateCounter from './Components/FunctionalStateCounter';
15+
import ThemeToggle from './Components/ThemeToggle';
1316

1417
const domNode = document.getElementById('root');
18+
if (!domNode) throw new Error('Root element not found');
1519
const root = createRoot(domNode);
1620

1721
const CounterPage = () => (
@@ -41,21 +45,18 @@ const CounterPage = () => (
4145
);
4246

4347
root.render(
44-
<BrowserRouter key='BrowserRouter'>
45-
<Nav key='Nav' />
46-
<Routes key='Routes'>
47-
<Route path='/' element={<Home key='Home' />} />
48-
<Route path='/tictactoe' element={<Board key='Board' />} />
49-
{/* Switch between the two "buttons" paths below via commenting/uncommenting to alternate between
50-
the public facing Buttons page and the fiber node hooks research page "ButtonsWithMoreHooks" */}
51-
<Route path='/buttons' element={<Buttons key='Buttons' />} />
52-
{/* <Route path='/buttons' element={<ButtonsWithMoreHooks key='ButtonsWithMoreHooks'/>} /> */}
53-
<Route path='/reducer' element={<CounterPage key='CounterPage' />} />
54-
</Routes>
55-
</BrowserRouter>,
56-
57-
/** Comment out everything above this and uncomment the line below as ButtonsWithMoreHooks import statement to skip all of the
58-
* router components and make fiber node hooks research easier */
59-
60-
// <ButtonsWithMoreHooks/>
48+
<AuthProvider>
49+
<ThemeProvider>
50+
<BrowserRouter>
51+
<ThemeToggle />
52+
<Nav />
53+
<Routes>
54+
<Route path='/' element={<Home />} />
55+
<Route path='/tictactoe' element={<Board />} />
56+
<Route path='/buttons' element={<Buttons />} />
57+
<Route path='/reducer' element={<CounterPage />} />
58+
</Routes>
59+
</BrowserRouter>
60+
</ThemeProvider>
61+
</AuthProvider>,
6162
);

demo-app/src/client/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en">
33
<head>
4-
<title>Reactime</title>
4+
<title>Demo App</title>
55
<!-- <link rel="icon" type="image/x-icon" href="../../../assets/logos/blackWhiteSquareIcon.png"> -->
6-
<link rel="stylesheet" type="text/css" href="./style.css">
6+
<link rel="stylesheet" type="text/css" href="./style.css" />
77
</head>
88
<body>
99
<main id="root"></main>

0 commit comments

Comments
 (0)