dashboard

This commit is contained in:
Karol Wypchlo 2021-02-05 15:45:22 +01:00
parent 8618759f75
commit 0c148cf011
12 changed files with 571 additions and 35 deletions

View File

@ -8,13 +8,16 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@fontsource/metropolis": "^4.1.0",
"@ory/kratos-client": "^0.5.4-alpha.1", "@ory/kratos-client": "^0.5.4-alpha.1",
"autoprefixer": "^10.2.4", "autoprefixer": "^10.2.4",
"dayjs": "^1.10.4",
"express-jwt": "^6.0.0", "express-jwt": "^6.0.0",
"jwks-rsa": "^1.12.2", "jwks-rsa": "^1.12.2",
"next": "^10.0.6", "next": "^10.0.6",
"postcss": "^8.2.4", "postcss": "^8.2.4",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"pretty-bytes": "^5.5.0",
"react": "17.0.1", "react": "17.0.1",
"react-dom": "17.0.1", "react-dom": "17.0.1",
"swr": "^0.4.1", "swr": "^0.4.1",

View File

@ -212,6 +212,7 @@ export default function Layout({ title, children }) {
</div> </div>
</header> </header>
</div> </div>
<main className="-mt-32"> <main className="-mt-32">
<div className="max-w-7xl mx-auto pb-12 px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto pb-12 px-4 sm:px-6 lg:px-8">
{/* Replace with your content */} {/* Replace with your content */}
@ -223,6 +224,13 @@ export default function Layout({ title, children }) {
{/* /End replace */} {/* /End replace */}
</div> </div>
</main> </main>
<footer>
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 lg:max-w-7xl text-sm text-gray-500 text-center sm:text-left">
<span className="block sm:inline">© 2021 Skynet Labs Inc.</span>{" "}
<span className="block sm:inline">All rights reserved.</span>
</div>
</footer>
</div> </div>
); );
} }

View File

