Skip to content

Commit 5d139a4

Browse files
committed
WEB-98 Replace useRunAction hook with useTransition + runAction util
1 parent 8279b76 commit 5d139a4

6 files changed

Lines changed: 87 additions & 82 deletions

File tree

src/app/editor/MediaLibrary.tsx

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"use client";
22

3-
import { useRef, useState } from "react";
3+
import { useRef, useState, useTransition } from "react";
44
import { File as FileIcon, Trash2, Copy } from "lucide-react";
55
import { uploadMediaAction, deleteMediaAction } from "../../lib/media-actions";
66
import type { MediaFile } from "../../lib/types";
7-
import { useRunAction } from "./useRunAction";
7+
import { runAction } from "./runAction";
88

99
function formatFileSize(bytes: number): string {
1010
if (bytes < 1024) return `${bytes} B`;
@@ -111,24 +111,32 @@ function MediaCard({
111111
}
112112

113113
export function MediaLibrary({ files: initialFiles }: { files: MediaFile[] }) {
114-
const [isPending, run] = useRunAction();
114+
const [isPending, startTransition] = useTransition();
115115
const [files, setFiles] = useState(initialFiles);
116116

117-
async function handleUpload(file: File) {
117+
function handleUpload(file: File) {
118118
const formData = new FormData();
119119
formData.append("file", file);
120-
const result = await run(uploadMediaAction(formData));
121-
if (result.success) {
122-
setFiles((prev) => [...prev, result.data]);
123-
}
120+
startTransition(async () => {
121+
const result = await runAction(uploadMediaAction(formData));
122+
if (result.success) {
123+
setFiles((prev) => [...prev, result.data]);
124+
} else {
125+
alert(result.error);
126+
}
127+
});
124128
}
125129

126-
async function handleDelete(file: MediaFile) {
130+
function handleDelete(file: MediaFile) {
127131
if (!window.confirm(`Delete "${file.name}"?`)) return;
128-
const result = await run(deleteMediaAction({ name: file.name }));
129-
if (result.success) {
130-
setFiles((prev) => prev.filter((f) => f.name !== file.name));
131-
}
132+
startTransition(async () => {
133+
const result = await runAction(deleteMediaAction({ name: file.name }));
134+
if (result.success) {
135+
setFiles((prev) => prev.filter((f) => f.name !== file.name));
136+
} else {
137+
alert(result.error);
138+
}
139+
});
132140
}
133141

134142
return (

src/app/editor/RouteTable.tsx

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"use client";
22

33
import Link from "next/link";
4-
import { useRef, useState } from "react";
4+
import { useRef, useState, useTransition } from "react";
55
import { Check, SquarePen, Trash2, X } from "lucide-react";
66
import {
77
createRouteAction,
88
updateRouteAction,
99
deleteRouteAction,
1010
} from "../../lib/actions";
11-
import { useRunAction } from "./useRunAction";
11+
import { runAction } from "./runAction";
1212

1313
type RouteRow = {
1414
id: number;
@@ -181,33 +181,45 @@ export function RouteTable({
181181
routes: RouteRow[];
182182
documents: DocumentOption[];
183183
}) {
184-
const [isPending, run] = useRunAction();
184+
const [isPending, startTransition] = useTransition();
185185
const [creating, setCreating] = useState(false);
186186
const [routes, setRoutes] = useState(initialRoutes);
187187

188-
async function handleCreate(path: string, documentId: number) {
188+
function handleCreate(path: string, documentId: number) {
189189
setCreating(false);
190-
const result = await run(createRouteAction({ path, documentId }));
191-
if (result.success) {
192-
const docName = documents.find((d) => d.id === documentId)?.name ?? "";
193-
setRoutes((prev) => [...prev, { id: result.data.routeId, path, documentId, documentName: docName }]);
194-
}
190+
startTransition(async () => {
191+
const result = await runAction(createRouteAction({ path, documentId }));
192+
if (result.success) {
193+
const docName = documents.find((d) => d.id === documentId)?.name ?? "";
194+
setRoutes((prev) => [...prev, { id: result.data.routeId, path, documentId, documentName: docName }]);
195+
} else {
196+
alert(result.error);
197+
}
198+
});
195199
}
196200

197-
async function handleUpdate(id: number, path: string, documentId: number) {
198-
const result = await run(updateRouteAction({ id, path, documentId }));
199-
if (result.success) {
200-
const docName = documents.find((d) => d.id === documentId)?.name ?? "";
201-
setRoutes((prev) => prev.map((r) => (r.id === id ? { ...r, path, documentId, documentName: docName } : r)));
202-
}
201+
function handleUpdate(id: number, path: string, documentId: number) {
202+
startTransition(async () => {
203+
const result = await runAction(updateRouteAction({ id, path, documentId }));
204+
if (result.success) {
205+
const docName = documents.find((d) => d.id === documentId)?.name ?? "";
206+
setRoutes((prev) => prev.map((r) => (r.id === id ? { ...r, path, documentId, documentName: docName } : r)));
207+
} else {
208+
alert(result.error);
209+
}
210+
});
203211
}
204212

205-
async function handleDelete(route: RouteRow) {
213+
function handleDelete(route: RouteRow) {
206214
if (!window.confirm(`Delete route "${route.path}"?`)) return;
207-
const result = await run(deleteRouteAction({ id: route.id }));
208-
if (result.success) {
209-
setRoutes((prev) => prev.filter((r) => r.id !== route.id));
210-
}
215+
startTransition(async () => {
216+
const result = await runAction(deleteRouteAction({ id: route.id }));
217+
if (result.success) {
218+
setRoutes((prev) => prev.filter((r) => r.id !== route.id));
219+
} else {
220+
alert(result.error);
221+
}
222+
});
211223
}
212224

213225
return (

src/app/editor/[id]/SaveButton.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"use client";
22

33
import { createUsePuck } from "@puckeditor/core";
4-
import { useState } from "react";
4+
import { useTransition } from "react";
55
import { useDocumentContext } from "./client";
66
import { saveVersionAction } from "../../../lib/actions";
7+
import { runAction } from "../runAction";
78

89
const usePuck = createUsePuck();
910

@@ -12,21 +13,20 @@ export function SaveButton() {
1213
const dispatch = usePuck((s) => s.dispatch);
1314
const { documentId, addVersion } = useDocumentContext();
1415

15-
const [isSaving, setIsSaving] = useState(false);
16+
const [isSaving, startTransition] = useTransition();
1617

17-
const handleSave = async () => {
18-
setIsSaving(true);
19-
const result = await saveVersionAction({ documentId, content: data });
18+
const handleSave = () => {
19+
startTransition(async () => {
20+
const result = await runAction(saveVersionAction({ documentId, content: data }));
2021

21-
if (result.success === false) {
22-
alert(`Error: ${result.error}`);
23-
setIsSaving(false);
24-
return;
25-
}
22+
if (result.success === false) {
23+
alert(result.error);
24+
return;
25+
}
2626

27-
dispatch({ type: "setData", data });
28-
addVersion(result.data.version);
29-
setIsSaving(false);
27+
dispatch({ type: "setData", data });
28+
addVersion(result.data.version);
29+
});
3030
};
3131

3232
return (

src/app/editor/[id]/VersionPluginContainer.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
"use client";
22

3-
import { useState } from "react";
3+
import { useTransition } from "react";
44
import { useRouter } from "next/navigation";
55
import { useDocumentContext } from "./client";
66
import { publishVersionAction } from "../../../lib/actions";
7+
import { runAction } from "../runAction";
78
import { VersionListPanel } from "./VersionListPanel";
89

910
export function VersionPluginContainer() {
1011
const router = useRouter();
1112
const { documentId, versionId, publishedVersionId, versions, setPublishedVersionId } = useDocumentContext();
12-
const [isPublishing, setIsPublishing] = useState(false);
13+
const [isPublishing, startTransition] = useTransition();
1314

14-
const handlePublishVersion = async (targetVersionId: number) => {
15-
setIsPublishing(true);
16-
const result = await publishVersionAction({ documentId, versionId: targetVersionId });
15+
const handlePublishVersion = (targetVersionId: number) => {
16+
startTransition(async () => {
17+
const result = await runAction(publishVersionAction({ documentId, versionId: targetVersionId }));
1718

18-
if (result.success === false) {
19-
alert(`Error: ${result.error}`);
20-
setIsPublishing(false);
21-
return;
22-
}
19+
if (result.success === false) {
20+
alert(result.error);
21+
return;
22+
}
2323

24-
setPublishedVersionId(targetVersionId);
25-
setIsPublishing(false);
24+
setPublishedVersionId(targetVersionId);
25+
});
2626
};
2727

2828
const handleLoadVersion = (versionIdToLoad: number) => {

src/app/editor/runAction.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { ActionResult } from "../../lib/types";
2+
3+
export async function runAction<T>(action: Promise<ActionResult<T>>): Promise<ActionResult<T>> {
4+
try {
5+
return await action;
6+
} catch {
7+
return { success: false, error: "Something went wrong. Please try again." };
8+
}
9+
}

src/app/editor/useRunAction.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)