diff --git a/app/(content)/(gaming)/games/layout.tsx b/app/(content)/(gaming)/games/layout.tsx
deleted file mode 100644
index e825038e820aae5f53f933edfc15181fb31e44a2..0000000000000000000000000000000000000000
--- a/app/(content)/(gaming)/games/layout.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-"use client"
-
-export default function DashboardLayout({
-    children,
-}: {
-    children: React.ReactNode;
-}) {
-    return (
-        <section>
-            <div>
-                {children}
-            </div>
-        </section>
-    );
-}
\ No newline at end of file
diff --git a/app/(content)/(gaming)/games/page.tsx b/app/(content)/(gaming)/games/page.tsx
index 13a76b8a43d4ae48818bdef7e0265bd45e87314a..68138b4fb14885b6da2e492f50f3668215524a52 100644
--- a/app/(content)/(gaming)/games/page.tsx
+++ b/app/(content)/(gaming)/games/page.tsx
@@ -1,10 +1,18 @@
 import { InfiniteScrollGames } from "@/components/InfiniteScroll";
+import Search from "@/components/search-games";
+import Sort from "@/components/sort-games";
 
 // renders a list of games infinitely (presumably)
 export default async function GamesPage() {
     return (
-        <div className="py-5">
-            <InfiniteScrollGames />
-        </div>
+        <main className="relative lg:gap-10 xl:grid xl:grid-cols-[1fr_300px]">
+            <div className="grid">
+                <Search className="p-3 lg:w-2/3 2xl:w-1/3" />
+                <InfiniteScrollGames />
+            </div>
+            <div className="hidden xl:block">
+                <Sort />
+            </div>
+        </main>
     )
 }
