feat: add settings page and fix sidebar layout
- Add Settings route, component, and useSettings hook - Add Settings link to nav - Fix sidebar to use fixed positioning instead of flexbox - Fix footer to stay within sidebar column - Reset form after save in useGuideForm - Use SubmitEvent type for handleSaveGuide
This commit is contained in:
parent
eb30a325db
commit
c4a8f975c5
6 changed files with 47 additions and 6 deletions
|
|
@ -22,11 +22,14 @@ function App() {
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
<Link to="/settings">Settings</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>SnapSteps © {new Date().getFullYear()}</footer>
|
<footer>SnapSteps © {new Date().getFullYear()}</footer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ export default function useGuideForm(initial?: CompiledGuideType) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveGuide = async (e: React.FormEvent<HTMLFormElement>) => {
|
const handleSaveGuide = async (e: React.SubmitEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!db) return;
|
if (!db) return;
|
||||||
|
|
||||||
|
|
@ -138,6 +138,8 @@ export default function useGuideForm(initial?: CompiledGuideType) {
|
||||||
setGuide(makeEmptyGuide());
|
setGuide(makeEmptyGuide());
|
||||||
setFrames([]);
|
setFrames([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.target.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
17
src/features/guides/hooks/useSettings.ts
Normal file
17
src/features/guides/hooks/useSettings.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { useIDB } from "../../../lib/contexts/dbinit.context";
|
||||||
|
import { useGuides } from "../../../lib/contexts/guide.context";
|
||||||
|
|
||||||
|
export const useSettings = () => {
|
||||||
|
const { db } = useIDB();
|
||||||
|
const { setGuides } = useGuides();
|
||||||
|
|
||||||
|
const deleteAllGuides = () => {
|
||||||
|
if (!db) return;
|
||||||
|
db.clear("guides");
|
||||||
|
setGuides([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
deleteAllGuides,
|
||||||
|
};
|
||||||
|
};
|
||||||
11
src/features/guides/routes/Settings.tsx
Normal file
11
src/features/guides/routes/Settings.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { useSettings } from "../hooks/useSettings";
|
||||||
|
|
||||||
|
export default function Settings() {
|
||||||
|
const { deleteAllGuides } = useSettings();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button onClick={deleteAllGuides}>Delete All Guides</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import App from "./App.tsx";
|
||||||
import GuideForm from "./features/guides/routes/GuideForm.tsx";
|
import GuideForm from "./features/guides/routes/GuideForm.tsx";
|
||||||
import NotFound from "./components/not-found/NotFound.tsx";
|
import NotFound from "./components/not-found/NotFound.tsx";
|
||||||
import Guide from "./features/guides/routes/Guide.tsx";
|
import Guide from "./features/guides/routes/Guide.tsx";
|
||||||
|
import Settings from "./features/guides/routes/Settings.tsx";
|
||||||
|
|
||||||
export const router = createBrowserRouter([
|
export const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
|
|
@ -21,6 +22,10 @@ export const router = createBrowserRouter([
|
||||||
path: "/edit-guide/:id",
|
path: "/edit-guide/:id",
|
||||||
Component: GuideForm,
|
Component: GuideForm,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/settings",
|
||||||
|
Component: Settings,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
font-family: system-ui, Arial, sans-serif;
|
font-family: system-ui, Arial, sans-serif;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
display: flex;
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,7 +21,9 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
flex: 0 0 var(--sidebar-width);
|
position: fixed;
|
||||||
|
height: 100%;
|
||||||
|
width: var(--sidebar-width);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -31,18 +33,19 @@ header {
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
margin-left: var(--sidebar-width);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding-block: 0.5rem;
|
padding: 0.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
width: var(--sidebar-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue