mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
feat: implement dynamic routing for editor to support persistent letter editing via public_id
This commit is contained in:
@@ -72,7 +72,7 @@ export default function App() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={ROUTES.WRITE}
|
path={ROUTES.WRITE()}
|
||||||
element={
|
element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<Editor />
|
<Editor />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const ROUTES = {
|
|||||||
ACTIVATE: "/activate/:uidb64/:token",
|
ACTIVATE: "/activate/:uidb64/:token",
|
||||||
LOGIN: "/login",
|
LOGIN: "/login",
|
||||||
DRAWER: "/drawer",
|
DRAWER: "/drawer",
|
||||||
WRITE: "/quill",
|
WRITE: (public_id?: string) =>
|
||||||
|
`/quill/${public_id ? public_id : ":public_id?"}`,
|
||||||
READ: "/read",
|
READ: "/read",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
} from "@phosphor-icons/react";
|
} from "@phosphor-icons/react";
|
||||||
import type { FabricObject } from "fabric";
|
import type { FabricObject } from "fabric";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { api } from "../api/apiClient";
|
import { api } from "../api/apiClient";
|
||||||
import {
|
import {
|
||||||
type CanvasTools,
|
type CanvasTools,
|
||||||
@@ -13,11 +14,14 @@ import {
|
|||||||
} from "../components/ui/ComposeCanvas";
|
} from "../components/ui/ComposeCanvas";
|
||||||
import DateDisplay from "../components/ui/DateDisplay";
|
import DateDisplay from "../components/ui/DateDisplay";
|
||||||
import { endpoints } from "../config/endpoints";
|
import { endpoints } from "../config/endpoints";
|
||||||
|
import { ROUTES } from "../config/routes";
|
||||||
import { useKeyStore } from "../store/useKeyStore";
|
import { useKeyStore } from "../store/useKeyStore";
|
||||||
import { CryptoUtils } from "../utils/crypto";
|
import { CryptoUtils } from "../utils/crypto";
|
||||||
|
|
||||||
export default function Editor() {
|
export default function Editor() {
|
||||||
const [_letterId] = useState(() => crypto.randomUUID());
|
const { public_id } = useParams();
|
||||||
|
const letterIdRef = useRef<string>(public_id ?? null);
|
||||||
|
const navigate = useNavigate();
|
||||||
const [isSealing, setIsSealing] = useState(false);
|
const [isSealing, setIsSealing] = useState(false);
|
||||||
const [isSaveSuccess, setIsSaveSuccess] = useState(false);
|
const [isSaveSuccess, setIsSaveSuccess] = useState(false);
|
||||||
|
|
||||||
@@ -35,6 +39,10 @@ export default function Editor() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function handleSeal(): Promise<void> {
|
async function handleSeal(): Promise<void> {
|
||||||
|
if (!public_id) {
|
||||||
|
letterIdRef.current = crypto.randomUUID();
|
||||||
|
navigate(ROUTES.WRITE(letterIdRef.current), { replace: true });
|
||||||
|
}
|
||||||
if (isSealing) return;
|
if (isSealing) return;
|
||||||
setIsSealing(true);
|
setIsSealing(true);
|
||||||
const cryptoUtils = new CryptoUtils();
|
const cryptoUtils = new CryptoUtils();
|
||||||
@@ -85,7 +93,7 @@ export default function Editor() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("public_id", _letterId);
|
formData.append("public_id", letterIdRef.current);
|
||||||
formData.append("type", "SENT");
|
formData.append("type", "SENT");
|
||||||
formData.append("status", "SEALED");
|
formData.append("status", "SEALED");
|
||||||
formData.append("encrypted_content", encrypted_letter.encrypted_content);
|
formData.append("encrypted_content", encrypted_letter.encrypted_content);
|
||||||
@@ -96,7 +104,7 @@ export default function Editor() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.post(endpoints.LETTERS, formData);
|
await api.put(`${endpoints.LETTERS}${letterIdRef.current}/`, formData);
|
||||||
setIsSaveSuccess(true);
|
setIsSaveSuccess(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsSaveSuccess(false);
|
setIsSaveSuccess(false);
|
||||||
@@ -111,13 +119,13 @@ export default function Editor() {
|
|||||||
return (
|
return (
|
||||||
<section className="flex-1 overflow-y-auto scrollbar-hide px-2 py-12 bg-base-300">
|
<section className="flex-1 overflow-y-auto scrollbar-hide px-2 py-12 bg-base-300">
|
||||||
{isSaveSuccess && (
|
{isSaveSuccess && (
|
||||||
<div className="modal bg-transparent modal-open">
|
<div className="modal modal-open bg-transparent backdrop-blur-md transition-all duration-300 ease-in-out">
|
||||||
<div className="modal-box bg-base-100">
|
<div className="modal-box bg-transparent">
|
||||||
<div className="alert alert-success">
|
<div className="alert alert-success">
|
||||||
<DownloadSimpleIcon size={18} weight="bold" />
|
<DownloadSimpleIcon size={18} weight="bold" />
|
||||||
<h3 className="font-bold text-lg">Letter saved successfully!</h3>
|
<h3 className="font-bold text-lg">Your letter is sealed!</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-action">
|
{/* <div className="modal-action">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-primary"
|
className="btn btn-primary"
|
||||||
@@ -125,7 +133,7 @@ export default function Editor() {
|
|||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user