Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38a245c
initial implementation of the userMachine
bashlk Oct 16, 2024
8a1b9e1
initial implementation of userMachine
bashlk Oct 17, 2024
3b1d6c2
cleaned up userMachine
bashlk Oct 18, 2024
9187e80
borked implementation of customizeUserMachine
bashlk Oct 18, 2024
212ef66
initial implementation of hierarchial machine
bashlk Oct 23, 2024
acbdab9
switched to machine per route and refactored login to use new machine
bashlk Oct 23, 2024
0e91c5a
finished using customizeUser state machine
bashlk Oct 24, 2024
5b7d9a8
implemented changePasswordMachine
bashlk Oct 24, 2024
e5a92f9
implemented profile machine
bashlk Oct 24, 2024
e0332b6
renamed hooks to useSystemMachine for added clarity
bashlk Oct 24, 2024
890558a
implemented entriesMachine
bashlk Oct 24, 2024
f7d16df
implemented timerMachine
bashlk Oct 24, 2024
f3ce64c
added new finished state to fix bug
bashlk Oct 24, 2024
90fd425
fixed bug with item status message
bashlk Oct 24, 2024
ddafe8d
removed unnecessary prop spread
bashlk Oct 24, 2024
d265052
removed unnecessary array
bashlk Oct 24, 2024
a549e14
initial implementation of history in rootMachine
bashlk Oct 24, 2024
ba61d8f
fixed bugs with history
bashlk Oct 24, 2024
32e84cc
removed reference to non existing register route
bashlk Oct 25, 2024
bfeaa72
refactored root machine to contain route state and switched to invoke…
bashlk Oct 25, 2024
43d9a21
removed unnecessary array
bashlk Oct 25, 2024
f51b7e8
added id
bashlk Oct 25, 2024
a1acda9
removed unnecessary assignment
bashlk Oct 30, 2024
c2c1de4
implemented useRootMachineState
bashlk Nov 1, 2024
564a440
replaced initialize events with inputs
bashlk Nov 1, 2024
ff3da74
added robots.txt
bashlk Dec 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/jotai/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Router from './components/Router';
const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change. This route never existed.

