From 4ab92e7047c58bb8034fbf34402d27cde045e496 Mon Sep 17 00:00:00 2001 From: Everest Date: Sun, 4 Feb 2024 00:52:59 -0300 Subject: [PATCH] Implement skeleton on load --- ui/package-lock.json | 87 ++++++++++++++++++++++++++++++++- ui/package.json | 1 + ui/src/components/EventList.tsx | 20 ++++++-- ui/src/main.css | 13 +++-- ui/src/organisms/EventCard.tsx | 69 +++++++++++++++++--------- ui/src/pages/Lending.tsx | 21 +++++--- ui/tailwind.config.js | 5 +- 7 files changed, 177 insertions(+), 39 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index f6b0b89..9a36b50 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -12,6 +12,7 @@ "@heroicons/react": "^2.1.1", "axios": "^1.6.7", "moment": "^2.30.1", + "primereact": "^10.4.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-markdown": "^9.0.1", @@ -40,6 +41,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@headlessui/react": { "version": "1.7.18", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.18.tgz", @@ -366,6 +378,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-world-flags": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/@types/react-world-flags/-/react-world-flags-1.4.5.tgz", @@ -806,6 +826,15 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "dev": true }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -2319,7 +2348,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2573,6 +2601,38 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/primereact": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/primereact/-/primereact-10.4.0.tgz", + "integrity": "sha512-PrLDJYcdb5JXq8x7cviFR1DT0xRKvLmr/u3cPwlxTdUrSkobr9ZVnH/Co6/fLmFRPjC3KmDXZdnWPf9+gE9dBA==", + "dependencies": { + "@types/react-transition-group": "^4.4.1", + "react-transition-group": "^4.4.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/property-information": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", @@ -2630,6 +2690,11 @@ "react": "^18.2.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-markdown": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz", @@ -2684,6 +2749,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/react-world-flags": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/react-world-flags/-/react-world-flags-1.6.0.tgz", @@ -2718,6 +2798,11 @@ "node": ">=8.10.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/remark-gfm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", diff --git a/ui/package.json b/ui/package.json index dbba89e..3581c5e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -7,6 +7,7 @@ "@heroicons/react": "^2.1.1", "axios": "^1.6.7", "moment": "^2.30.1", + "primereact": "^10.4.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-markdown": "^9.0.1", diff --git a/ui/src/components/EventList.tsx b/ui/src/components/EventList.tsx index 7185507..5592aea 100644 --- a/ui/src/components/EventList.tsx +++ b/ui/src/components/EventList.tsx @@ -1,19 +1,29 @@ import { Event } from '../props/generated'; import EventCard from '../organisms/EventCard'; -import { Filters } from '../organisms/FilterButton'; interface EventListProps { events: Event[] + loading: boolean } -export default function EventList({ events }: EventListProps) { +export default function EventList({ events, loading }: EventListProps) { return (
- {events !== null ? events.map((event) => ( - - )) : null} + {loading + ? ( + <> + + + + + + + + ) + : (events !== null ? events.map((event) => ()) : null) + }
diff --git a/ui/src/main.css b/ui/src/main.css index b5c61c9..751d75a 100644 --- a/ui/src/main.css +++ b/ui/src/main.css @@ -1,3 +1,10 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@layer tailwind-base, primereact, tailwind-utilities; + +@layer tailwind-base { + @tailwind base; +} + +@layer tailwind-utilities { + @tailwind components; + @tailwind utilities; +} diff --git a/ui/src/organisms/EventCard.tsx b/ui/src/organisms/EventCard.tsx index 89ebc7b..8820fe5 100644 --- a/ui/src/organisms/EventCard.tsx +++ b/ui/src/organisms/EventCard.tsx @@ -3,9 +3,10 @@ import { UserGroupIcon } from '@heroicons/react/20/solid'; import { Event } from '../props/generated'; import EventModal from './EventModal'; import Moment from 'moment'; +import { Skeleton } from 'primereact/skeleton'; interface EventCardProps { - event: Event + event: Event | null } export default function EventList({ event }: EventCardProps) { @@ -14,37 +15,61 @@ export default function EventList({ event }: EventCardProps) { return ( <> - { setOpenDetails(false) }} /> -
{ setOpenDetails(true) }}> -
- -
+ {event !== null + ? ( { setOpenDetails(false) }} />) + : null + } +
{ setOpenDetails(true) }}> + {event !== null + ? (
+ +
) + : ()}
-

{event.title}

-

- - - {Moment(event.begin)?.format('DD/MM')} - {Moment(event.end)?.format('DD/MM')} - -

-

- {event.venues !== null ? event.venues?.map((venue) => ( - - )) : null} -

+ +

+ {event?.venues !== null ? event?.venues?.map((venue) => ( + + )) : null} +

+ ) + : (<> + + + + )}
- {event?.attendees !== null ? ( + {event !== null ? ( - ) : null} + ) : ( + + )}
diff --git a/ui/src/pages/Lending.tsx b/ui/src/pages/Lending.tsx index 5bfb58d..b84b5a0 100644 --- a/ui/src/pages/Lending.tsx +++ b/ui/src/pages/Lending.tsx @@ -7,10 +7,13 @@ import EventList from "../components/EventList"; import { Props, Event as EventType } from "../props/generated"; import { Filters } from '../organisms/FilterButton'; import axios from 'axios'; +import { PrimeReactProvider } from 'primereact/api'; +import Tailwind from 'primereact/passthrough/tailwind'; export default function Lending({ Events, User, MainTag, Tags, Cities }: Props) { const [events, setEvents] = useState(Events); + const [loading, setLoading] = useState(false); const [page, setPage] = useState(0); const [filters, setFilters] = useState({ name: "", @@ -21,8 +24,10 @@ export default function Lending({ Events, User, MainTag, Tags, Cities }: Props) }); const onFilterChange = async (f: Filters) => { + setLoading(true) setFilters(f); const e = await requestEvents(0, f); + setLoading(false) setPage(0); setEvents(e); } @@ -34,13 +39,15 @@ export default function Lending({ Events, User, MainTag, Tags, Cities }: Props) } return ( -
-
- - onRequestNewPage} /> - -
-
+ +
+
+ + onRequestNewPage} /> + +
+
); } diff --git a/ui/tailwind.config.js b/ui/tailwind.config.js index aec69fb..52da09b 100644 --- a/ui/tailwind.config.js +++ b/ui/tailwind.config.js @@ -1,6 +1,9 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/**/*.{ts,tsx,js,jsx}"], + content: [ + "./src/**/*.{ts,tsx,js,jsx}", + "./node_modules/primereact/**/*.{js,ts,jsx,tsx}", + ], theme: { extend: {}, },