Skip to content

Commit

Permalink
update list design, add head (#361)
Browse files Browse the repository at this point in the history
* update list design, add head

* fix back button
  • Loading branch information
correttojs authored Sep 11, 2023
1 parent 14bafa0 commit be5a878
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 36 deletions.
8 changes: 2 additions & 6 deletions test/next/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@
--background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
a {
@apply underline text-blue-600 hover:text-blue-800 visited:text-purple-600;
}

body {
Expand Down
2 changes: 2 additions & 0 deletions test/next/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import './globals.css';

export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
Expand Down
11 changes: 11 additions & 0 deletions test/next/src/app/vercel/blob/api/app/head/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as vercelBlob from '@vercel/blob';
import { NextResponse } from 'next/server';

export async function POST(request: Request): Promise<NextResponse> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const body: { url: string } = await request.json();
if (!body.url)
return NextResponse.json(new Error('url is required'), { status: 400 });

return NextResponse.json(await vercelBlob.head(body.url));
}
114 changes: 85 additions & 29 deletions test/next/src/app/vercel/blob/app/list/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ export default function AppList(): JSX.Element {
const [result, setResult] = useState<vercelBlob.ListBlobResult>();
const [searchPrefix, setSearchPrefix] = useState('');
const [urlsToRemove, setUrlsToRemove] = useState<string[]>([]);
const [head, setHead] = useState<vercelBlob.HeadBlobResult>();

const getList = useCallback(
async (cursor: string, prefix: string = searchPrefix) => {
async (
cursor: string | null,
prefix: string = searchPrefix,
reset = false
) => {
const search = new URLSearchParams();
search.set('limit', '10');
if (prefix) {
Expand All @@ -19,9 +24,13 @@ export default function AppList(): JSX.Element {
if (cursor) {
search.set('cursor', cursor);
}
if (reset) {
setResult(undefined);
}
const data = (await fetch(`${API_ROOT}/list?${search.toString()}`).then(
(r) => r.json()
)) as vercelBlob.ListBlobResult;

setResult({
...data,
blobs: cursor ? [...(result?.blobs || []), ...data.blobs] : data.blobs,
Expand All @@ -48,39 +57,67 @@ export default function AppList(): JSX.Element {
'Content-Type': 'application/json',
},
});
await getList('', searchPrefix);
if (result) {
setResult({
...result,
blobs: result.blobs.filter((b) => !urls.includes(b.url)),
});
}
};

const handleHead = async (url: string): Promise<void> => {
const data = (await fetch(`${API_ROOT}/head`, {
method: 'POST',
body: JSON.stringify({ url }),
headers: {
'Content-Type': 'application/json',
},
}).then((r) => r.json())) as vercelBlob.HeadBlobResult;
setHead(data);
};

if (!result) {
return <div>Loading...</div>;
}

return (
<>
<div className="p-4 flex flex-col gap-4">
<h1>App Router List blob items</h1>
<input
onChange={(e): void => setSearchPrefix(e.target.value)}
placeholder="prefix"
type="text"
value={searchPrefix}
/>
<button
onClick={(): void => void getList('', searchPrefix)}
type="button"
>
Search
</button>

<button
onClick={(): void => void handleDelete(urlsToRemove)}
type="button"
>
Multi-delete
</button>
<ul>
<div className="flex gap-2">
<input
className="shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
onChange={(e): void => setSearchPrefix(e.target.value)}
placeholder="prefix"
type="text"
value={searchPrefix}
/>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={(): void => void getList('', searchPrefix)}
type="button"
>
Search
</button>
<button
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
onClick={(): void => void handleDelete(urlsToRemove)}
type="button"
>
Multi-delete
</button>
</div>
<ul className="flex flex-col gap-2">
<li className="grid grid-cols-7 gap-2">
<p>Select</p>
<p>path</p>
<p>size</p>
<p>download</p>
<p>date</p>
</li>
{result.blobs.map((blob) => (
<li key={blob.pathname}>
<li className="grid grid-cols-7 gap-2" key={blob.pathname}>
<input
className="w-auto"
onChange={(e): void => {
if (e.target.checked) {
setUrlsToRemove([...urlsToRemove, blob.url]);
Expand All @@ -90,9 +127,26 @@ export default function AppList(): JSX.Element {
}}
type="checkbox"
/>
{blob.pathname} - {blob.size} -
{new Date(blob.uploadedAt).toISOString()} - {blob.url}
<p>{blob.pathname}</p>
<p>{blob.size}</p>
<a
className="text-underline text-blue-500 hover:text-blue-800"
href={blob.url}
rel="noopener"
target="_blank"
>
download
</a>
<p>{new Date(blob.uploadedAt).toISOString()} </p>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={(): void => void handleHead(blob.url)}
type="button"
>
Head
</button>
<button
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
onClick={(): void => void handleDelete([blob.url])}
type="button"
>
Expand All @@ -102,8 +156,9 @@ export default function AppList(): JSX.Element {
))}
</ul>
{result.hasMore && result.cursor ? (
<>
<div>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={(): void =>
void getList(result.cursor ?? '', searchPrefix)
}
Expand All @@ -112,8 +167,9 @@ export default function AppList(): JSX.Element {
Load More
</button>
<div>Cursor: {result.cursor}</div>
</>
</div>
) : null}
</>
{head ? <div>{JSON.stringify(head)}</div> : null}
</div>
);
}
4 changes: 3 additions & 1 deletion test/next/src/app/vercel/blob/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export default function Layout({
}): JSX.Element {
return (
<div>
<a href="/">← Home</a>
<div className="flex gap-2">
<a href="/">← Home</a> <a href="/vercel/blob">← Blob</a>
</div>
{children}
</div>
);
Expand Down

1 comment on commit be5a878

@vercel
Copy link

@vercel vercel bot commented on be5a878 Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.