diff --git a/src/main.tsx b/src/main.tsx index be4ab51..7687115 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -28,7 +28,7 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( } /> } /> - } /> + } /> } /> diff --git a/src/pages/CreatePattern.module.css b/src/pages/CreatePattern.module.css new file mode 100644 index 0000000..3efe96f --- /dev/null +++ b/src/pages/CreatePattern.module.css @@ -0,0 +1,15 @@ +@layer pages { + .create_form { + border-radius: calc(var(--border-radius) * 2); + background-color: var(--color-surface-container); + } + .form_row { + display: flex; + flex-direction: row; + align-items: center; + gap: calc(var(--spacing) * 3); + .pattern_name_input { + min-width: 30em; + } + } +} diff --git a/src/pages/CreatePattern.tsx b/src/pages/CreatePattern.tsx new file mode 100644 index 0000000..649f428 --- /dev/null +++ b/src/pages/CreatePattern.tsx @@ -0,0 +1,80 @@ +import { invoke } from '@tauri-apps/api/core'; +import cx from 'clsx'; +import { useSetAtom } from 'jotai'; +import { FC, useActionState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { NotificationType, ToastDuration, useNotification } from '../components/Notifications'; +import { CurrentPatternAtom, Pattern } from '../context/Patterns'; +import styles from './CreatePattern.module.css'; + +const CreatePattern: FC = () => { + const { showToast } = useNotification(); + const navigate = useNavigate(); + const loadPattern = useSetAtom(CurrentPatternAtom); + + const [errState, handleFormSubmit] = useActionState(async (state, formData) => { + const patternName = formData.get('pattern_name') as string | null; + + if (patternName === null || patternName.length === 0) { + showToast( + NotificationType.ERROR, + 'Please enter a pattern name.', + 'material-symbols-light:error-outline', + ToastDuration.MEDIUM, + ); + return true; + } + + const newPattern = new Pattern(); + newPattern.name = patternName; + + try { + await invoke('save_pattern', { pattern: newPattern }); + const reloadedPattern = await invoke('get_pattern', { patternId: newPattern.id }); + if (!reloadedPattern) { + showToast( + NotificationType.ERROR, + 'Failed to reload the created pattern. Please try again.', + 'material-symbols-light:error-outline', + ToastDuration.MEDIUM, + ); + loadPattern(null); + navigate('/library'); + return true; + } + loadPattern(reloadedPattern); + navigate('./edit'); + } catch (e) { + console.error('[save pattern]', e); + loadPattern(null); + showToast( + NotificationType.ERROR, + 'Failed to create pattern. Please try again.', + 'material-symbols-light:error-outline', + ToastDuration.MEDIUM, + ); + } + + return false; + }, false); + + return ( +
+
+
+ + +
+
+
+ ); +}; + +export default CreatePattern; diff --git a/src/pages/PatternNavigator.tsx b/src/pages/PatternNavigator.tsx new file mode 100644 index 0000000..9f203d4 --- /dev/null +++ b/src/pages/PatternNavigator.tsx @@ -0,0 +1,12 @@ +import { useAtomValue } from 'jotai'; +import { FC } from 'react'; +import { Navigate } from 'react-router-dom'; +import { CurrentPatternAtom } from '../context/Patterns'; + +const PatternNavigator: FC = () => { + const currentPattern = useAtomValue(CurrentPatternAtom); + + return currentPattern === null ? : ; +}; + +export default PatternNavigator;