Skip to content

Commit

Permalink
Create Home page (Before and After Login)
Browse files Browse the repository at this point in the history
  • Loading branch information
FeimeiChen committed Apr 16, 2024
1 parent 50d8e85 commit 88e40eb
Show file tree
Hide file tree
Showing 30 changed files with 918 additions and 66 deletions.
Empty file modified ui/public/cogs.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/public/id-card-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified ui/public/id-email.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/public/key-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions ui/public/uh-groupings-text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/public/user-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified ui/public/watch.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ui/public/wrench-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
102 changes: 102 additions & 0 deletions ui/src/app/(index)/_components/AfterLogin.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<main>
<div className="bg-seafoam pt-5 pb-5">
<div className="container bg-seafoam pt-7 pb-7">
<div className="grid sm:grid-cols-12 text-center justify-center items-center gap-4">
<div className="sm:col-span-3 md:col-span-2">
<div className="flex justify-center items-center rounded-full
h-[100px] w-[100px] bg-white mx-auto relative lg:ml-0">
<Image
src="/uhgroupings/user-solid.svg"
alt="user-solid"
width={56}
height={64}
/>
<div
className="bg-blue-background rounded-full flex justify-center
items-center h-[30px] w-[30px] absolute left-3 bottom-0 ml-16">
<KeyRound className="fill-white stroke-none p-0.5" data-testid="key-round"/>
</div>
</div>
</div>
<div className="sm:col-span-9 md:col-span-10 text-center md:text-left">
<h1 className="whitespace-nowrap text-[1.75rem]"
data-testid="welcome-message">Welcome, <span
className="text-text-color">{currentUser.firstName}</span>!</h1>
<h1 className="whitespace-nowrap text-[1.75rem]" data-testid="role">Role: <span
className="text-text-color">{getHighestRole()}</span></h1>
</div>
</div>
</div>
</div>

<div className="container grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8 mt-10 mb-10">
{isAdmin && <PageInfoCard
title='Admin'
description={'Manage the list of Administrators for this service. ' +
'Search for and manage any grouping on behalf of the owner.'}
href='/admin'>
<Image
alt="key-solid"
src="uhgroupings/key-solid.svg"
width={48}
height={48}
className="mr-5 mb-4 max-w-[48] h-auto"
/>
</PageInfoCard>}

<PageInfoCard
title='Memberships'
description='View and manage my memberships. Search for new groupings to join as a member.'
href='/memberships'
number={numberOfMemberships}>
<Image src="uhgroupings/id-card-solid.svg"
alt= "id-card"
width={54}
height={48}
className="mr-5 mb-4 max-w-[54] h-auto"/>
</PageInfoCard>

{isOwner && <PageInfoCard
title='Groupings'
description={'Review members, manage Include and Exclude lists, ' +
'configure preferences, and export members.'}
href='/groupings'
number={numberOfGroupings}>
<Image
alt="wrench-solid"
src="uhgroupings/wrench-solid.svg"
width={48}
height={48}
className="mr-5 mb-4 max-w-[48] h-auto"
/>
</PageInfoCard>}
</div>
</main>
);
}

export default AfterLogin;
19 changes: 19 additions & 0 deletions ui/src/app/(index)/_components/Announcement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use client';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { AlertCircle } from 'lucide-react';

const Announcement = ({
announcement
}: {
announcement: string
}) => (
<Alert className="bg-yellow-100 border border-yellow-200 mb-2">
<AlertCircle data-testid="circle-alert-icon" className="h-4 w-4"/>
<AlertTitle className="font-semibold">Announcement</AlertTitle>
<AlertDescription>
{announcement}
</AlertDescription>
</Alert>
);

export default Announcement;
22 changes: 22 additions & 0 deletions ui/src/app/(index)/_components/BeforeLogin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button } from '@/components/ui/button';
import { ArrowRight } from 'lucide-react';
import UHGroupingsInfo from '@/components/UHGroupingsInfo';

const BeforeLogin = () => {
return (
<main className="bg-seafoam pb-10">
<UHGroupingsInfo variant="home"/>
<div className="row">
<div className="text-center">
<a href="https://uhawaii.atlassian.net/wiki/spaces/UHIAM/pages/13403213/UH+Groupings">
<Button size="lg" variant="default">
Learn More <ArrowRight className="ml-1"/>
</Button>
</a>
</div>
</div>
</main>
);
};

export default BeforeLogin;
31 changes: 31 additions & 0 deletions ui/src/app/(index)/_components/LoginButton.tsx
Original file line number Diff line number Diff line change
@@ -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) ? (
<Button
size="lg"
variant="default"
onClick={() => login()}>
Login Here
</Button>
) : (
<Button
size="lg"
variant="default"
onClick={() => logout()}>
Logout
</Button>
)}
</>
);

export default LoginButton;
37 changes: 37 additions & 0 deletions ui/src/app/(index)/_components/PageInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="flex flex-col justify-between">
<div>
<div className="flex items-center mb-1">
{children}
{number && <span className="text-[2.5rem] text-text-color">{number}</span>}
</div>
<h2 className="text-2xl text-text-color font-medium mb-2">{title}</h2>
<p className="mb-4 text-base font-normal">{description}</p>
</div>
<Link href={href}>
<Button>{title}</Button>
</Link>
</div>
);

}

export default PageInfoCard
72 changes: 70 additions & 2 deletions ui/src/app/(index)/page.tsx
Original file line number Diff line number Diff line change
@@ -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
<main>
<div className="container mt-5 mb-5">
{activeAnnouncements().map((announcement: string, index: number) => (
<Announcement announcement={announcement} key={index}/>
))}
<div className="flex flex-row py-8 px-0.5 justify-between">
<div className="md:w-7/12 flex items-center">
<div>
<h1 className="sr-only">UH Groupings</h1>
<Image
src="uhgroupings/uh-groupings-text.svg"
alt="UH Groupings logotype"
width={337.5}
height={52.5}
className="w-[210px] h-[32.67px] sm:w-1/2 sm:h-auto md:w-[337.5px] md:h-[52.5px]"
/>

<p className="text-xl mt-1"> Manage your groupings in one place, use them in many.</p>
<div className="mt-4">
{!currentUser.roles.includes(Role.UH) &&
<LoginButton currentUser={currentUser}/>}
</div>
</div>
</div>
<div className="hidden lg:block md:w-5/12">
<Image
src="/uhgroupings/uh-groupings-logo-large.svg"
alt="UH Groupings"
width={365.5}
height={292.5}
/>
</div>
</div>
</div>

{currentUser.roles.includes(Role.UH) ? (
<AfterLogin
currentUser={currentUser}
numberOfGroupings={numberOfGroupings}
numberOfMemberships={numberOfMemberships}/>
) : (
<BeforeLogin/>
)}
</main>
);
}

Expand Down
Loading

0 comments on commit 88e40eb

Please sign in to comment.