diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json
index 962d4844..7c9b53ac 100644
--- a/packages/dashboard/package.json
+++ b/packages/dashboard/package.json
@@ -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",
diff --git a/packages/dashboard/src/components/Layout.js b/packages/dashboard/src/components/Layout.js
index cb5c4928..85f65837 100644
--- a/packages/dashboard/src/components/Layout.js
+++ b/packages/dashboard/src/components/Layout.js
@@ -212,6 +212,7 @@ export default function Layout({ title, children }) {
+
{/* Replace with your content */}
@@ -223,6 +224,13 @@ export default function Layout({ title, children }) {
{/* /End replace */}
+
+
);
}
diff --git a/packages/dashboard/src/components/Table.js b/packages/dashboard/src/components/Table.js
index 962803cc..4d9e1b56 100644
--- a/packages/dashboard/src/components/Table.js
+++ b/packages/dashboard/src/components/Table.js
@@ -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 (
@@ -34,9 +34,9 @@ export default function Table({ data, headers, actions, page, setPage }) {
{dataSlice.map((row, index) => (
- {headers.map(({ key, name }) => (
+ {headers.map(({ key, formatter }) => (
- {row[key] || "-"}
+ {(formatter ? formatter(row[key]) : row[key]) || "-"}
|
))}
{actions.map(({ key, name, action }) => (
@@ -57,10 +57,8 @@ export default function Table({ data, headers, actions, page, setPage }) {
>
- Showing {rowsPerPage * (page - 1) + 1} to{" "}
-
- {rowsPerPage * page > data.length ? data.length : rowsPerPage * page}
- {" "}
+ Showing {data.length ? pageSize * (page - 1) + 1 : 0} to{" "}
+ {pageSize * page > data.length ? data.length : pageSize * page}{" "}
of {data.length} results
diff --git a/packages/dashboard/src/pages/_app.js b/packages/dashboard/src/pages/_app.js
index 9917eca6..ee495472 100644
--- a/packages/dashboard/src/pages/_app.js
+++ b/packages/dashboard/src/pages/_app.js
@@ -1,4 +1,5 @@
import "tailwindcss/tailwind.css";
+import "@fontsource/metropolis/all.css";
function MyApp({ Component, pageProps }) {
return ;
diff --git a/packages/dashboard/src/pages/api/fixtures/downloads.js b/packages/dashboard/src/pages/api/fixtures/downloads.js
new file mode 100644
index 00000000..7dd0dc1f
--- /dev/null
+++ b/packages/dashboard/src/pages/api/fixtures/downloads.js
@@ -0,0 +1,4 @@
+export default (req, res) => {
+ res.statusCode = 200;
+ res.json(require("./downloads.json"));
+};
diff --git a/packages/dashboard/src/pages/api/fixtures/downloads.json b/packages/dashboard/src/pages/api/fixtures/downloads.json
new file mode 100644
index 00000000..929caede
--- /dev/null
+++ b/packages/dashboard/src/pages/api/fixtures/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"
+ }
+]
diff --git a/packages/dashboard/src/pages/api/fixtures/uploads.js b/packages/dashboard/src/pages/api/fixtures/uploads.js
new file mode 100644
index 00000000..019f548c
--- /dev/null
+++ b/packages/dashboard/src/pages/api/fixtures/uploads.js
@@ -0,0 +1,4 @@
+export default (req, res) => {
+ res.statusCode = 200;
+ res.json(require("./uploads.json"));
+};
diff --git a/packages/dashboard/src/pages/api/fixtures/uploads.json b/packages/dashboard/src/pages/api/fixtures/uploads.json
new file mode 100644
index 00000000..929caede
--- /dev/null
+++ b/packages/dashboard/src/pages/api/fixtures/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"
+ }
+]
diff --git a/packages/dashboard/src/pages/downloads.js b/packages/dashboard/src/pages/downloads.js
index f82b2a3b..68873093 100644
--- a/packages/dashboard/src/pages/downloads.js
+++ b/packages/dashboard/src/pages/downloads.js
@@ -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 (
-
+ {data && }
);
}
diff --git a/packages/dashboard/src/pages/index.js b/packages/dashboard/src/pages/index.js
index 7b7ea817..992f5e59 100644
--- a/packages/dashboard/src/pages/index.js
+++ b/packages/dashboard/src/pages/index.js
@@ -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 ;
+ const { data: user, error } = useSWR("/api/user", fetcher);
+
+ return (
+
+
+
+
+
+
+
+ {/* Heroicon name: outline/users */}
+
+
+
+
- Current plan
+
-
+
Free
+
+
+
+
+
+
+
+
+
+
+
+ {/* Heroicon name: outline/cursor-click */}
+
+
+
+
- Current period download
+
-
+
{prettyBytes(189237982173)}
+
+
+
+
+
+
+
+
+
+
+
+ {/* Heroicon name: outline/cursor-click */}
+
+
+
+
- Current period upload
+
-
+
{prettyBytes(9237982173)}
+
+
+
+
+
+
+
+
+ {/* ============ */}
+
+
+
+
+
Recent downloads
+
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+
Recent uploads
+
+
+ {/* This example requires Tailwind CSS v2.0+ */}
+
+
+
+
+
+ );
}
diff --git a/packages/dashboard/src/pages/uploads.js b/packages/dashboard/src/pages/uploads.js
index e99ff14e..1def9e12 100644
--- a/packages/dashboard/src/pages/uploads.js
+++ b/packages/dashboard/src/pages/uploads.js
@@ -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 (
-
+ {data && }
);
}
diff --git a/packages/dashboard/tailwind.config.js b/packages/dashboard/tailwind.config.js
index 626a4659..b24c7054 100644
--- a/packages/dashboard/tailwind.config.js
+++ b/packages/dashboard/tailwind.config.js
@@ -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: {},