@ -1,11 +1,11 @@
const rowsPerPage = 10; const pageSize = 10;
export default function Table({ data, headers, actions, page, setPage }) { export default function Table({ data, headers, actions, page, setPage }) {
const lastPage = Math.ceil(data.length / rowsPerPage); const lastPage = Math.ceil(data.length / pageSize);
if (page > lastPage) setPage(lastPage); if (page > lastPage) setPage(lastPage);
const dataSlice = data.slice(rowsPerPage * (page - 1), rowsPerPage * (page - 1) + rowsPerPage); const dataSlice = data.slice(pageSize * (page - 1), pageSize * (page - 1) + pageSize);
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
@ -34,9 +34,9 @@ export default function Table({ data, headers, actions, page, setPage }) {
<tbody> <tbody>
{dataSlice.map((row, index) => ( {dataSlice.map((row, index) => (
<tr className={index % 2 ? "bg-white" : "bg-gray-50"} key={index}> <tr className={index % 2 ? "bg-white" : "bg-gray-50"} key={index}>
{headers.map(({ key, name }) => ( {headers.map(({ key, formatter }) => (
<td key={key} className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"> <td key={key} className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{row[key] || "-"} {(formatter ? formatter(row[key]) : row[key]) || "-"}
</td> </td>
))} ))}
{actions.map(({ key, name, action }) => ( {actions.map(({ key, name, action }) => (
@ -57,10 +57,8 @@ export default function Table({ data, headers, actions, page, setPage }) {
> >
<div className="hidden sm:block"> <div className="hidden sm:block">
<p className="text-sm text-gray-700"> <p className="text-sm text-gray-700">
Showing <span className="font-medium">{rowsPerPage * (page - 1) + 1}</span> to{" "} Showing <span className="font-medium">{data.length ? pageSize * (page - 1) + 1 : 0}</span> to{" "}
<span className="font-medium"> <span className="font-medium">{pageSize * page > data.length ? data.length : pageSize * page}</span>{" "}
{rowsPerPage * page > data.length ? data.length : rowsPerPage * page}
</span>{" "}
of <span className="font-medium">{data.length}</span> results of <span className="font-medium">{data.length}</span> results
</p> </p>
</div> </div>

View File

@ -1,4 +1,5 @@
import "tailwindcss/tailwind.css"; import "tailwindcss/tailwind.css";
import "@fontsource/metropolis/all.css";
function MyApp({ Component, pageProps }) { function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />; return <Component {...pageProps} />;

View File

@ -0,0 +1,4 @@
export default (req, res) => {
res.statusCode = 200;
res.json(require("./downloads.json"));
};

View File

@ -0,0 +1,38 @@
[
{
"skylink": "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw",
"name": "ugabuga.pdf",
"size": 123123,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg",
"name": "ugabuga.pdf",
"size": 8912739812,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ",
"name": "ugabuga.pdf",
"size": 123123,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA",
"name": "ugabuga.pdf",
"size": 83943,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ",
"name": "ugabuga.pdf",
"size": 3290489120,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA",
"name": "ugabuga.pdf",
"size": 1290389,
"uploadedOn": "2020-04-02T08:02:17-05:00"
}
]

View File

@ -0,0 +1,4 @@
export default (req, res) => {
res.statusCode = 200;
res.json(require("./uploads.json"));
};

View File

@ -0,0 +1,38 @@
[
{
"skylink": "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw",
"name": "ugabuga.pdf",
"size": 123123,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg",
"name": "ugabuga.pdf",
"size": 8912739812,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ",
"name": "ugabuga.pdf",
"size": 123123,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA",
"name": "ugabuga.pdf",
"size": 83943,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ",
"name": "ugabuga.pdf",
"size": 3290489120,
"uploadedOn": "2020-04-02T08:02:17-05:00"
},
{
"skylink": "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA",
"name": "ugabuga.pdf",
"size": 1290389,
"uploadedOn": "2020-04-02T08:02:17-05:00"
}
]

View File

@ -1,28 +1,26 @@
import dayjs from "dayjs";
import prettyBytes from "pretty-bytes";
import { useState } from "react"; import { useState } from "react";
import useSWR from "swr";
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import Table from "../components/Table"; import Table from "../components/Table";
const data = [ const fetcher = (url) => fetch(url).then((r) => r.json());
{ skylink: "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw", size: "1 KB", date: "today" },
{ skylink: "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg", size: "102 MB", date: "today" },
{ skylink: "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ", size: "141 KB", date: "today" },
{ skylink: "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA", size: "1 KB", date: "today" },
{ skylink: "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ", size: "0 KB", date: "today" },
{ skylink: "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA", size: "1.3 MB", date: "today" },
];
const headers = [ const headers = [
{ key: "name", name: "Name" },
{ key: "skylink", name: "Skylink" }, { key: "skylink", name: "Skylink" },
{ key: "size", name: "Size" }, { key: "size", name: "Size", formatter: prettyBytes },
{ key: "date", name: "Access time" }, { key: "downloadedOn", name: "Accessed on", formatter: (date) => dayjs(date).format("YYYY-MM-DD HH:mm:ss") },
]; ];
const actions = []; const actions = [];
export default function Downloads() { export default function Downloads() {
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const { data, error } = useSWR("/api/fixtures/downloads", fetcher);
return ( return (
<Layout title="Your downloads"> <Layout title="Your downloads">
<Table data={data} headers={headers} actions={actions} page={page} setPage={setPage} /> {data && <Table data={data} headers={headers} actions={actions} page={page} setPage={setPage} />}
</Layout> </Layout>
); );
} }

View File

@ -1,5 +1,447 @@
import prettyBytes from "pretty-bytes";
import Link from "next/link";
import useSWR from "swr";
import Layout from "../components/Layout"; import Layout from "../components/Layout";
const fetcher = (url) => fetch(url).then((r) => r.json());
export default function Home() { export default function Home() {
return <Layout title="Dashboard"></Layout>; const { data: user, error } = useSWR("/api/user", fetcher);
return (
<Layout title="Dashboard">
<div className="bg-white rounded-lg shadow px-5 py-6 sm:px-6">
<dl className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
<div className="flex flex-col bg-white overflow-hidden shadow rounded-lg">
<div className="flex-grow px-4 py-5 sm:p-6">
<div className="flex items-center">
<div className="flex-shrink-0 bg-indigo-500 rounded-md p-3">
{/* Heroicon name: outline/users */}
<svg
className="h-6 w-6 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
/>
</svg>
</div>
<div className="ml-5 w-0 flex-1">
<dt className="text-sm font-medium text-gray-500 truncate">Current plan</dt>
<dd className="flex items-baseline">
<div className="text-2xl font-semibold text-gray-900">Free</div>
</dd>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-4 sm:px-6">
<div className="text-sm">
<Link href="/payments">
<a className="font-medium text-indigo-600 hover:text-indigo-500">
View current payments<span className="sr-only">Total Subscribers stats</span>
</a>
</Link>
</div>
</div>
</div>
<div className="flex flex-col bg-white overflow-hidden shadow rounded-lg">
<div className="flex-grow px-4 py-5 sm:p-6">
<div className="flex items-center">
<div className="flex-shrink-0 bg-green-500 rounded-md p-3">
{/* Heroicon name: outline/cursor-click */}
<svg
className="h-6 w-6 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"
/>
</svg>
</div>
<div className="ml-5 w-0 flex-1">
<dt className="text-sm font-medium text-gray-500 truncate">Current period download</dt>
<dd className="flex items-baseline">
<div className="text-2xl font-semibold text-grey-900">{prettyBytes(189237982173)}</div>
</dd>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-4 sm:px-6">
<div className="text-sm">
<Link href="/downloads">
<a className="font-medium text-indigo-600 hover:text-indigo-500">View all downloads</a>
</Link>
</div>
</div>
</div>
<div className="flex flex-col bg-white overflow-hidden shadow rounded-lg">
<div className="flex-grow px-4 py-5 sm:p-6">
<div className="flex items-center">
<div className="flex-shrink-0 bg-red-500 rounded-md p-3">
{/* Heroicon name: outline/cursor-click */}
<svg
className="h-6 w-6 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
</div>
<div className="ml-5 w-0 flex-1">
<dt className="text-sm font-medium text-gray-500 truncate">Current period upload</dt>
<dd className="flex items-baseline">
<div className="text-2xl font-semibold text-grey-900">{prettyBytes(9237982173)}</div>
</dd>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-4 sm:px-6">
<div className="text-sm">
<Link href="/uploads">
<a className="font-medium text-indigo-600 hover:text-indigo-500">View all uploads</a>
</Link>
</div>
</div>
</div>
</dl>
{/* ============ */}
<div className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-2">
<div className="flex flex-col">
<div className="pb-5 border-b border-gray-200 sm:flex sm:items-center sm:justify-between">
<h3 className="text-lg leading-6 font-medium text-gray-900">Recent downloads</h3>
</div>
{/* This example requires Tailwind CSS v2.0+ */}
<div className="bg-white shadow overflow-hidden sm:rounded-md">
<ul className="divide-y divide-gray-200">
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"
/>
</svg>
{prettyBytes(12389128893)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"
/>
</svg>
{prettyBytes(1112)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"
/>
</svg>
{prettyBytes(4124)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
<div className="flex flex-col">
<div className="pb-5 border-b border-gray-200">
<h3 className="text-lg leading-6 font-medium text-gray-900">Recent uploads</h3>
</div>
{/* This example requires Tailwind CSS v2.0+ */}
<div className="bg-white shadow overflow-hidden sm:rounded-md">
<ul className="divide-y divide-gray-200">
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
{prettyBytes(234674)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
{prettyBytes(43215)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
<li>
<a href="#" className="block hover:bg-gray-50">
<div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-indigo-600 truncate">Bitcoin.pdf</p>
</div>
<div className="mt-2 sm:flex sm:justify-between">
<div className="sm:flex">
<p className="flex items-center text-sm text-gray-500">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
{prettyBytes(123)}
</p>
</div>
<div className="mt-2 flex items-center text-sm text-gray-500 sm:mt-0">
{/* Heroicon name: solid/calendar */}
<svg
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"
clipRule="evenodd"
/>
</svg>
<time dateTime="2020-01-07">January 7, 2020</time>
</div>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</Layout>
);
} }

View File

@ -1,28 +1,26 @@
import dayjs from "dayjs";
import prettyBytes from "pretty-bytes";
import { useState } from "react"; import { useState } from "react";
import useSWR from "swr";
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import Table from "../components/Table"; import Table from "../components/Table";
const data = [ const fetcher = (url) => fetch(url).then((r) => r.json());
{ skylink: "PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw", size: "1 KB", date: "today" },
{ skylink: "XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg", size: "102 MB", date: "today" },
{ skylink: "IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ", size: "141 KB", date: "today" },
{ skylink: "_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA", size: "1 KB", date: "today" },
{ skylink: "AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ", size: "0 KB", date: "today" },
{ skylink: "CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA", size: "1.3 MB", date: "today" },
];
const headers = [ const headers = [
{ key: "name", name: "Name" },
{ key: "skylink", name: "Skylink" }, { key: "skylink", name: "Skylink" },
{ key: "size", name: "Size" }, { key: "size", name: "Size", formatter: prettyBytes },
{ key: "date", name: "Uploaded on" }, { key: "uploadedOn", name: "Uploaded on", formatter: (date) => dayjs(date).format("YYYY-MM-DD HH:mm:ss") },
]; ];
const actions = [{ key: "delete", name: "Delete", action: () => undefined }]; const actions = [];
export default function Uploads() { export default function Downloads() {
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const { data, error } = useSWR("/api/fixtures/uploads", fetcher);
return ( return (
<Layout title="Your uploads"> <Layout title="Your uploads">
<Table data={data} headers={headers} actions={actions} page={page} setPage={setPage} /> {data && <Table data={data} headers={headers} actions={actions} page={page} setPage={setPage} />}
</Layout> </Layout>
); );
} }

View File

@ -2,7 +2,11 @@ module.exports = {
purge: ["./src/**/*.js"], purge: ["./src/**/*.js"],
darkMode: false, // or 'media' or 'class' darkMode: false, // or 'media' or 'class'
theme: { theme: {
extend: {}, extend: {
fontFamily: {
sans: ["Metropolis", "Helvetica", "Arial", "Sans-Serif"],
},
},
}, },
variants: { variants: {
extend: {}, extend: {},