Skip to content

Commit 1eb7bde

Browse files
committed
Move all actual app logic into new PayloadManager component
1 parent 5059580 commit 1eb7bde

2 files changed

Lines changed: 127 additions & 117 deletions

File tree

src/App.tsx

Lines changed: 3 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,6 @@
1-
import { DragEvent, useState } from "react";
2-
import { produce } from "immer";
3-
import { useLocalStorage } from "@uidotdev/usehooks";
4-
5-
import { PayloadCard } from "./PayloadCard";
6-
import { Payload } from "./payload";
7-
import { getDataTransferItemString } from "./utils";
1+
import { PayloadManager } from "./PayloadManager";
82

93
function App() {
10-
const [payloads, setPayloads] = useLocalStorage<Payload[]>("payloads", [
11-
{
12-
id: crypto.randomUUID(),
13-
label: "Hello World",
14-
data: [
15-
{
16-
contentType: "text/plain",
17-
data: "Hello World!",
18-
},
19-
],
20-
},
21-
]);
22-
23-
const addPayload = () => {
24-
setPayloads(
25-
produce((payloads) => {
26-
payloads.unshift({
27-
id: crypto.randomUUID(),
28-
label: "New payload",
29-
data: [
30-
{
31-
contentType: "text/plain",
32-
data: "Hello World!",
33-
},
34-
],
35-
});
36-
})
37-
);
38-
};
39-
40-
const deletePayload = (index: number) => {
41-
setPayloads(
42-
produce((payloads) => {
43-
payloads.splice(index, 1);
44-
})
45-
);
46-
};
47-
48-
const importDataTransfer = async (transfer: DataTransfer) => {
49-
const newPayload: Payload = {
50-
id: crypto.randomUUID(),
51-
label: "Imported Payload",
52-
data: await Promise.all(
53-
Array.from(transfer.items).map(async (item) => {
54-
return {
55-
contentType: item.type,
56-
data: await getDataTransferItemString(item),
57-
};
58-
})
59-
),
60-
};
61-
62-
setPayloads(
63-
produce((payloads) => {
64-
payloads.unshift(newPayload);
65-
})
66-
);
67-
};
68-
69-
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
70-
event.preventDefault();
71-
event.dataTransfer.dropEffect = "copy";
72-
};
73-
74-
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
75-
event.preventDefault();
76-
if (!event.dataTransfer) return;
77-
78-
void importDataTransfer(event.dataTransfer);
79-
};
80-
814
return (
825
<div className="p-8 min-h-screen">
836
<div className="max-w-3xl mx-auto">
@@ -101,46 +24,9 @@ function App() {
10124
</div>
10225
</header>
10326

27+
{/* "Payload Manager" (actual app) */}
10428
<main className="mt-8">
105-
<div className="flex items-center justify-between gap-2">
106-
<h2 className="font-bold text-xl text-gray-800">Payloads</h2>
107-
<button
108-
className="bg-gray-200 flex items-center gap-2 text-gray-500 hover:bg-gray-500 hover:text-white active:bg-gray-400 font-medium transition px-2 py-1 rounded text-sm"
109-
onClick={addPayload}
110-
>
111-
<div className="text-xl leading-[0px] -translate-y-[2px] font-light">
112-
+
113-
</div>
114-
Create payload
115-
</button>
116-
</div>
117-
118-
{/* Drop Area */}
119-
<div
120-
className="mt-6 p-8 border-2 border-gray-300 border-dashed rounded-lg text-center text-gray-400 text-sm select-none"
121-
onDragOver={handleDragOver}
122-
onDrop={handleDrop}
123-
>
124-
Drag something and drop it here to import…
125-
</div>
126-
127-
{/* Payload List */}
128-
<div className="mt-6 flex flex-col gap-4">
129-
{payloads.map((payload, index) => (
130-
<PayloadCard
131-
key={payload.id}
132-
payload={payload}
133-
onDelete={() => deletePayload(index)}
134-
onUpdate={(newPayload) =>
135-
setPayloads(
136-
produce((payloads) => {
137-
payloads[index] = newPayload;
138-
})
139-
)
140-
}
141-
/>
142-
))}
143-
</div>
29+
<PayloadManager />
14430
</main>
14531
</div>
14632
</div>

src/PayloadManager.tsx

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { DragEvent } from "react";
2+
import { produce } from "immer";
3+
import { useLocalStorage } from "@uidotdev/usehooks";
4+
5+
import { PayloadCard } from "./PayloadCard";
6+
import { Payload } from "./payload";
7+
import { getDataTransferItemString } from "./utils";
8+
9+
export function PayloadManager() {
10+
const [payloads, setPayloads] = useLocalStorage<Payload[]>("payloads", [
11+
{
12+
id: crypto.randomUUID(),
13+
label: "Hello World",
14+
data: [
15+
{
16+
contentType: "text/plain",
17+
data: "Hello World!",
18+
},
19+
],
20+
},
21+
]);
22+
23+
const addPayload = () => {
24+
setPayloads(
25+
produce((payloads) => {
26+
payloads.unshift({
27+
id: crypto.randomUUID(),
28+
label: "New payload",
29+
data: [
30+
{
31+
contentType: "text/plain",
32+
data: "Hello World!",
33+
},
34+
],
35+
});
36+
})
37+
);
38+
};
39+
40+
const deletePayload = (index: number) => {
41+
setPayloads(
42+
produce((payloads) => {
43+
payloads.splice(index, 1);
44+
})
45+
);
46+
};
47+
48+
const importDataTransfer = async (transfer: DataTransfer) => {
49+
const newPayload: Payload = {
50+
id: crypto.randomUUID(),
51+
label: "Imported Payload",
52+
data: await Promise.all(
53+
Array.from(transfer.items).map(async (item) => {
54+
return {
55+
contentType: item.type,
56+
data: await getDataTransferItemString(item),
57+
};
58+
})
59+
),
60+
};
61+
62+
setPayloads(
63+
produce((payloads) => {
64+
payloads.unshift(newPayload);
65+
})
66+
);
67+
};
68+
69+
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
70+
event.preventDefault();
71+
event.dataTransfer.dropEffect = "copy";
72+
};
73+
74+
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
75+
event.preventDefault();
76+
if (!event.dataTransfer) return;
77+
78+
void importDataTransfer(event.dataTransfer);
79+
};
80+
81+
return (
82+
<div>
83+
<div className="flex items-center justify-between gap-2">
84+
<h2 className="font-bold text-xl text-gray-800">Payloads</h2>
85+
<button
86+
className="bg-gray-200 flex items-center gap-2 text-gray-500 hover:bg-gray-500 hover:text-white active:bg-gray-400 font-medium transition px-2 py-1 rounded text-sm"
87+
onClick={addPayload}
88+
>
89+
<div className="text-xl leading-[0px] -translate-y-[2px] font-light">
90+
+
91+
</div>
92+
Create payload
93+
</button>
94+
</div>
95+
96+
{/* Drop Area */}
97+
<div
98+
className="mt-6 p-8 border-2 border-gray-300 border-dashed rounded-lg text-center text-gray-400 text-sm select-none"
99+
onDragOver={handleDragOver}
100+
onDrop={handleDrop}
101+
>
102+
Drag something and drop it here to import…
103+
</div>
104+
105+
{/* Payload List */}
106+
<div className="mt-6 flex flex-col gap-4">
107+
{payloads.map((payload, index) => (
108+
<PayloadCard
109+
key={payload.id}
110+
payload={payload}
111+
onDelete={() => deletePayload(index)}
112+
onUpdate={(newPayload) =>
113+
setPayloads(
114+
produce((payloads) => {
115+
payloads[index] = newPayload;
116+
})
117+
)
118+
}
119+
/>
120+
))}
121+
</div>
122+
</div>
123+
);
124+
}

0 commit comments

Comments
 (0)