diff --git a/ui/public/cogs.svg b/ui/public/cogs.svg old mode 100755 new mode 100644 diff --git a/ui/public/id-card-solid.svg b/ui/public/id-card-solid.svg new file mode 100644 index 00000000..8abeb2c8 --- /dev/null +++ b/ui/public/id-card-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/id-email.svg b/ui/public/id-email.svg old mode 100755 new mode 100644 diff --git a/ui/public/key-solid.svg b/ui/public/key-solid.svg new file mode 100644 index 00000000..7555f7ed --- /dev/null +++ b/ui/public/key-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/uh-groupings-text.svg b/ui/public/uh-groupings-text.svg new file mode 100644 index 00000000..f323aed7 --- /dev/null +++ b/ui/public/uh-groupings-text.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/public/user-solid.svg b/ui/public/user-solid.svg new file mode 100644 index 00000000..30cbd7d3 --- /dev/null +++ b/ui/public/user-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/watch.svg b/ui/public/watch.svg old mode 100755 new mode 100644 diff --git a/ui/public/wrench-solid.svg b/ui/public/wrench-solid.svg new file mode 100644 index 00000000..280b3bd0 --- /dev/null +++ b/ui/public/wrench-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/app/(index)/_components/AfterLogin.tsx b/ui/src/app/(index)/_components/AfterLogin.tsx new file mode 100644 index 00000000..e52c5fbc --- /dev/null +++ b/ui/src/app/(index)/_components/AfterLogin.tsx @@ -0,0 +1,102 @@ +import User from '@/access/User'; +import Role from '@/access/Role'; +import Image from 'next/image'; +import { KeyRound } from 'lucide-react'; +import PageInfoCard from '@/app/(index)/_components/PageInfoCard'; + +const AfterLogin = ({ + currentUser, + numberOfGroupings, + numberOfMemberships +}: { + currentUser: User, + numberOfGroupings: number, + numberOfMemberships: number +}) => { + const isAdmin = currentUser.roles.includes(Role.ADMIN); + const isOwner = currentUser.roles.includes(Role.OWNER); + const getHighestRole = () => { + if (isAdmin) return 'Admin'; + else if (isOwner) return 'Owner'; + else return 'Member'; + } + + return ( +
+
+
+
+
+
+ user-solid +
+ +
+
+
+
+

Welcome, {currentUser.firstName}!

+

Role: {getHighestRole()}

+
+
+
+
+ +
+ {isAdmin && + key-solid + } + + + id-card + + + {isOwner && + wrench-solid + } +
+
+ ); +} + +export default AfterLogin; diff --git a/ui/src/app/(index)/_components/Announcement.tsx b/ui/src/app/(index)/_components/Announcement.tsx new file mode 100644 index 00000000..2e00816f --- /dev/null +++ b/ui/src/app/(index)/_components/Announcement.tsx @@ -0,0 +1,19 @@ +'use client'; +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; +import { AlertCircle } from 'lucide-react'; + +const Announcement = ({ + announcement +}: { + announcement: string +}) => ( + + + Announcement + + {announcement} + + +); + +export default Announcement; diff --git a/ui/src/app/(index)/_components/BeforeLogin.tsx b/ui/src/app/(index)/_components/BeforeLogin.tsx new file mode 100644 index 00000000..d47e4a2f --- /dev/null +++ b/ui/src/app/(index)/_components/BeforeLogin.tsx @@ -0,0 +1,22 @@ +import { Button } from '@/components/ui/button'; +import { ArrowRight } from 'lucide-react'; +import UHGroupingsInfo from '@/components/UHGroupingsInfo'; + +const BeforeLogin = () => { + return ( +
+ +
+
+ + + +
+
+
+ ); +}; + +export default BeforeLogin; diff --git a/ui/src/app/(index)/_components/LoginButton.tsx b/ui/src/app/(index)/_components/LoginButton.tsx new file mode 100644 index 00000000..544f01c9 --- /dev/null +++ b/ui/src/app/(index)/_components/LoginButton.tsx @@ -0,0 +1,31 @@ +'use client'; +import { Button } from '@/components/ui/button'; +import Role from '@/access/Role'; +import User from '@/access/User'; +import { login, logout } from '@/access/AuthenticationService'; + +const LoginButton = ({ + currentUser +}: { + currentUser: User; +}) => ( + <> + {!currentUser.roles.includes(Role.UH) ? ( + + ) : ( + + )} + +); + +export default LoginButton; diff --git a/ui/src/app/(index)/_components/PageInfoCard.tsx b/ui/src/app/(index)/_components/PageInfoCard.tsx new file mode 100644 index 00000000..586ecd35 --- /dev/null +++ b/ui/src/app/(index)/_components/PageInfoCard.tsx @@ -0,0 +1,37 @@ +import { ReactNode } from 'react'; +import Link from 'next/link'; +import { Button } from '@/components/ui/button'; + + +const PageInfoCard = ({ + title, + description, + href, + children, + number +}: { + title: string, + description: string, + href: string, + children?: ReactNode, + number?: number +}) => { + return ( +
+
+
+ {children} + {number && {number}} +
+

{title}

+

{description}

+
+ + + +
+ ); + +} + +export default PageInfoCard diff --git a/ui/src/app/(index)/page.tsx b/ui/src/app/(index)/page.tsx index b0223723..f1920f2f 100644 --- a/ui/src/app/(index)/page.tsx +++ b/ui/src/app/(index)/page.tsx @@ -1,6 +1,74 @@ -const Home = () => { +import Image from 'next/image'; +import BeforeLogin from '@/app/(index)/_components/BeforeLogin'; +import AfterLogin from '@/app/(index)/_components/AfterLogin'; +import { getCurrentUser } from '@/access/AuthenticationService'; +import Role from '@/access/Role'; +import LoginButton from '@/app/(index)/_components/LoginButton'; +import { getAnnouncements, getNumberOfGroupings, getNumberOfMemberships } from '@/services/GroupingsApiService'; +import Announcement from '@/app/(index)/_components/Announcement'; + +const Home = async () => { + const [currentUser, numberOfGroupings, numberOfMemberships, announcements] = await Promise.all([ + getCurrentUser(), + getNumberOfGroupings(), + getNumberOfMemberships(), + getAnnouncements() + ]); + + const activeAnnouncements = () => { + if (!announcements) { + return [] + } + return announcements.announcements + .filter((announcement) => announcement.state === 'Active') + .map((announcement) => announcement.message) + } + return ( - null +
+
+ {activeAnnouncements().map((announcement: string, index: number) => ( + + ))} +
+
+
+

UH Groupings

+ UH Groupings logotype + +

Manage your groupings in one place, use them in many.

+
+ {!currentUser.roles.includes(Role.UH) && + } +
+
+
+
+ UH Groupings +
+
+
+ + {currentUser.roles.includes(Role.UH) ? ( + + ) : ( + + )} +
); } diff --git a/ui/src/app/about/page.tsx b/ui/src/app/about/page.tsx index c8d17f53..92d02ce0 100644 --- a/ui/src/app/about/page.tsx +++ b/ui/src/app/about/page.tsx @@ -1,58 +1,8 @@ -import Image from 'next/image'; +import UHGroupingsInfo from '@/components/UHGroupingsInfo'; const About = () => (
-
-
-
-

What is a UH Grouping?

-

A grouping is a collection of members - (e.g., all full-time - Hilo faculty).

-
-
-
-
- Cogs icon -
-

Create groupings, manage grouping memberships, - control members' self-service - options, designate sync destinations, and more.

-
- -
-
- Email icon -
-

Synchronize groupings email LISTSERV lists, attributes for access - control via - CAS and LDAP, etc.

-
- -
-
- Watch icon -
-

Leverage group data from official sources, which can - substantially reduce the - manual overhead of membership management.

-
-
-
-
- +

GENERAL INFO

@@ -60,8 +10,10 @@ const About = () => (

How do I request a new grouping?

A request form is available. + href={'https://uhawaii.atlassian.net/wiki/spaces/UHIAM/' + + 'pages/13402308/UH+Groupings+Request+Form'} + aria-label="A request form is available">A request form is available + .

Exactly what is a grouping?

diff --git a/ui/src/components/AboutInfoItem.tsx b/ui/src/components/AboutInfoItem.tsx new file mode 100644 index 00000000..749a7b36 --- /dev/null +++ b/ui/src/components/AboutInfoItem.tsx @@ -0,0 +1,30 @@ +import Image from 'next/image'; + +const AboutInfoItem = ({ + src, + alt, + description, + variant +}: { + src: string, + alt: string, + description: string, + variant?: 'default' | 'home' +}) => { + const size = variant === 'home' ? 'text-[1.2rem]' : 'text-base'; + + return ( +
+
+ {alt} +
+

{description}

+
+ ); +} + +export default AboutInfoItem; diff --git a/ui/src/components/UHGroupingsInfo.tsx b/ui/src/components/UHGroupingsInfo.tsx new file mode 100644 index 00000000..0b8b41f8 --- /dev/null +++ b/ui/src/components/UHGroupingsInfo.tsx @@ -0,0 +1,49 @@ +import AboutInfoItem from '@/components/AboutInfoItem'; + +const UHGroupingsInfo = ({ + variant +}: { + variant?: 'default' | 'home'; +}) => { + const color = variant === 'home' ? 'text-text-color' : 'text-uh-black'; + variant = variant ?? 'default'; + + return ( +
+
+
+
+

What is a UH Grouping?

+

A grouping is a collection of members + (e.g., all full-time + Hilo faculty).

+
+
+ + + +
+
+
+
+ ); + +} + +export default UHGroupingsInfo; diff --git a/ui/src/components/layout/navbar/Navbar.tsx b/ui/src/components/layout/navbar/Navbar.tsx index a9a5921c..12da83ed 100644 --- a/ui/src/components/layout/navbar/Navbar.tsx +++ b/ui/src/components/layout/navbar/Navbar.tsx @@ -9,11 +9,10 @@ import TimeoutModal from '@/components/modal/TimeoutModal'; const Navbar = async () => { const currentUser = await getCurrentUser(); - - return ( + return ( <> -