\ No newline at end of file
diff --git a/app/(content)/layout.tsx b/app/(content)/layout.tsx
index 06b983170168def7ae12c64c1a653550b7bc647e..8660cfe8e2cc881cd80c182bd9d854801e11a65a 100644
--- a/app/(content)/layout.tsx
+++ b/app/(content)/layout.tsx
@@ -10,8 +10,8 @@ export default async function ContentLayout({
     children,
 }: DashboardLayoutProps) {
     return (
-        <div className="flex min-h-screen flex-col space-y-6">
-            <div className="container grid flex-1 gap-12 md:grid-cols-[200px_1fr]">
+        <div className="flex min-h-screen flex-col">
+            <div className="mx-6 my-6 flex-1 md:grid md:grid-cols-[220px_1fr] md:gap-6 lg:grid-cols-[240px_1fr] lg:gap-10">
                 <aside className="hidden w-[200px] flex-col md:flex">
                     <div className="sticky top-0">
                         <DashboardNav items={dashboardConfig.sidebarNav} />
diff --git a/components/InfiniteScroll.tsx b/components/InfiniteScroll.tsx
index 895e83edf60b7576d4365f1e4bb3363f8ec89459..6aa7bbcc1bcc9eac663dc16b655bcae61ac2ea34 100644
--- a/components/InfiniteScroll.tsx
+++ b/components/InfiniteScroll.tsx
@@ -18,6 +18,7 @@ export function InfiniteScrollGames() {
         ['infiniteGames'],
         async ({ pageParam = 1 }) =>
             await fetch(`/api/games/?page=${pageParam}`,
+                { cache: 'force-cache' }
             ).then((result) => result.json() as Promise<IGame[]>),
         {
             getNextPageParam: (lastPage, pages) => {
@@ -27,7 +28,7 @@ export function InfiniteScrollGames() {
     )
 
     return (
-        <Card className="p-5">
+        <Card className="p-6">
             {status === 'error'
                 ?
                 (<span>Error: {(error as Error).message}</span>)
diff --git a/components/nav.tsx b/components/nav.tsx
index afc15302cd4858bb4840767275e67135cc5b1695..b7c9d441e084b09527aa4e494524b04fad1e464a 100644
--- a/components/nav.tsx
+++ b/components/nav.tsx
@@ -25,7 +25,7 @@ export default function DashboardNav({ items }: DashboardNavProps) {
 
     return (
         <nav className="grid items-start gap-2">
-            <div className="flex items-center py-2">
+            <div className="flex items-center">
                 <Link href="/" className={cn("rounded-full p-3 hover:bg-accent")}>
                     <Icons.logo className="h-7 w-7 dark:hidden" />
                     <Icons.logoWhite className="h-7 w-7 hidden dark:block" />
diff --git a/components/search-games.tsx b/components/search-games.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..14551f34905b4ee0326924bb38cbf737da848b54
--- /dev/null
+++ b/components/search-games.tsx
@@ -0,0 +1,40 @@
+"use client"
+
+import { cn } from '@/lib/utils';
+import { useState } from 'react';
+import { Button } from './ui/button';
+import { Icons } from './ui/icons';
+import { Input } from './ui/input';
+import { toast } from './ui/use-toast';
+
+interface DocsSearchProps extends React.HTMLAttributes<HTMLFormElement> { }
+
+export default function Search({ className, ...props }: DocsSearchProps) {
+    const [searchText, setSearchText] = useState('');
+
+    function onSubmit(event: React.SyntheticEvent) {
+        event.preventDefault()
+
+        return toast({
+            title: "Not implemented",
+            description: "We're still working on the search.",
+        })
+    };
+
+    return (
+        <form
+            onSubmit={onSubmit}
+            className={cn("relative w-full flex justify-end items-center", className)}
+            {...props}
+        >
+            <Input
+                type="search"
+                placeholder="Search..."
+                className="rounded-full pr-12"
+            />
+            <Button variant="outline" size="lg" className="absolute align-middle h-8 px-2.5 mr-1">
+                <Icons.arrowRight className="h-3 w-3" />
+            </Button>
+        </form>
+    );
+}
\ No newline at end of file
diff --git a/components/sort-games.tsx b/components/sort-games.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..76f380eef5126e30f5009bca260900981755c9ca
--- /dev/null
+++ b/components/sort-games.tsx
@@ -0,0 +1,63 @@
+"use client"
+
+import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { useState } from "react";
+import { Card } from "./ui/card";
+
+export default function Sort() {
+  const [select, setSelect] = useState<string>('');
+
+  const handleChange = (event: any) => {
+    const selectedOption = event.target.value as string;
+    setSelect(selectedOption);
+  };
+
+  return (
+    <Card className="p-6 grid items-start gap-2">
+      <Select>
+        <SelectTrigger className="w-full">
+          <SelectValue placeholder="Sort by..." />
+        </SelectTrigger>
+        <SelectContent>
+          <SelectGroup>
+            <SelectLabel>Sorting</SelectLabel>
+            <SelectItem value="">Any</SelectItem>
+            <SelectItem value="name">Name</SelectItem>
+            <SelectItem value="rating">Rating</SelectItem>
+          </SelectGroup>
+        </SelectContent>
+      </Select>
+
+      <h1 className="pt-3">Filter</h1>
+      <Select>
+        <SelectTrigger className="w-full">
+          <SelectValue placeholder="By genre..." />
+        </SelectTrigger>
+        <SelectContent>
+          <SelectGroup>
+            <SelectLabel>Genre</SelectLabel>
+            <SelectItem value="">Any</SelectItem>
+            <SelectItem value="action">Action</SelectItem>
+            <SelectItem value="simulation">Simulation</SelectItem>
+          </SelectGroup>
+        </SelectContent>
+      </Select>
+
+      <Select>
+        <SelectTrigger className="w-full">
+          <SelectValue placeholder="By platform..." />
+        </SelectTrigger>
+        <SelectContent>
+          <SelectGroup>
+            <SelectLabel>Platform</SelectLabel>
+            <SelectItem value="">Any</SelectItem>
+            <SelectItem value="pc">PC</SelectItem>
+            <SelectItem value="playstation">Playstation</SelectItem>
+            <SelectItem value="xbox">Xbox</SelectItem>
+            <SelectItem value="nintendo">Nintendo</SelectItem>
+          </SelectGroup>
+        </SelectContent>
+      </Select>
+    </Card>
+  )
+}
\ No newline at end of file
diff --git a/components/ui/input.tsx b/components/ui/input.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..929e05f50056bb69c128b4ac19fc3b83eed2c646
--- /dev/null
+++ b/components/ui/input.tsx
@@ -0,0 +1,25 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+export interface InputProps
+  extends React.InputHTMLAttributes<HTMLInputElement> {}
+
+const Input = React.forwardRef<HTMLInputElement, InputProps>(
+  ({ className, type, ...props }, ref) => {
+    return (
+      <input
+        type={type}
+        className={cn(
+          "flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
+          className
+        )}
+        ref={ref}
+        {...props}
+      />
+    )
+  }
+)
+Input.displayName = "Input"
+
+export { Input }
diff --git a/components/ui/scroll-area.tsx b/components/ui/scroll-area.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..54b87cd76571b2891f8f4fc8624733fa817eb841
--- /dev/null
+++ b/components/ui/scroll-area.tsx
@@ -0,0 +1,48 @@
+"use client"
+
+import * as React from "react"
+import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
+
+import { cn } from "@/lib/utils"
+
+const ScrollArea = React.forwardRef<
+  React.ElementRef<typeof ScrollAreaPrimitive.Root>,
+  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
+>(({ className, children, ...props }, ref) => (
+  <ScrollAreaPrimitive.Root
+    ref={ref}
+    className={cn("relative overflow-hidden", className)}
+    {...props}
+  >
+    <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
+      {children}
+    </ScrollAreaPrimitive.Viewport>
+    <ScrollBar />
+    <ScrollAreaPrimitive.Corner />
+  </ScrollAreaPrimitive.Root>
+))
+ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
+
+const ScrollBar = React.forwardRef<
+  React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
+  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
+>(({ className, orientation = "vertical", ...props }, ref) => (
+  <ScrollAreaPrimitive.ScrollAreaScrollbar
+    ref={ref}
+    orientation={orientation}
+    className={cn(
+      "flex touch-none select-none transition-colors",
+      orientation === "vertical" &&
+        "h-full w-2.5 border-l border-l-transparent p-[1px]",
+      orientation === "horizontal" &&
+        "h-2.5 border-t border-t-transparent p-[1px]",
+      className
+    )}
+    {...props}
+  >
+    <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
+  </ScrollAreaPrimitive.ScrollAreaScrollbar>
+))
+ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
+
+export { ScrollArea, ScrollBar }
diff --git a/components/ui/select.tsx b/components/ui/select.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0d23fc492c4283de34ece4b29fa5933dde4abe5d
--- /dev/null
+++ b/components/ui/select.tsx
@@ -0,0 +1,120 @@
+"use client"
+
+import * as React from "react"
+import * as SelectPrimitive from "@radix-ui/react-select"
+import { Check, ChevronDown } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const Select = SelectPrimitive.Root
+
+const SelectGroup = SelectPrimitive.Group
+
+const SelectValue = SelectPrimitive.Value
+
+const SelectTrigger = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Trigger>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
+>(({ className, children, ...props }, ref) => (
+  <SelectPrimitive.Trigger
+    ref={ref}
+    className={cn(
+      "flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
+      className
+    )}
+    {...props}
+  >
+    {children}
+    <SelectPrimitive.Icon asChild>
+      <ChevronDown className="h-4 w-4 opacity-50" />
+    </SelectPrimitive.Icon>
+  </SelectPrimitive.Trigger>
+))
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
+
+const SelectContent = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Content>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
+>(({ className, children, position = "popper", ...props }, ref) => (
+  <SelectPrimitive.Portal>
+    <SelectPrimitive.Content
+      ref={ref}
+      className={cn(
+        "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md animate-in fade-in-80",
+        position === "popper" && "translate-y-1",
+        className
+      )}
+      position={position}
+      {...props}
+    >
+      <SelectPrimitive.Viewport
+        className={cn(
+          "p-1",
+          position === "popper" &&
+            "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
+        )}
+      >
+        {children}
+      </SelectPrimitive.Viewport>
+    </SelectPrimitive.Content>
+  </SelectPrimitive.Portal>
+))
+SelectContent.displayName = SelectPrimitive.Content.displayName
+
+const SelectLabel = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Label>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.Label
+    ref={ref}
+    className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
+    {...props}
+  />
+))
+SelectLabel.displayName = SelectPrimitive.Label.displayName
+
+const SelectItem = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Item>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
+>(({ className, children, ...props }, ref) => (
+  <SelectPrimitive.Item
+    ref={ref}
+    className={cn(
+      "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+      className
+    )}
+    {...props}
+  >
+    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+      <SelectPrimitive.ItemIndicator>
+        <Check className="h-4 w-4" />
+      </SelectPrimitive.ItemIndicator>
+    </span>
+
+    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
+  </SelectPrimitive.Item>
+))
+SelectItem.displayName = SelectPrimitive.Item.displayName
+
+const SelectSeparator = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Separator>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.Separator
+    ref={ref}
+    className={cn("-mx-1 my-1 h-px bg-muted", className)}
+    {...props}
+  />
+))
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName
+
+export {
+  Select,
+  SelectGroup,
+  SelectValue,
+  SelectTrigger,
+  SelectContent,
+  SelectLabel,
+  SelectItem,
+  SelectSeparator,
+}
diff --git a/components/ui/toast.tsx b/components/ui/toast.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2deb2e9cc94af0be722b6a433a6d309621f12a5f
--- /dev/null
+++ b/components/ui/toast.tsx
@@ -0,0 +1,127 @@
+import * as React from "react"
+import * as ToastPrimitives from "@radix-ui/react-toast"
+import { VariantProps, cva } from "class-variance-authority"
+import { X } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const ToastProvider = ToastPrimitives.Provider
+
+const ToastViewport = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Viewport>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
+>(({ className, ...props }, ref) => (
+  <ToastPrimitives.Viewport
+    ref={ref}
+    className={cn(
+      "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
+      className
+    )}
+    {...props}
+  />
+))
+ToastViewport.displayName = ToastPrimitives.Viewport.displayName
+
+const toastVariants = cva(
+  "data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full",
+  {
+    variants: {
+      variant: {
+        default: "bg-background border",
+        destructive:
+          "group destructive border-destructive bg-destructive text-destructive-foreground",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+    },
+  }
+)
+
+const Toast = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Root>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
+    VariantProps<typeof toastVariants>
+>(({ className, variant, ...props }, ref) => {
+  return (
+    <ToastPrimitives.Root
+      ref={ref}
+      className={cn(toastVariants({ variant }), className)}
+      {...props}
+    />
+  )
+})
+Toast.displayName = ToastPrimitives.Root.displayName
+
+const ToastAction = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Action>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
+>(({ className, ...props }, ref) => (
+  <ToastPrimitives.Action
+    ref={ref}
+    className={cn(
+      "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-destructive/30 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
+      className
+    )}
+    {...props}
+  />
+))
+ToastAction.displayName = ToastPrimitives.Action.displayName
+
+const ToastClose = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Close>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
+>(({ className, ...props }, ref) => (
+  <ToastPrimitives.Close
+    ref={ref}
+    className={cn(
+      "absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
+      className
+    )}
+    toast-close=""
+    {...props}
+  >
+    <X className="h-4 w-4" />
+  </ToastPrimitives.Close>
+))
+ToastClose.displayName = ToastPrimitives.Close.displayName
+
+const ToastTitle = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Title>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
+>(({ className, ...props }, ref) => (
+  <ToastPrimitives.Title
+    ref={ref}
+    className={cn("text-sm font-semibold", className)}
+    {...props}
+  />
+))
+ToastTitle.displayName = ToastPrimitives.Title.displayName
+
+const ToastDescription = React.forwardRef<
+  React.ElementRef<typeof ToastPrimitives.Description>,
+  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
+>(({ className, ...props }, ref) => (
+  <ToastPrimitives.Description
+    ref={ref}
+    className={cn("text-sm opacity-90", className)}
+    {...props}
+  />
+))
+ToastDescription.displayName = ToastPrimitives.Description.displayName
+
+type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
+
+type ToastActionElement = React.ReactElement<typeof ToastAction>
+
+export {
+  type ToastProps,
+  type ToastActionElement,
+  ToastProvider,
+  ToastViewport,
+  Toast,
+  ToastTitle,
+  ToastDescription,
+  ToastClose,
+  ToastAction,
+}
diff --git a/components/ui/use-toast.ts b/components/ui/use-toast.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c70c0d61949e822e1c5f2530d91aad64ded73d47
--- /dev/null
+++ b/components/ui/use-toast.ts
@@ -0,0 +1,189 @@
+// Inspired by react-hot-toast library
+import * as React from "react"
+
+import { ToastActionElement, type ToastProps } from "@/components/ui/toast"
+
+const TOAST_LIMIT = 1
+const TOAST_REMOVE_DELAY = 1000000
+
+type ToasterToast = ToastProps & {
+  id: string
+  title?: React.ReactNode
+  description?: React.ReactNode
+  action?: ToastActionElement
+}
+
+const actionTypes = {
+  ADD_TOAST: "ADD_TOAST",
+  UPDATE_TOAST: "UPDATE_TOAST",
+  DISMISS_TOAST: "DISMISS_TOAST",
+  REMOVE_TOAST: "REMOVE_TOAST",
+} as const
+
+let count = 0
+
+function genId() {
+  count = (count + 1) % Number.MAX_VALUE
+  return count.toString()
+}
+
+type ActionType = typeof actionTypes
+
+type Action =
+  | {
+      type: ActionType["ADD_TOAST"]
+      toast: ToasterToast
+    }
+  | {
+      type: ActionType["UPDATE_TOAST"]
+      toast: Partial<ToasterToast>
+    }
+  | {
+      type: ActionType["DISMISS_TOAST"]
+      toastId?: ToasterToast["id"]
+    }
+  | {
+      type: ActionType["REMOVE_TOAST"]
+      toastId?: ToasterToast["id"]
+    }
+
+interface State {
+  toasts: ToasterToast[]
+}
+
+const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
+
+const addToRemoveQueue = (toastId: string) => {
+  if (toastTimeouts.has(toastId)) {
+    return
+  }
+
+  const timeout = setTimeout(() => {
+    toastTimeouts.delete(toastId)
+    dispatch({
+      type: "REMOVE_TOAST",
+      toastId: toastId,
+    })
+  }, TOAST_REMOVE_DELAY)
+
+  toastTimeouts.set(toastId, timeout)
+}
+
+export const reducer = (state: State, action: Action): State => {
+  switch (action.type) {
+    case "ADD_TOAST":
+      return {
+        ...state,
+        toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
+      }
+
+    case "UPDATE_TOAST":
+      return {
+        ...state,
+        toasts: state.toasts.map((t) =>
+          t.id === action.toast.id ? { ...t, ...action.toast } : t
+        ),
+      }
+
+    case "DISMISS_TOAST": {
+      const { toastId } = action
+
+      // ! Side effects ! - This could be extracted into a dismissToast() action,
+      // but I'll keep it here for simplicity
+      if (toastId) {
+        addToRemoveQueue(toastId)
+      } else {
+        state.toasts.forEach((toast) => {
+          addToRemoveQueue(toast.id)
+        })
+      }
+
+      return {
+        ...state,
+        toasts: state.toasts.map((t) =>
+          t.id === toastId || toastId === undefined
+            ? {
+                ...t,
+                open: false,
+              }
+            : t
+        ),
+      }
+    }
+    case "REMOVE_TOAST":
+      if (action.toastId === undefined) {
+        return {
+          ...state,
+          toasts: [],
+        }
+      }
+      return {
+        ...state,
+        toasts: state.toasts.filter((t) => t.id !== action.toastId),
+      }
+  }
+}
+
+const listeners: Array<(state: State) => void> = []
+
+let memoryState: State = { toasts: [] }
+
+function dispatch(action: Action) {
+  memoryState = reducer(memoryState, action)
+  listeners.forEach((listener) => {
+    listener(memoryState)
+  })
+}
+
+interface Toast extends Omit<ToasterToast, "id"> {}
+
+function toast({ ...props }: Toast) {
+  const id = genId()
+
+  const update = (props: ToasterToast) =>
+    dispatch({
+      type: "UPDATE_TOAST",
+      toast: { ...props, id },
+    })
+  const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
+
+  dispatch({
+    type: "ADD_TOAST",
+    toast: {
+      ...props,
+      id,
+      open: true,
+      onOpenChange: (open) => {
+        if (!open) dismiss()
+      },
+    },
+  })
+
+  return {
+    id: id,
+    dismiss,
+    update,
+  }
+}
+
+function useToast() {
+  const [state, setState] = React.useState<State>(memoryState)
+
+  React.useEffect(() => {
+    listeners.push(setState)
+    return () => {
+      const index = listeners.indexOf(setState)
+      if (index > -1) {
+        listeners.splice(index, 1)
+      }
+    }
+  }, [state])
+
+  return {
+    ...state,
+    toast,
+    dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
+  }
+}
+
+export { useToast, toast }
diff --git a/package-lock.json b/package-lock.json
index 8f0f3cb5aebdc29cfd29089caa35f221168e5280..a1ff6ee240459811cdd649e31671ba439e6537b5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,10 @@
         "@clerk/themes": "^1.7.3",
         "@prisma/client": "^4.14.1",
         "@radix-ui/react-dropdown-menu": "^2.0.4",
+        "@radix-ui/react-scroll-area": "^1.0.3",
+        "@radix-ui/react-select": "^1.2.1",
         "@radix-ui/react-slot": "^1.0.1",
+        "@radix-ui/react-toast": "^1.1.3",
         "@tanstack/react-query": "^4.29.7",
         "class-variance-authority": "^0.6.0",
         "clsx": "^1.2.1",
@@ -642,6 +645,14 @@
       "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c.tgz",
       "integrity": "sha512-3jum8/YSudeSN0zGW5qkpz+wAN2V/NYCQ+BPjvHYDfWatLWlQkqy99toX0GysDeaUoBIJg1vaz2yKqiA3CFcQw=="
     },
+    "node_modules/@radix-ui/number": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz",
+      "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10"
+      }
+    },
     "node_modules/@radix-ui/primitive": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz",
@@ -899,6 +910,60 @@
         "react-dom": "^16.8 || ^17.0 || ^18.0"
       }
     },
+    "node_modules/@radix-ui/react-scroll-area": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.3.tgz",
+      "integrity": "sha512-sBX9j8Q+0/jReNObEAveKIGXJtk3xUoSIx4cMKygGtO128QJyVDn01XNOFsyvihKDCTcu7SINzQ2jPAZEhIQtw==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10",
+        "@radix-ui/number": "1.0.0",
+        "@radix-ui/primitive": "1.0.0",
+        "@radix-ui/react-compose-refs": "1.0.0",
+        "@radix-ui/react-context": "1.0.0",
+        "@radix-ui/react-direction": "1.0.0",
+        "@radix-ui/react-presence": "1.0.0",
+        "@radix-ui/react-primitive": "1.0.2",
+        "@radix-ui/react-use-callback-ref": "1.0.0",
+        "@radix-ui/react-use-layout-effect": "1.0.0"
+      },
+      "peerDependencies": {
+        "react": "^16.8 || ^17.0 || ^18.0",
+        "react-dom": "^16.8 || ^17.0 || ^18.0"
+      }
+    },
+    "node_modules/@radix-ui/react-select": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.1.tgz",
+      "integrity": "sha512-GULRMITaOHNj79BZvQs3iZO0+f2IgI8g5HDhMi7Bnc13t7IlG86NFtOCfTLme4PNZdEtU+no+oGgcl6IFiphpQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10",
+        "@radix-ui/number": "1.0.0",
+        "@radix-ui/primitive": "1.0.0",
+        "@radix-ui/react-collection": "1.0.2",
+        "@radix-ui/react-compose-refs": "1.0.0",
+        "@radix-ui/react-context": "1.0.0",
+        "@radix-ui/react-direction": "1.0.0",
+        "@radix-ui/react-dismissable-layer": "1.0.3",
+        "@radix-ui/react-focus-guards": "1.0.0",
+        "@radix-ui/react-focus-scope": "1.0.2",
+        "@radix-ui/react-id": "1.0.0",
+        "@radix-ui/react-popper": "1.1.1",
+        "@radix-ui/react-portal": "1.0.2",
+        "@radix-ui/react-primitive": "1.0.2",
+        "@radix-ui/react-slot": "1.0.1",
+        "@radix-ui/react-use-callback-ref": "1.0.0",
+        "@radix-ui/react-use-controllable-state": "1.0.0",
+        "@radix-ui/react-use-layout-effect": "1.0.0",
+        "@radix-ui/react-use-previous": "1.0.0",
+        "@radix-ui/react-visually-hidden": "1.0.2",
+        "aria-hidden": "^1.1.1",
+        "react-remove-scroll": "2.5.5"
+      },
+      "peerDependencies": {
+        "react": "^16.8 || ^17.0 || ^18.0",
+        "react-dom": "^16.8 || ^17.0 || ^18.0"
+      }
+    },
     "node_modules/@radix-ui/react-slot": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz",
