Skip to content

Commit

Permalink
feat: add facility context switch and ui
Browse files Browse the repository at this point in the history
  • Loading branch information
calisio authored and jtucholski committed Oct 28, 2024
1 parent 5cdb010 commit 2cb149f
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 146 deletions.
6 changes: 5 additions & 1 deletion backend/src/handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,15 @@ func (srv *Server) validateOrySession(r *http.Request) (*Claims, bool, error) {
if !ok {
passReset = true
}
var facilityName string
if err := srv.Db.Model(&models.Facility{}).Select("name").Where("id = ?", facilityId).Find(&facilityName).Error; err != nil {
return nil, hasCookie, err
}
claims := &Claims{
Username: user.Username,
UserID: user.ID,
FacilityID: uint(facilityId),
FacilityName: user.Facility.Name,
FacilityName: facilityName,
PasswordReset: passReset,
KratosID: kratosID,
Role: user.Role,
Expand Down
210 changes: 133 additions & 77 deletions frontend/src/Components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ import {
HomeIcon,
RectangleStackIcon,
TrophyIcon,
UsersIcon
UsersIcon,
ArrowRightEndOnRectangleIcon,
SunIcon,
MoonIcon,
UserCircleIcon
} from '@heroicons/react/24/solid';
import { useAuth } from '@/useAuth';
import { useAuth, handleLogout } from '@/useAuth';
import ULIComponent from './ULIComponent';
import { Link } from 'react-router-dom';
import ThemeToggle from './ThemeToggle';

export default function Navbar({
isPinned,
Expand All @@ -23,9 +28,10 @@ export default function Navbar({
isPinned: boolean;
onTogglePin: () => void;
}) {
const user = useAuth();
const { user } = useAuth();

return (
<div className="w-60 min-w-[240px] h-screen flex flex-col justify-start bg-background group">
<div className="w-60 min-w-[240px] flex flex-col bg-background group h-screen">
<div className="hidden lg:flex self-end py-6 mr-4">
{isPinned ? (
<div
Expand Down Expand Up @@ -54,79 +60,129 @@ export default function Navbar({
<Brand />
</Link>

<ul className="menu">
{user.user?.role == UserRole.Admin ? (
<>
{/* admin view */}
<li className="mt-16">
<Link to="/admin-dashboard">
<ULIComponent icon={HomeIcon} /> Dashboard
</Link>
</li>
<li>
<Link to="/student-management">
<ULIComponent icon={AcademicCapIcon} />
Students
</Link>
</li>
<li>
<Link to="/admin-management">
<ULIComponent icon={UsersIcon} />
Admins
</Link>
</li>
<li>
<Link to="/open-content-management">
<ULIComponent icon={BookOpenIcon} />
Open Content
</Link>
</li>
<li>
<Link to="/resources-management">
<ULIComponent icon={ArchiveBoxIcon} />
Resources
</Link>
</li>
<li>
<Link to="/provider-platform-management">
<ULIComponent icon={RectangleStackIcon} />
Platforms
</Link>
</li>
</>
) : (
<>
{/* student view */}
<li className="mt-16">
<Link to="/student-dashboard">
<ULIComponent icon={HomeIcon} /> Dashboard
</Link>
</li>
<li className="">
<Link to="/my-courses">
<ULIComponent icon={BookOpenIcon} /> My Courses
</Link>
</li>
<li className="">
<Link to="/my-progress">
<ULIComponent icon={TrophyIcon} /> My Progress
</Link>
</li>
<li>
<Link to="/open-content">
<ULIComponent icon={BookOpenIcon} />
Open Content
</Link>
</li>
<li className="">
<Link to="/course-catalog">
<ULIComponent icon={BuildingStorefrontIcon} />
Course Catalog
</Link>
</li>
</>
)}
</ul>
<div className="h-full">
<ul className="menu h-full flex flex-col justify-between">
<div>
{user?.role == UserRole.Admin ? (
<>
{/* admin view */}
<li className="mt-16">
<Link to="/admin-dashboard">
<ULIComponent icon={HomeIcon} />
Dashboard
</Link>
</li>
<li>
<Link to="/student-management">
<ULIComponent icon={AcademicCapIcon} />
Students
</Link>
</li>
<li>
<Link to="/admin-management">
<ULIComponent icon={UsersIcon} />
Admins
</Link>
</li>
<li>
<Link to="/open-content-management">
<ULIComponent icon={BookOpenIcon} />
Open Content
</Link>
</li>
<li>
<Link to="/resources-management">
<ULIComponent icon={ArchiveBoxIcon} />
Resources
</Link>
</li>
<li>
<Link to="/provider-platform-management">
<ULIComponent
icon={RectangleStackIcon}
/>
Platforms
</Link>
</li>
</>
) : (
<>
{/* student view */}
<li className="mt-16">
<Link to="/student-dashboard">
<ULIComponent icon={HomeIcon} />
Dashboard
</Link>
</li>
<li>
<Link to="/my-courses">
<ULIComponent icon={BookOpenIcon} /> My
Courses
</Link>
</li>
<li>
<Link to="/my-progress">
<ULIComponent icon={TrophyIcon} /> My
Progress
</Link>
</li>
<li>
<Link to="/open-content">
<ULIComponent icon={BookOpenIcon} />
Open Content
</Link>
</li>
<li>
<Link to="/course-catalog">
<ULIComponent
icon={BuildingStorefrontIcon}
/>
Course Catalog
</Link>
</li>
</>
)}
</div>
<li className="dropdown dropdown-right dropdown-end w-full">
<div tabIndex={0} role="button">
<ULIComponent
icon={UserCircleIcon}
iconClassName={'w-5 h-5'}
/>
{user?.name_first} {user?.name_last}
</div>
<ul
tabIndex={0}
className="dropdown-content menu bg-grey-2 dark:bg-grey-1 rounded-box z-50 w-52 p-2 shadow"
>
<li className="self-center">
<label className="flex cursor-pointer gap-2">
<ULIComponent
icon={SunIcon}
iconClassName={'w-6 h-6'}
/>
<ThemeToggle />
<ULIComponent
icon={MoonIcon}
iconClassName={'w-6 h-6'}
/>
</label>
</li>
<div className="divider mt-0 mb-0"></div>
<li className="self-center">
<button
onClick={() => {
void handleLogout();
}}
>
<ArrowRightEndOnRectangleIcon className="h-4" />
Logout
</button>
</li>
</ul>
</li>
</ul>
</div>
</div>
);
}
91 changes: 47 additions & 44 deletions frontend/src/Components/PageNav.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { useEffect, useRef, useState } from 'react';
import { handleLogout, useAuth } from '@/useAuth';
import { useAuth } from '@/useAuth';
import {
ArrowRightEndOnRectangleIcon,
Bars3Icon,
BuildingOffice2Icon,
HomeIcon
} from '@heroicons/react/24/solid';

import { SunIcon, MoonIcon } from '@heroicons/react/24/outline';

import ThemeToggle from './ThemeToggle';
import ULIComponent from '@/Components/ULIComponent.tsx';
import { usePathValue } from '@/PathValueCtx';
import { Facility, UserRole } from '@/common';
import { useLoaderData } from 'react-router-dom';
import API from '@/api/api';

export default function PageNav({
path,
Expand All @@ -25,6 +24,7 @@ export default function PageNav({
const detailsRef = useRef<HTMLDetailsElement>(null);
const { pathVal } = usePathValue();
const [customPath, setCustomPath] = useState<string[]>(path ?? []);
const facilityNames = useLoaderData() as Facility[] | null;

useEffect(() => {
const handlePathChange = () => {
Expand Down Expand Up @@ -60,6 +60,13 @@ export default function PageNav({
};
}, []);

const handleSwitchFacility = async (facility: Facility) => {
const resp = await API.put(`admin/facility-context/${facility.id}`, {});
if (resp.success) {
window.location.reload();
}
};

return (
<div className="px-8 flex justify-between items-center">
<div className="breadcrumbs">
Expand Down Expand Up @@ -97,46 +104,42 @@ export default function PageNav({
))}
</ul>
</div>
<ul className="menu menu-horizontal px-1">
<li>
<details className="dropdown dropdown-end" ref={detailsRef}>
<summary>
{user && (
{user?.role == UserRole.Admin ? (
<ul className="menu menu-horizontal px-1">
<li>
<details
className="dropdown dropdown-end"
ref={detailsRef}
>
<summary>
<ULIComponent icon={BuildingOffice2Icon} />
<span className="font-semibold">
{user.name_first} {user.name_last}
{user.facility_name}
</span>
)}
</summary>
<ul className="dropdown-content bg-grey-2 z-[1] dark:bg-grey-1">
<li>
<label className="flex cursor-pointer gap-2">
<ULIComponent
icon={SunIcon}
iconClassName={'w-6 h-6'}
/>
<ThemeToggle />
<ULIComponent
icon={MoonIcon}
iconClassName={'w-6 h-6'}
/>
</label>
</li>
<div className="divider mt-0 mb-0"></div>

<li>
<button
onClick={() => {
void handleLogout();
}}
>
<ArrowRightEndOnRectangleIcon className="h-4" />
Logout
</button>
</li>
</ul>
</details>
</li>
</ul>
</summary>
<ul className="dropdown-content w-max bg-grey-2 z-[1] dark:bg-grey-1 flex flex-col">
{facilityNames?.map((facility: Facility) => (
<li
key={facility.id}
onClick={() => {
void handleSwitchFacility(facility);
}}
>
<label>{facility.name}</label>
</li>
))}
</ul>
</details>
</li>
</ul>
) : (
<div className="flex flex-row items-center gap-2 px-6 py-4">
<ULIComponent icon={BuildingOffice2Icon} />
<label className="font-semibold">
{user?.facility_name}
</label>
</div>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion frontend/src/Layouts/AuthenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default function AuthenticatedLayout() {
checked={isNavOpen && !isNavPinned}
onChange={() => setIsNavOpen(!isNavOpen)}
/>
<div className="drawer-side">
<div className="!overflow-visible drawer-side">
<label
htmlFor="nav-drawer"
className="drawer-overlay"
Expand Down
Loading

0 comments on commit 2cb149f

Please sign in to comment.