Skip to content

Revamp mobile UI #10103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import Providers from "@/context/providers";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { useState } from "react";
import Wrapper from "@/components/Wrapper";
import Sidebar from "@/components/Sidebar";
import Header from "@/components/Header";
import Sidebar from "@/components/navigation/Sidebar";
import Live from "@/pages/Live";
import Export from "@/pages/Export";
import Storage from "@/pages/Storage";
Expand All @@ -14,27 +12,22 @@ import NoMatch from "@/pages/NoMatch";
import Settings from "@/pages/Settings";
import UIPlayground from "./pages/UIPlayground";
import Events from "./pages/Events";
import { isDesktop } from "react-device-detect";
import { isDesktop, isMobile } from "react-device-detect";
import Statusbar from "./components/Statusbar";
import Bottombar from "./components/navigation/Bottombar";

function App() {
const [sheetOpen, setSheetOpen] = useState(false);

const toggleNavbar = () => {
setSheetOpen((prev) => !prev);
};

return (
<Providers>
<BrowserRouter>
<Wrapper>
<Header onToggleNavbar={toggleNavbar} />
<div className="w-full h-full pt-2 overflow-hidden">
<Sidebar sheetOpen={sheetOpen} setSheetOpen={setSheetOpen} />
{isDesktop && <Sidebar />}
{isDesktop && <Statusbar />}
{isMobile && <Bottombar />}
<div
id="pageRoot"
className="absolute left-0 md:left-16 top-16 md:top-2 right-0 bottom-0 md:bottom-8 overflow-hidden"
className="absolute left-0 md:left-16 top-2 right-0 bottom-16 md:bottom-8 overflow-hidden"
>
<Routes>
<Route path="/" element={<Live />} />
Expand Down
63 changes: 0 additions & 63 deletions web/src/components/Header.tsx

This file was deleted.

95 changes: 0 additions & 95 deletions web/src/components/Sidebar.tsx

This file was deleted.

39 changes: 28 additions & 11 deletions web/src/components/filter/ReviewFilterGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Calendar } from "../ui/calendar";
import { ReviewFilter } from "@/types/review";
import { getEndOfDayTimestamp } from "@/utils/dateUtil";
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
import { isMobile } from "react-device-detect";

const ATTRIBUTES = ["amazon", "face", "fedex", "license_plate", "ups"];

Expand Down Expand Up @@ -122,11 +123,17 @@ function CamerasFilterButton({
}}
>
<DropdownMenuTrigger asChild>
<Button className="mx-1 capitalize" variant="secondary">
<LuVideo className=" mr-[10px]" />
{selectedCameras == undefined
? "All Cameras"
: `${selectedCameras.length} Cameras`}
<Button
size={isMobile ? "sm" : "default"}
className="mx-1 capitalize"
variant="secondary"
>
<LuVideo className="md:mr-[10px]" />
<div className="hidden md:block">
{selectedCameras == undefined
? "All Cameras"
: `${selectedCameras.length} Cameras`}
</div>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
Expand Down Expand Up @@ -205,9 +212,15 @@ function CalendarFilterButton({
}}
>
<PopoverTrigger asChild>
<Button className="mx-1" variant="secondary">
<LuCalendar className=" mr-[10px]" />
{day == undefined ? "Last 24 Hours" : selectedDate}
<Button
size={isMobile ? "sm" : "default"}
className="mx-1"
variant="secondary"
>
<LuCalendar className="md:mr-[10px]" />
<div className="hidden md:block">
{day == undefined ? "Last 24 Hours" : selectedDate}
</div>
</Button>
</PopoverTrigger>
<PopoverContent>
Expand Down Expand Up @@ -241,9 +254,13 @@ function GeneralFilterButton({
return (
<Popover>
<PopoverTrigger asChild>
<Button className="mx-1" variant="secondary">
<LuFilter className=" mr-[10px]" />
Filter
<Button
size={isMobile ? "sm" : "default"}
className="mx-1"
variant="secondary"
>
<LuFilter className="md:mr-[10px]" />
<div className="hidden md:block">Filter</div>
</Button>
</PopoverTrigger>
<PopoverContent side="left" asChild>
Expand Down
26 changes: 26 additions & 0 deletions web/src/components/navigation/Bottombar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { navbarLinks } from "@/pages/site-navigation";
import NavItem from "./NavItem";
import SettingsNavItems from "../settings/SettingsNavItems";

function Bottombar() {
return (
<div className="absolute h-16 left-4 bottom-0 right-4 flex flex-row items-center justify-between">
{navbarLinks.map((item) => (
<NavItem
className=""
variant="secondary"
key={item.id}
Icon={item.icon}
title={item.title}
url={item.url}
dev={item.dev}
/>
))}
<SettingsNavItems className="flex flex-shrink-0 justify-between gap-4" />
</div>
);
}

//

export default Bottombar;
64 changes: 64 additions & 0 deletions web/src/components/navigation/NavItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { IconType } from "react-icons";
import { NavLink } from "react-router-dom";
import { ENV } from "@/env";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";

const variants = {
primary: {
active: "font-bold text-primary-foreground bg-primary",
inactive: "text-muted-foreground bg-muted",
},
secondary: {
active: "font-bold text-primary",
inactive: "text-muted-foreground",
},
};

type NavItemProps = {
className: string;
variant?: "primary" | "secondary";
Icon: IconType;
title: string;
url: string;
dev?: boolean;
onClick?: () => void;
};

export default function NavItem({
className,
variant = "primary",
Icon,
title,
url,
dev,
onClick,
}: NavItemProps) {
const shouldRender = dev ? ENV !== "production" : true;

return (
shouldRender && (
<Tooltip>
<NavLink
to={url}
onClick={onClick}
className={({ isActive }) =>
`${className} flex flex-col justify-center items-center rounded-lg ${
variants[variant][isActive ? "active" : "inactive"]
}`
}
>
<TooltipTrigger>
<Icon className="w-5 h-5 m-[6px]" />
</TooltipTrigger>
</NavLink>
<TooltipContent side="right">
<p>{title}</p>
</TooltipContent>
</Tooltip>
)
);
}
28 changes: 28 additions & 0 deletions web/src/components/navigation/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Logo from "../Logo";
import { navbarLinks } from "@/pages/site-navigation";
import SettingsNavItems from "../settings/SettingsNavItems";
import NavItem from "./NavItem";

function Sidebar() {
return (
<aside className="w-[52px] z-10 h-screen sticky top-0 overflow-y-auto scrollbar-hidden py-4 flex flex-col justify-between">
<span tabIndex={0} className="sr-only" />
<div className="w-full flex flex-col gap-0 items-center">
<Logo className="w-8 h-8 mb-6" />
{navbarLinks.map((item) => (
<NavItem
className="mx-[10px] mb-6"
key={item.id}
Icon={item.icon}
title={item.title}
url={item.url}
dev={item.dev}
/>
))}
</div>
<SettingsNavItems className="hidden md:flex flex-col items-center mb-8" />
</aside>
);
}

export default Sidebar;
Loading