@@ -911,6 +976,30 @@
         "react": "^16.8 || ^17.0 || ^18.0"
       }
     },
+    "node_modules/@radix-ui/react-toast": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.3.tgz",
+      "integrity": "sha512-yHFgpxi9wjbfPvpSPdYAzivCqw48eA1ofT8m/WqYOVTxKPdmQMuVKRYPlMmj4C1d6tJdFj/LBa1J4iY3fL4OwQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10",
+        "@radix-ui/primitive": "1.0.0",
+        "@radix-ui/react-collection": "1.0.2",
+        "@radix-ui/react-compose-refs": "1.0.0",
+        "@radix-ui/react-context": "1.0.0",
+        "@radix-ui/react-dismissable-layer": "1.0.3",
+        "@radix-ui/react-portal": "1.0.2",
+        "@radix-ui/react-presence": "1.0.0",
+        "@radix-ui/react-primitive": "1.0.2",
+        "@radix-ui/react-use-callback-ref": "1.0.0",
+        "@radix-ui/react-use-controllable-state": "1.0.0",
+        "@radix-ui/react-use-layout-effect": "1.0.0",
+        "@radix-ui/react-visually-hidden": "1.0.2"
+      },
+      "peerDependencies": {
+        "react": "^16.8 || ^17.0 || ^18.0",
+        "react-dom": "^16.8 || ^17.0 || ^18.0"
+      }
+    },
     "node_modules/@radix-ui/react-use-callback-ref": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz",
