Skip to content

Commit

Permalink
Feat: Enhance Filter UI
Browse files Browse the repository at this point in the history
  • Loading branch information
lauchaves committed Nov 25, 2024
1 parent df2d9c3 commit f465b90
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 123 deletions.
178 changes: 112 additions & 66 deletions frontend/app/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { createContext, useContext, useState, ReactNode } from "react";
import { cn } from "@/lib/utils";
import { X, Menu } from "lucide-react";
import { cn } from "@/lib/utils";
import { Menu, X } from "lucide-react";
import React, { createContext, useContext, useState, ReactNode, useRef, useEffect } from "react";

interface SidebarContextType {
isOpen: boolean;
Expand Down Expand Up @@ -28,75 +28,121 @@ export const useSidebar = () => {
return context;
};

export const Sidebar = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => {
const { isOpen } = useSidebar();
return (
<div
ref={ref}
className={cn(
"fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-lg transition-transform duration-300",
isOpen ? "translate-x-0" : "-translate-x-full",
className
)}
{...props}
/>
);
}
);
export const Sidebar = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const { isOpen, toggleSidebar } = useSidebar();
const sidebarRef = useRef<HTMLDivElement>(null);

// Close sidebar when clicking outside
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (sidebarRef.current && !sidebarRef.current.contains(event.target as Node)) {
// Close sidebar if the click is outside
if (isOpen) {
toggleSidebar();
}
}
};

document.addEventListener("mousedown", handleClickOutside);

return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOpen, toggleSidebar]);

return (
<div
ref={(node) => {
sidebarRef.current = node;
if (ref) {
if (typeof ref === "function") ref(node);
else ref.current = node;
}
}}
className={cn(
"fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-lg transition-transform duration-300",
isOpen ? "translate-x-0" : "-translate-x-full",
className
)}
{...props}
/>
);
});
Sidebar.displayName = "Sidebar";

export const SidebarHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={cn("px-4 py-2 border-b flex justify-between items-center", className)} {...props}>
{props.children}
<SidebarClose />
</div>
)
);
export const SidebarHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"px-4 py-2 border-b flex justify-between items-center",
className
)}
{...props}
>
{props.children}
<SidebarClose />
</div>
));
SidebarHeader.displayName = "SidebarHeader";

export const SidebarContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex-1 overflow-y-auto p-4", className)} {...props} />
)
);
export const SidebarContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex-1 overflow-y-auto", className)}
{...props}
/>
));
SidebarContent.displayName = "SidebarContent";

export const SidebarTrigger = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
({ className, ...props }, ref) => {
const { toggleSidebar } = useSidebar();
return (
<button
ref={ref}
onClick={toggleSidebar}
className={cn("p-2", className)}
{...props}
>
<Menu size={30} className="text-black"/>
<span className="sr-only">Toggle Sidebar</span>
</button>
);
}
);
export const SidebarTrigger = React.forwardRef<
HTMLButtonElement,
React.ButtonHTMLAttributes<HTMLButtonElement>
>(({ className, ...props }, ref) => {
const { toggleSidebar } = useSidebar();
return (
<button
ref={ref}
onClick={toggleSidebar}
className={cn(
"flex items-center gap-2 mt-2 p-1 border border-transparent hover:border-[#ccc] transition-all duration-200",
className
)}
{...props}
>
<Menu size={30} className="text-black" />
<span className="text-sm">All</span>
</button>
);
});
SidebarTrigger.displayName = "SidebarTrigger";

export const SidebarClose = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
({ className, ...props }, ref) => {
const { toggleSidebar } = useSidebar();
return (
<button
ref={ref}
onClick={toggleSidebar}
className={cn("absolute right-4 top-4 opacity-70 hover:opacity-100", className)}
{...props}
>
<X className="h-4 w-4" />
<span className="sr-only">Close Sidebar</span>
</button>
);
}
);
export const SidebarClose = React.forwardRef<
HTMLButtonElement,
React.ButtonHTMLAttributes<HTMLButtonElement>
>(({ className, ...props }, ref) => {
const { toggleSidebar } = useSidebar();
return (
<button
ref={ref}
onClick={toggleSidebar}
className={cn(
"absolute right-4 top-4 opacity-70 hover:opacity-100",
className
)}
{...props}
>
<X className="h-4 w-4" />
<span className="sr-only">Close Sidebar</span>
</button>
);
});
SidebarClose.displayName = "SidebarClose";

// export { SidebarProvider, Sidebar, SidebarHeader, SidebarContent, SidebarTrigger, SidebarClose };
60 changes: 37 additions & 23 deletions frontend/app/components/ui/slider.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
"use client"

import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"

import { cn } from "@/lib/utils"
import * as SliderPrimitive from "@radix-ui/react-slider";
import * as React from "react";
import { cn } from "@/lib/utils";

const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn(
"relative flex w-full touch-none select-none items-center",
className
)}
{...props}
>
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" />
</SliderPrimitive.Root>
))
Slider.displayName = SliderPrimitive.Root.displayName
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> & { value: [number, number]; onValueChange: (value: [number, number]) => void; }
>(({ className, value, onValueChange, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn("relative flex w-full touch-none select-none items-center", className)}
value={value}
onValueChange={onValueChange}
max={1500}
min={0}
step={10}
{...props}
>
{/* Range */}
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>

{/* Min Value */}
<SliderPrimitive.Thumb
className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
style={{ left: `${(value[0] / 1500) * 100}%` }}
/>

{/* Max Value */}
<SliderPrimitive.Thumb
className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
style={{ left: `${(value[1] / 1500) * 100}%` }}
/>
</SliderPrimitive.Root>
));

Slider.displayName = "Slider";

export { Slider }
export { Slider }
Loading

0 comments on commit f465b90

Please sign in to comment.