dashboard
This commit is contained in:
parent
8618759f75
commit
0c148cf011
|
@ -8,13 +8,16 @@
|
|||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/metropolis": "^4.1.0",
|
||||
"@ory/kratos-client": "^0.5.4-alpha.1",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"dayjs": "^1.10.4",
|
||||
"express-jwt": "^6.0.0",
|
||||
"jwks-rsa": "^1.12.2",
|
||||
"next": "^10.0.6",
|
||||
"postcss": "^8.2.4",
|
||||
"prettier": "^2.2.1",
|
||||
"pretty-bytes": "^5.5.0",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"swr": "^0.4.1",
|
||||
|
|
|
@ -212,6 +212,7 @@ export default function Layout({ title, children }) {
|
|||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<main className="-mt-32">
|
||||
<div className="max-w-7xl mx-auto pb-12 px-4 sm:px-6 lg:px-8">
|
||||
{/* Replace with your content */}
|
||||
|
@ -223,6 +224,13 @@ export default function Layout({ title, children }) {
|
|||
{/* /End replace */}
|
||||
</div>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
const rowsPerPage = 10;
|
||||
const pageSize = 10;
|
||||
|
||||
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);
|
||||
|
||||
const dataSlice = data.slice(rowsPerPage * (page - 1), rowsPerPage * (page - 1) + rowsPerPage);
|
||||
const dataSlice = data.slice(pageSize * (page - 1), pageSize * (page - 1) + pageSize);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
|
@ -34,9 +34,9 @@ export default function Table({ data, headers, actions, page, setPage }) {
|
|||
<tbody>
|
||||
{dataSlice.map((row, 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">
|
||||
{row[key] || "-"}
|
||||
{(formatter ? formatter(row[key]) : row[key]) || "-"}
|
||||
</td>
|
||||
))}
|
||||
{actions.map(({ key, name, action }) => (
|
||||
|
@ -57,10 +57,8 @@ export default function Table({ data, headers, actions, page, setPage }) {
|
|||
>
|
||||
<div className="hidden sm:block">
|
||||
<p className="text-sm text-gray-700">
|
||||
Showing <span className="font-medium">{rowsPerPage * (page - 1) + 1}</span> to{" "}
|
||||
<span className="font-medium">
|
||||
{rowsPerPage * page > data.length ? data.length : rowsPerPage * page}
|
||||
</span>{" "}
|
||||
Showing <span className="font-medium">{data.length ? pageSize * (page - 1) + 1 : 0}</span> to{" "}
|
||||
<span className="font-medium">{pageSize * page > data.length ? data.length : pageSize * page}</span>{" "}
|
||||
of <span className="font-medium">{data.length}</span> results
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import "tailwindcss/tailwind.css";
|
||||
import "@fontsource/metropolis/all.css";
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export default (req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.json(require("./downloads.json"));
|
||||
};
|
|
@ -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"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
export default (req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.json(require("./uploads.json"));
|
||||
};
|
|
@ -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"
|
||||
}
|
||||
]
|
|
@ -1,28 +1,26 @@
|
|||
import dayjs from "dayjs";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import { useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import Layout from "../components/Layout";
|
||||
import Table from "../components/Table";
|
||||
|
||||
const data = [
|
||||
{ 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 fetcher = (url) => fetch(url).then((r) => r.json());
|
||||
const headers = [
|
||||
{ key: "name", name: "Name" },
|
||||
{ key: "skylink", name: "Skylink" },
|
||||
{ key: "size", name: "Size" },
|
||||
{ key: "date", name: "Access time" },
|
||||
{ key: "size", name: "Size", formatter: prettyBytes },
|
||||
{ key: "downloadedOn", name: "Accessed on", formatter: (date) => dayjs(date).format("YYYY-MM-DD HH:mm:ss") },
|
||||
];
|
||||
const actions = [];
|
||||
|
||||
export default function Downloads() {
|
||||
const [page, setPage] = useState(1);
|
||||
const { data, error } = useSWR("/api/fixtures/downloads", fetcher);
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,447 @@
|
|||
import prettyBytes from "pretty-bytes";
|
||||
import Link from "next/link";
|
||||
import useSWR from "swr";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
const fetcher = (url) => fetch(url).then((r) => r.json());
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
import dayjs from "dayjs";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import { useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import Layout from "../components/Layout";
|
||||
import Table from "../components/Table";
|
||||
|
||||
const data = [
|
||||
{ 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 fetcher = (url) => fetch(url).then((r) => r.json());
|
||||
const headers = [
|
||||
{ key: "name", name: "Name" },
|
||||
{ key: "skylink", name: "Skylink" },
|
||||
{ key: "size", name: "Size" },
|
||||
{ key: "date", name: "Uploaded on" },
|
||||
{ key: "size", name: "Size", formatter: prettyBytes },
|
||||
{ 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 { data, error } = useSWR("/api/fixtures/uploads", fetcher);
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,11 @@ module.exports = {
|
|||
purge: ["./src/**/*.js"],
|
||||
darkMode: false, // or 'media' or 'class'
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ["Metropolis", "Helvetica", "Arial", "Sans-Serif"],
|
||||
},
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
extend: {},
|
||||
|
|
Reference in New Issue