@@ -957,6 +1046,17 @@
         "react": "^16.8 || ^17.0 || ^18.0"
       }
     },
+    "node_modules/@radix-ui/react-use-previous": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.0.tgz",
+      "integrity": "sha512-RG2K8z/K7InnOKpq6YLDmT49HGjNmrK+fr82UCVKT2sW0GYfVnYp4wZWBooT/EYfQ5faA9uIjvsuMMhH61rheg==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10"
+      },
+      "peerDependencies": {
+        "react": "^16.8 || ^17.0 || ^18.0"
+      }
+    },
     "node_modules/@radix-ui/react-use-rect": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz",
@@ -981,6 +1081,19 @@
         "react": "^16.8 || ^17.0 || ^18.0"
       }
     },
+    "node_modules/@radix-ui/react-visually-hidden": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.2.tgz",
+      "integrity": "sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg==",
+      "dependencies": {
+        "@babel/runtime": "^7.13.10",
+        "@radix-ui/react-primitive": "1.0.2"
+      },
+      "peerDependencies": {
+        "react": "^16.8 || ^17.0 || ^18.0",
+        "react-dom": "^16.8 || ^17.0 || ^18.0"
+      }
+    },
     "node_modules/@radix-ui/rect": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz",
diff --git a/package.json b/package.json
index 2a17a6412103f65ed53a74a6cec2e31659246cf3..aee36ccf609ed52b3a2e520a1dddd27d6bb59e1a 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,10 @@
     "@clerk/themes": "^1.7.3",
     "@prisma/client": "^4.14.1",
     "@radix-ui/react-dropdown-menu": "^2.0.4",
+    "@radix-ui/react-scroll-area": "^1.0.3",
+    "@radix-ui/react-select": "^1.2.1",
     "@radix-ui/react-slot": "^1.0.1",
+    "@radix-ui/react-toast": "^1.1.3",
     "@tanstack/react-query": "^4.29.7",
     "class-variance-authority": "^0.6.0",
     "clsx": "^1.2.1",