feat(guides): implement guide detail view with delete and export
- Render guide title, description, frames, and steps from context - Add delete and export PDF actions via useGuide hook - Add print media query to hide header, footer, and buttons - Extract guide logic into useGuide hook - Add Guide.css for view-specific styles
This commit is contained in:
parent
7cdeb98161
commit
4dd8ce8b17
4 changed files with 64 additions and 2 deletions
22
src/features/guides/hooks/useGuide.ts
Normal file
22
src/features/guides/hooks/useGuide.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { useIDB } from "../../../lib/contexts/dbinit.context";
|
||||||
|
import { useGuides } from "../../../lib/contexts/guide.context";
|
||||||
|
|
||||||
|
export default function useGuide() {
|
||||||
|
const { setGuides } = useGuides();
|
||||||
|
const { db } = useIDB();
|
||||||
|
|
||||||
|
const deleteGuide = (id: string) => {
|
||||||
|
if (!db) return;
|
||||||
|
db.delete("guides", id);
|
||||||
|
setGuides((guides) => guides.filter((guide) => guide.id !== id));
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportGuide = () => {
|
||||||
|
window.print();
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
deleteGuide,
|
||||||
|
exportGuide,
|
||||||
|
};
|
||||||
|
}
|
||||||
4
src/features/guides/routes/Guide.css
Normal file
4
src/features/guides/routes/Guide.css
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
@media print {
|
||||||
|
.guide {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,38 @@
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
|
import { useGuides } from "../../../lib/contexts/guide.context";
|
||||||
|
import useGuide from "../hooks/useGuide";
|
||||||
|
|
||||||
export default function Guide() {
|
export default function Guide() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
const { guides } = useGuides();
|
||||||
|
const { deleteGuide, exportGuide } = useGuide();
|
||||||
|
const guide = guides.find((g) => g.id === id);
|
||||||
|
|
||||||
|
if (!guide) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="guide">
|
||||||
<h1>Guide {id}</h1>
|
<h1>{guide.title}</h1>
|
||||||
|
<p>{guide.description}</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{guide.frames.map((frame, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<h2>{frame.title}</h2>
|
||||||
|
<img src={URL.createObjectURL(frame.file)} alt={frame.title} />
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
{frame.steps.map((step, stepIndex) => (
|
||||||
|
<li key={stepIndex}>{step.text}</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => deleteGuide(guide.id)}>Delete</button>
|
||||||
|
<button>Edit</button>
|
||||||
|
<button onClick={exportGuide}>Export PDF</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,3 +85,11 @@ textarea {
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
border-color: #ff7700 !important;
|
border-color: #ff7700 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue