Skip to content

Commit

Permalink
feat: requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
georgi4444 committed Nov 7, 2024
1 parent 13dfdcf commit a11194c
Show file tree
Hide file tree
Showing 20 changed files with 344 additions and 228 deletions.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@nextui-org/popover": "^2.1.29",
"@nextui-org/skeleton": "^2.0.32",
"@nextui-org/snippet": "2.0.43",
"@nextui-org/switch": "2.0.34",
"@nextui-org/switch": "^2.0.34",
"@nextui-org/system": "2.2.6",
"@nextui-org/theme": "2.2.11",
"@react-aria/ssr": "3.9.4",
Expand All @@ -36,11 +36,11 @@
"framer-motion": "~11.1.1",
"highcharts": "^11.4.8",
"highcharts-react-official": "^3.2.1",
"iconsax-react": "^0.0.8",
"intl-messageformat": "^10.5.0",
"leaflet": "^1.9.4",
"leaflet-defaulticon-compatibility": "^0.1.2",
"leaflet-geosearch": "^4.0.0",
"lucide-react": "^0.454.0",
"next": "14.2.10",
"next-themes": "^0.2.1",
"react": "18.3.1",
Expand Down Expand Up @@ -89,6 +89,5 @@
"never"
]
}
},
"packageManager": "[email protected]+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}
}
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import '@/styles/globals.css';
import clsx from 'clsx';
import { Metadata, Viewport } from 'next';

import AlertsMenuWrapper from '@/components/AlertsMenu/AlertsMenuWrapper';
import Sidebar from '@/components/Sidebar/Sidebar';
import { AlertsMenuWrapper } from '@/components/AlertsMenu/AlertsMenuWrapper';
import { Sidebar } from '@/components/Sidebar/Sidebar';
import { fontSans } from '@/config/fonts';
import { siteConfig } from '@/config/site';

Expand Down
12 changes: 6 additions & 6 deletions src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ThemeProvider as NextThemesProvider } from 'next-themes';
import type { ThemeProviderProps } from 'next-themes/dist/types.d.ts';
import * as React from 'react';

import { SidebarProvider } from '@/components/Sidebar/SidebarContext';
import { SidebarProvider } from '@/domain/contexts/SidebarContext';

export interface ProvidersProps {
children: React.ReactNode;
Expand All @@ -17,10 +17,10 @@ export function Providers({ children, themeProps }: ProvidersProps) {
const router = useRouter();

return (
<SidebarProvider>
<NextUIProvider navigate={router.push}>
<NextThemesProvider {...themeProps}>{children}</NextThemesProvider>
</NextUIProvider>
</SidebarProvider>
<NextUIProvider navigate={router.push}>
<NextThemesProvider defaultTheme="system" {...themeProps}>
<SidebarProvider>{children} </SidebarProvider>
</NextThemesProvider>
</NextUIProvider>
);
}
25 changes: 25 additions & 0 deletions src/components/AlertsMenu/AlertButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Button } from '@nextui-org/button';
import { Image } from '@nextui-org/image';
import clsx from 'clsx';
import { forwardRef } from 'react';

import { AlertButtonProps } from '@/domain/props/AlertButtonProps';

export const AlertButton = forwardRef<HTMLButtonElement, AlertButtonProps>(
({ icon, label, isSelected, onClick, className, ...props }, ref) => {
return (
<Button
isIconOnly
radius="full"
className={clsx(isSelected ? 'bg-primary' : 'bg-content2', className)}
onClick={onClick}
ref={ref}
{...props}
>
<div className="w-6 h-6 flex items-center justify-center">
<Image src={icon} alt={label} className="object-contain w-auto h-auto max-w-full max-h-full" />
</div>
</Button>
);
}
);
115 changes: 23 additions & 92 deletions src/components/AlertsMenu/AlertsMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,124 +1,55 @@
'use client';

import { Button } from '@nextui-org/button';
import { Image } from '@nextui-org/image';
import { Popover, PopoverContent, PopoverTrigger } from '@nextui-org/popover';
import { useMemo } from 'react';

import { useSidebar } from '../Sidebar/SidebarContext';
import { AlertButton } from '@/components/AlertsMenu/AlertButton';
import { useSidebar } from '@/domain/contexts/SidebarContext';
import { AlertType } from '@/domain/enums/AlertType';
import { AlertsMenuProps } from '@/domain/props/AlertsMenuProps';
import { SidebarOperations } from '@/operations/charts/SidebarOperations';

export type AlertKey = 'hunger' | 'conflicts1' | 'conflicts2' | 'hazards';

export type AlertTypeKey = 'conflicts';

type Alert = {
key: AlertKey;
label: string;
icon: string;
};

type AlertType = {
key: AlertTypeKey;
label: string;
icon: string;
subalerts: Alert[];
};

const alertTypes: (Alert | AlertType)[] = [
{
key: 'hunger',
label: 'Hunger Alert',
icon: '/menu_fcs.png',
},
{
key: 'conflicts',
label: 'Conflicts',
icon: '/menu_conflicts.png',
subalerts: [
{
key: 'conflicts1',
label: 'Conflicts 1',
icon: '/menu_conflicts.png',
},
{
key: 'conflicts2',
label: 'Conflicts 2',
icon: '/menu_conflicts.png',
},
],
},
{
key: 'hazards',
label: 'Hazards',
icon: '/menu_hazards.png',
},
];

type AlertsMenuProps = {
variant: 'outside' | 'inside';
};

export default function AlertsMenu({ variant }: AlertsMenuProps) {
export function AlertsMenu({ variant }: AlertsMenuProps) {
const { isAlertSelected, toggleAlert } = useSidebar();

const isSubAlertClicked = useMemo(
() => (mainAlert: AlertTypeKey) => {
const alert = alertTypes.find((a) => a.key === mainAlert) as AlertType;
return alert.subalerts.some((subalert) => isAlertSelected(subalert.key)) ?? false;
() => (mainAlert: AlertType) => {
const alert = SidebarOperations.getSidebarAlertTypeByKey(mainAlert);
return alert?.subalerts?.some((subalert) => isAlertSelected(subalert.key)) ?? false;
},
[isAlertSelected]
);

return (
<div className="flex gap-1">
{alertTypes.map((item) =>
'subalerts' in item ? (
{SidebarOperations.getSidebarAlertTypes().map((item) =>
SidebarOperations.hasSubalerts(item) ? (
<Popover placement={variant === 'inside' ? 'bottom' : 'top'} key={item.key}>
<PopoverTrigger>
<Button isIconOnly radius="full" className={isSubAlertClicked(item.key) ? 'bg-primary' : 'bg-background'}>
<div className="w-6 h-6 flex items-center justify-center">
<Image
src={item.icon}
alt={item.label}
className="object-contain w-auto h-auto max-w-full max-h-full"
/>
</div>
</Button>
<AlertButton icon={item.icon} label={item.label} isSelected={isSubAlertClicked(item.key)} />
</PopoverTrigger>
<PopoverContent>
<div className="gap-1 flex">
{item.subalerts.map((subalert) => (
<Button
<AlertButton
key={subalert.key}
isIconOnly
radius="full"
className={isAlertSelected(subalert.key) ? 'bg-primary' : 'bg-background'}
icon={subalert.icon}
label={subalert.label}
isSelected={isAlertSelected(subalert.key)}
onClick={() => toggleAlert(subalert.key)}
>
<div className="w-6 h-6 flex items-center justify-center">
<Image
src={subalert.icon}
alt={subalert.label}
className="object-contain w-auto h-auto max-w-full max-h-full"
/>
</div>
</Button>
/>
))}
</div>
</PopoverContent>
</Popover>
) : (
<Button
isIconOnly
radius="full"
className={isAlertSelected(item.key) ? 'bg-primary' : 'bg-background'}
onClick={() => toggleAlert(item.key)}
<AlertButton
key={item.key}
>
<div className="w-6 h-6 flex items-center justify-center">
<Image src={item.icon} alt={item.label} className="object-contain w-auto h-auto max-w-full max-h-full" />
</div>
</Button>
icon={item.icon}
label={item.label}
isSelected={isAlertSelected(item.key)}
onClick={() => toggleAlert(item.key)}
/>
)
)}
</div>
Expand Down
9 changes: 5 additions & 4 deletions src/components/AlertsMenu/AlertsMenuWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
'use client';

import { useSidebar } from '../Sidebar/SidebarContext';
import AlertsMenu from './AlertsMenu';
import { AlertsMenu } from '@/components/AlertsMenu/AlertsMenu';
import { useSidebar } from '@/domain/contexts/SidebarContext';
import { AlertsMenuVariant } from '@/domain/enums/AlertsMenuVariant';

export default function AlertsMenuWrapper() {
export function AlertsMenuWrapper() {
const { isSidebarOpen } = useSidebar();

if (isSidebarOpen) {
return null;
}
return (
<div className="absolute bottom-0 left-0 z-50 p-4">
<AlertsMenu variant="outside" />
<AlertsMenu variant={AlertsMenuVariant.Outside} />
</div>
);
}
45 changes: 45 additions & 0 deletions src/components/Sidebar/CollapsedSidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Button } from '@nextui-org/button';
import { Card, CardBody, CardHeader } from '@nextui-org/card';
import { Image } from '@nextui-org/image';
import { Listbox, ListboxItem } from '@nextui-org/listbox';
import { SidebarRight } from 'iconsax-react';

import { CollapsedSidebarProps } from '@/domain/props/CollapsedSidebarProps';
import { SidebarOperations } from '@/operations/charts/SidebarOperations';

export function CollapsedSidebar({ selectedMapType, handleSelectionChange, toggleSidebar }: CollapsedSidebarProps) {
return (
<div className="absolute top-0 left-0 z-50 p-4">
<Card className="h-full">
<CardHeader className="flex justify-center items-center">
<Button isIconOnly variant="light" onClick={toggleSidebar} aria-label="Close sidebar">
<SidebarRight size={24} />
</Button>
</CardHeader>
<CardBody>
<Listbox
variant="flat"
aria-label="Listbox menu with sections"
selectionMode="single"
selectedKeys={new Set(selectedMapType)}
onSelectionChange={handleSelectionChange}
disallowEmptySelection
hideSelectedIcon
>
{SidebarOperations.getSidebarMapTypes().map((item) => (
<ListboxItem key={item.key} textValue={item.label}>
<div className="w-6 h-6 flex items-center justify-center">
<Image
src={item.icon}
alt={item.label}
className="object-contain w-auto h-auto max-w-full max-h-full"
/>
</div>
</ListboxItem>
))}
</Listbox>
</CardBody>
</Card>
</div>
);
}
Loading

0 comments on commit a11194c

Please sign in to comment.