From 2a781e960367b11397ced1a03c2f60c2f3a0a443 Mon Sep 17 00:00:00 2001 From: Olly Hearn Date: Fri, 12 Apr 2024 20:13:59 +0300 Subject: [PATCH] design & shits --- frontend/app/src/components/AuthModal.tsx | 1 - .../app/src/components/HeaderComponent.tsx | 19 ++++- frontend/app/src/components/authProvider.ts | 14 ---- .../app/src/components/queue/QueuesList.tsx | 50 ++++++++++++ frontend/app/src/components/styles.css | 76 ++++++++++++++++++- frontend/app/src/pages/AppRoutes.tsx | 17 ++++- frontend/app/src/pages/DashboardPage.tsx | 17 +---- frontend/app/src/pages/NotFoundPage.tsx | 17 +++++ frontend/app/src/pages/styles.css | 4 +- frontend/app/src/slice/QueueApi.ts | 14 +++- 10 files changed, 188 insertions(+), 41 deletions(-) delete mode 100644 frontend/app/src/components/authProvider.ts create mode 100644 frontend/app/src/components/queue/QueuesList.tsx create mode 100644 frontend/app/src/pages/NotFoundPage.tsx diff --git a/frontend/app/src/components/AuthModal.tsx b/frontend/app/src/components/AuthModal.tsx index b511168..33739b0 100644 --- a/frontend/app/src/components/AuthModal.tsx +++ b/frontend/app/src/components/AuthModal.tsx @@ -1,5 +1,4 @@ import { Form, Input, Menu, MenuProps, Modal, Spin } from "antd"; -import "./styles.css"; import { KeyOutlined, LoadingOutlined, diff --git a/frontend/app/src/components/HeaderComponent.tsx b/frontend/app/src/components/HeaderComponent.tsx index d3c72e2..5119814 100644 --- a/frontend/app/src/components/HeaderComponent.tsx +++ b/frontend/app/src/components/HeaderComponent.tsx @@ -11,13 +11,16 @@ import "./styles.css"; import { StorePrototype, logOut, store } from "../config/store"; import { useSelector } from "react-redux"; import tr from "../config/translation"; -import { Link } from "react-router-dom"; +import { Link, useLocation, useNavigate } from "react-router-dom"; +import logo from "../../static/android-chrome-192x192.png"; const { Header } = Layout; type NullableUser = { name: string | null; username: string } | null; const HeaderComponent = () => { + const navigate = useNavigate(); + const [authModalOpen, setAuthModalOpen] = useState(false); const [userMenuOpen, setUserMenuOpen] = useState(false); @@ -41,6 +44,15 @@ const HeaderComponent = () => { ]; const items: MenuProps["items"] = [ + { + label: ( +
+ logo +
+ ), + key: "logo", + onClick: () => navigate("/"), + }, { label: {tr("Dashboard")}, key: "dashboard", @@ -69,15 +81,14 @@ const HeaderComponent = () => { return ( <> -
-
+
diff --git a/frontend/app/src/components/authProvider.ts b/frontend/app/src/components/authProvider.ts deleted file mode 100644 index a00d8e0..0000000 --- a/frontend/app/src/components/authProvider.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useEffect } from "react"; -import { useGetUserQuery } from "../slice/AuthApi"; -import { store, updateUser } from "../config/store"; - -const authProvider = () => { - const { data, isFetching, isError } = useGetUserQuery({}); - useEffect(() => { - if (!isFetching && !isError) { - store.dispatch(updateUser(data)); - } - }, [data, isFetching, useGetUserQuery]); -}; - -export default authProvider; diff --git a/frontend/app/src/components/queue/QueuesList.tsx b/frontend/app/src/components/queue/QueuesList.tsx new file mode 100644 index 0000000..c9f4c11 --- /dev/null +++ b/frontend/app/src/components/queue/QueuesList.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { useGetQueuesQuery } from "../../slice/QueueApi"; +import "../styles.css"; +import { Button, Spin } from "antd"; +import { + ArrowUpOutlined, + LoadingOutlined, + PlusCircleOutlined, +} from "@ant-design/icons"; +import Title from "antd/es/typography/Title"; +import tr from "../../config/translation"; + +type Queue = { + id: string; + name: string; +}; + +const QueuesList = (): JSX.Element => { + const { data, isLoading } = useGetQueuesQuery({}); + console.log(isLoading); + return ( +
+ + {tr("My queues")} + } + spinning={isLoading} + > + {data?.length ? ( + data?.map((ele: Queue) => ( +
+ {ele.name} +
+ )) + ) : ( + + {tr("You have no queues! Create one here")} <ArrowUpOutlined /> + + )} +
+
+ ); +}; +export default QueuesList; diff --git a/frontend/app/src/components/styles.css b/frontend/app/src/components/styles.css index 637148e..38c0763 100644 --- a/frontend/app/src/components/styles.css +++ b/frontend/app/src/components/styles.css @@ -1,9 +1,79 @@ -.menubar { +/* .menubar { display: flex; justify-content: space-between; align-items: center; - } + } */ .antd-modal-content { background-color: #001529; -} \ No newline at end of file +} + +.card { + background: #001529; + margin-top: 0.5rem; + margin-right: 1rem; + margin-left: 1rem; + border-radius: 10px; + padding: 1rem; +} + +.secondary { + background: white; + padding: 0.5rem; +} + +.queue-in-list { + display: flex; + flex-flow: row; + justify-content: space-between; + align-items: flex-start; + width: 100%; + margin-top: 1rem; + margin-bottom: 1rem; +} + +@keyframes headerDrop { + 0% { + transform: translateY(-50%); + opacity: 0%; + } + 60% { + opacity: 50%; + } + 100% { + transform: translateY(0); + opacity: 100%; + } +} + +.header { + animation: 0.3s ease-out 0s 1 headerDrop; + margin-top: 0.5rem; + margin-right: 1rem; + margin-left: 1rem; + border-radius: 10px; +} + +.header-container { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +.header-logo { + display: flex; + justify-content: center; + align-items: center; +} + +.logo { + width: 36px; + height: auto; + transition-duration: 0.2s; +} + +.logo:hover { + transform: rotate(0.05turn); + transition-duration: 0.2s; +} diff --git a/frontend/app/src/pages/AppRoutes.tsx b/frontend/app/src/pages/AppRoutes.tsx index 72f66e0..3ddd5e4 100644 --- a/frontend/app/src/pages/AppRoutes.tsx +++ b/frontend/app/src/pages/AppRoutes.tsx @@ -1,20 +1,33 @@ import React, { ReactNode } from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import MainPage from "./MainPage"; -import { getLocalToken, loadLanguage, store } from "../config/store"; +import { + StorePrototype, + getLocalToken, + loadLanguage, + store, +} from "../config/store"; import DashboardPage from "./DashboardPage"; import PropTypes from "prop-types"; +import { useSelector } from "react-redux"; +import NotFoundPage from "./NotFoundPage"; const AppRoutes = ({ children }: { children: ReactNode }) => { store.dispatch(getLocalToken()); store.dispatch(loadLanguage()); + const user = useSelector((state: StorePrototype) => state.auth.user); + return ( {children} } /> - } /> + : } + /> + } /> ); diff --git a/frontend/app/src/pages/DashboardPage.tsx b/frontend/app/src/pages/DashboardPage.tsx index 42bfe9a..5ea0d15 100644 --- a/frontend/app/src/pages/DashboardPage.tsx +++ b/frontend/app/src/pages/DashboardPage.tsx @@ -1,22 +1,9 @@ import React from "react"; import "./styles.css"; -import logoSquare from "../../static/logo-square.png"; -import { Button } from "antd"; -import tr from "../config/translation"; +import QueuesList from "../components/queue/QueuesList"; const DashboardPage = () => { - return ( -
- logo -

- {tr("Queuing has never been so simple")} -

-
- - -
-
- ); + return ; }; export default DashboardPage; diff --git a/frontend/app/src/pages/NotFoundPage.tsx b/frontend/app/src/pages/NotFoundPage.tsx new file mode 100644 index 0000000..00520ef --- /dev/null +++ b/frontend/app/src/pages/NotFoundPage.tsx @@ -0,0 +1,17 @@ +import { QuestionCircleOutlined } from "@ant-design/icons"; +import React from "react"; +import tr from "../config/translation"; +import Title from "antd/es/typography/Title"; + +const NotFoundPage = () => { + return ( + <> +
+ +
+ {tr("Not found")} + + ); +}; + +export default NotFoundPage; diff --git a/frontend/app/src/pages/styles.css b/frontend/app/src/pages/styles.css index f4efc0e..a387373 100644 --- a/frontend/app/src/pages/styles.css +++ b/frontend/app/src/pages/styles.css @@ -1,6 +1,8 @@ .card { background: #001529; - margin: 10px; + margin-top: 0.5rem; + margin-right: 1rem; + margin-left: 1rem; border-radius: 10px; } diff --git a/frontend/app/src/slice/QueueApi.ts b/frontend/app/src/slice/QueueApi.ts index e383158..4128ca1 100644 --- a/frontend/app/src/slice/QueueApi.ts +++ b/frontend/app/src/slice/QueueApi.ts @@ -2,6 +2,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { baseUrl } from "../config/baseUrl"; import { RootState } from "../config/store"; +export type CreateQueueRequest = { + name: string; + description: string | null; +}; + export const QueueApi = createApi({ reducerPath: "QueueApi", baseQuery: fetchBaseQuery({ @@ -18,7 +23,14 @@ export const QueueApi = createApi({ getQueues: builder.query({ query: () => "/", }), + createQueue: builder.mutation({ + query: (data: CreateQueueRequest) => ({ + url: "/", + method: "POST", + body: data, + }), + }), }), }); -export const { useGetQueuesQuery } = QueueApi; +export const { useGetQueuesQuery, useCreateQueueMutation } = QueueApi;