{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
Expand Down
1 change: 0 additions & 1 deletion packages/mobx/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import Profile from './routes/Profile/Profile';
const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },
{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
Expand Down
1 change: 0 additions & 1 deletion packages/react/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Profile from './routes/Profile/Profile';
const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },
{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
Expand Down
1 change: 0 additions & 1 deletion packages/tanstack-query/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import Profile from './routes/Profile/Profile';
const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },
{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
Expand Down
1 change: 0 additions & 1 deletion packages/valtio/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import Profile from './routes/Profile/Profile';
const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },
{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
Expand Down
4 changes: 3 additions & 1 deletion packages/xstate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
"preview": "vite preview"
},
"dependencies": {
"@xstate/react": "^4.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"xstate": "^5.18.2"
},
"devDependencies": {
"@types/react": "^18.2.64",
Expand Down
52 changes: 16 additions & 36 deletions packages/xstate/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,47 @@
import Router from '@timo/common/components/Router';
import UserContextProvider from '@timo/common/context/UserContextProvider';
import Container from '@timo/common/components/Container';
import Title from '@timo/common/components/Title';
import TopBarWithUser from '@timo/common/contextualComponents/TopBarWithUser';
import ProtectedRoute from '@timo/common/contextualComponents/ProtectedRoute';

import Login from './routes/Login/Login';
import Entries from './routes/Entries/Entries';
import NewEntry from './routes/NewEntry/NewEntry';
import Profile from './routes/Profile/Profile';

const routes = [
{ path: '/', name: 'Entries' },
{ path: '/login', name: 'Login' },
{ path: '/register', name: 'Register' },
{ path: '/new', name: 'NewEntry' },
{ path: '/profile', name: 'Profile' }
];
import TopBarWithUser from './contextualComponents/TopBarWithUser';
import MachineContextProvider from './context/MachineContext';
import Router from './components/Router';

const App = () => (
<UserContextProvider>
<Router routes={routes}>
{(routeName, history) => {
<MachineContextProvider>
<Router>
{(routeName) => {
let pageComponent = null;
switch (routeName) {
case 'Login':
pageComponent = <Login history={history} />;
case 'login':
pageComponent = <Login />;
break;
case 'NewEntry':
case 'newEntry':
pageComponent = (
<ProtectedRoute history={history}>
<NewEntry history={history} />
</ProtectedRoute>
<NewEntry />
);
break;
case 'Entries':
case 'entries':
pageComponent = (
<ProtectedRoute history={history}>
<Entries history={history} />
</ProtectedRoute>
<Entries />
);
break;
case 'Profile':
case 'profile':
pageComponent = (
<ProtectedRoute history={history}>
<Profile />
</ProtectedRoute>
<Profile />
);
break;
default:
pageComponent = (
<Title>Page not found</Title>
);
}
return (
<Container>
<TopBarWithUser history={history} />
<TopBarWithUser />
{pageComponent}
</Container>
);
}}
</Router>
</UserContextProvider>
</MachineContextProvider>
);

export default App;
17 changes: 17 additions & 0 deletions packages/xstate/src/components/Router.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import PropTypes from 'prop-types';
import useRootMachineState from '../hooks/useRootMachineState';

const Router = ({ children }) => {
const state = useRootMachineState(state => state.value);
const route = state?.authenticated || state?.unauthenticated;
if (route && route !== 'unknown') {
return children(route);
}
return null;
};

Router.propTypes = {
children: PropTypes.func.isRequired
};

export default Router;
17 changes: 17 additions & 0 deletions packages/xstate/src/components/Timer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import styles from '@timo/common/components/Timer/Timer.module.css';
import useChildMachineState from '../hooks/useChildMachineState';

const Timer = () => {
const timerValue = useChildMachineState('newEntry', state => state.context.timerValue);

// Format duration to HH:MM:SS
const formattedValue = new Date(timerValue * 1000).toISOString().slice(11, 19);

return (
<div className={styles.timer}>
{formattedValue}
</div>
);
};

export default Timer;
23 changes: 23 additions & 0 deletions packages/xstate/src/context/MachineContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import PropTypes from 'prop-types';
import { createActor } from 'xstate';
import { createContext } from 'react';
import root from '../machines/root';

const rootActor = createActor(root, { systemId: 'root' });
rootActor.start();

export const MachineContext = createContext();

const MachineContextProvider = ({ children }) => {
return (
<MachineContext.Provider value={rootActor}>
{children}
</MachineContext.Provider>
);
};

MachineContextProvider.propTypes = {
children: PropTypes.node.isRequired
};

export default MachineContextProvider;
21 changes: 21 additions & 0 deletions packages/xstate/src/contextualComponents/TopBarWithUser.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import TopBar from '@timo/common/components/TopBar';
import useRootMachine from '../hooks/useRootMachine';
import useRootMachineState from '../hooks/useRootMachineState';

const TopBarWithUser = () => {
const rootMachine = useRootMachine();
const userData = useRootMachineState(state => state.context.userData);

return (
<TopBar
avatar={{
character: userData?.avatar_character,
background: userData?.avatar_background
}}
onIconClick={() => rootMachine.send({ type: 'pushRoute', route: 'entries' })}
onAvatarClick={() => rootMachine.send({ type: 'pushRoute', route: 'profile' })}
/>
);
};

export default TopBarWithUser;
9 changes: 9 additions & 0 deletions packages/xstate/src/hooks/useChildMachine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useSelector } from '@xstate/react';
import useRootMachine from './useRootMachine';

const useChildMachine = (childId) => {
const rootMachine = useRootMachine();
return useSelector(rootMachine, (state) => state.children[childId]);
};

export default useChildMachine;
9 changes: 9 additions & 0 deletions packages/xstate/src/hooks/useChildMachineState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useSelector } from '@xstate/react';
import useChildMachine from './useChildMachine';

const useChildMachineState = (childId, selector) => {
const machine = useChildMachine(childId);
return useSelector(machine, selector);
};

export default useChildMachineState;
8 changes: 8 additions & 0 deletions packages/xstate/src/hooks/useRootMachine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useContext } from 'react';
import { MachineContext } from '../context/MachineContext';

const useRootMachine = () => {
return useContext(MachineContext);
};

export default useRootMachine;
9 changes: 9 additions & 0 deletions packages/xstate/src/hooks/useRootMachineState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useSelector } from '@xstate/react';
import useRootMachine from './useRootMachine';

const useRootMachineState = (selector) => {
const rootMachine = useRootMachine();
return useSelector(rootMachine, selector);
};

export default useRootMachineState;
55 changes: 55 additions & 0 deletions packages/xstate/src/machines/changePassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { setup, assign, fromPromise } from 'xstate';
import { updatePassword } from '@timo/common/api';

const changePasswordMachine = setup({
actors: {
updatePassword: fromPromise(async ({ input }) => updatePassword(input))
}
}).createMachine({
id: 'changePassword',
initial: 'idle',
context: ({ input }) => ({
username: input.username,
statusMessage: null
}),
states: {
'idle': {
on: {
'save': {
target: 'saving'
}
}
},
'saving': {
entry: [
assign({
statusMessage: 'Saving...'
})
],
invoke: [
{
src: 'updatePassword',
input: ({ context, event }) => ({
username: context.username,
password: event.password,
newPassword: event.newPassword
}),
onDone: {
target: 'idle',
actions: assign({
statusMessage: 'Password updated'
})
},
onError: {
target: 'idle',
actions: assign({
statusMessage: ({ event }) => event.error.message
})
}
}
]
}
}
});

export default changePasswordMachine;
Loading