From cfeb937819b64b4b242cf83ecbe5b6f2ddc361a8 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Tue, 5 Nov 2024 14:55:42 +0200
Subject: [PATCH 1/8] #56 made nav bar mobile friendly

---
 package.json                     |   1 +
 pnpm-lock.yaml                   |  75 +++++++++++++++++++
 src/app/_components/header.tsx   |  36 ++++++----
 src/components/slide-in-menu.tsx | 120 +++++++++++++++++++++++++++++++
 src/components/ui/button.tsx     |   2 +-
 5 files changed, 219 insertions(+), 15 deletions(-)
 create mode 100644 src/components/slide-in-menu.tsx

diff --git a/package.json b/package.json
index 81448ea..b1943b7 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
     "@radix-ui/react-dropdown-menu": "^2.1.2",
     "@radix-ui/react-icons": "^1.3.1",
     "@radix-ui/react-label": "^2.1.0",
+    "@radix-ui/react-navigation-menu": "^1.2.1",
     "@radix-ui/react-slot": "^1.1.0",
     "@t3-oss/env-nextjs": "^0.10.1",
     "@tanstack/react-query": "^5.50.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c509405..ca796eb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -44,6 +44,9 @@ importers:
       '@radix-ui/react-label':
         specifier: ^2.1.0
         version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@radix-ui/react-navigation-menu':
+        specifier: ^1.2.1
+        version: 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@radix-ui/react-slot':
         specifier: ^1.1.0
         version: 1.1.0(@types/react@18.3.12)(react@18.3.1)
@@ -1854,6 +1857,19 @@ packages:
       '@types/react-dom':
         optional: true
 
+  '@radix-ui/react-navigation-menu@1.2.1':
+    resolution: {integrity: sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q==}
+    peerDependencies:
+      '@types/react': '*'
+      '@types/react-dom': '*'
+      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+      react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+      '@types/react-dom':
+        optional: true
+
   '@radix-ui/react-popper@1.2.0':
     resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==}
     peerDependencies:
@@ -1964,6 +1980,15 @@ packages:
       '@types/react':
         optional: true
 
+  '@radix-ui/react-use-previous@1.1.0':
+    resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==}
+    peerDependencies:
+      '@types/react': '*'
+      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+
   '@radix-ui/react-use-rect@1.1.0':
     resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
     peerDependencies:
@@ -1982,6 +2007,19 @@ packages:
       '@types/react':
         optional: true
 
+  '@radix-ui/react-visually-hidden@1.1.0':
+    resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==}
+    peerDependencies:
+      '@types/react': '*'
+      '@types/react-dom': '*'
+      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+      react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+      '@types/react-dom':
+        optional: true
+
   '@radix-ui/rect@1.1.0':
     resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
 
@@ -8098,6 +8136,28 @@ snapshots:
       '@types/react': 18.3.12
       '@types/react-dom': 18.3.1
 
+  '@radix-ui/react-navigation-menu@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+    dependencies:
+      '@radix-ui/primitive': 1.1.0
+      '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.12)(react@18.3.1)
+      '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      react: 18.3.1
+      react-dom: 18.3.1(react@18.3.1)
+    optionalDependencies:
+      '@types/react': 18.3.12
+      '@types/react-dom': 18.3.1
+
   '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -8195,6 +8255,12 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.12
 
+  '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.12)(react@18.3.1)':
+    dependencies:
+      react: 18.3.1
+    optionalDependencies:
+      '@types/react': 18.3.12
+
   '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.12)(react@18.3.1)':
     dependencies:
       '@radix-ui/rect': 1.1.0
@@ -8209,6 +8275,15 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.12
 
+  '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+    dependencies:
+      '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      react: 18.3.1
+      react-dom: 18.3.1(react@18.3.1)
+    optionalDependencies:
+      '@types/react': 18.3.12
+      '@types/react-dom': 18.3.1
+
   '@radix-ui/rect@1.1.0': {}
 
   '@remix-run/router@1.5.0': {}
diff --git a/src/app/_components/header.tsx b/src/app/_components/header.tsx
index 9f2a5df..6436147 100644
--- a/src/app/_components/header.tsx
+++ b/src/app/_components/header.tsx
@@ -2,18 +2,20 @@
 
 import Link from "next/link";
 import Image from "next/image";
-import React from "react";
+import React, { useState } from "react";
+import SlideInMenu from "~/components/slide-in-menu";
 
 const Header = () => {
+  const [isMenuOpen] = useState(false);
+
   return (
     <>
       <header className="w-full bg-background_dark text-text-dark relative overflow-hidden h-28">
-        <div className="relative flex justify-between items-center h-full">
-          {/* blue background with responsive width */}
+        <div className="relative flex justify-between items-center h-full px-4 sm:px-8">
           <div
             className="
               absolute inset-y-0 left-0
-              w-3/5
+              w-4/5
               sm:w-1/2 
               lg:w-[32%] 
               bg-[#2C5696] 
@@ -24,7 +26,7 @@ const Header = () => {
             "
           ></div>
 
-          <a href="/" className="relative z-10 flex items-center pl-8 ml-28">
+          <a href="/" className="relative z-10 flex items-center pl-4 sm:pl-8">
             <Image
               src="/logos/UT_website_logo_white_est.svg"
               alt="Logo"
@@ -33,35 +35,41 @@ const Header = () => {
             />
           </a>
 
-          <div className="relative z-10 flex items-center pr-8 space-x-6">
-            <button className="hover:text-primary-dark text-text-dark text-lg">ENG</button>
-            <button className="hover:text-primary-dark text-text-dark text-lg">EST</button>
-            <button className="bg-primary-dark text-white px-4 py-2 rounded hover:bg-primary-dark_hover">
+          <div className="relative z-10 flex items-center space-x-4 sm:space-x-6">
+            <button className="hover:text-primary-dark text-text-dark text-lg hidden sm:block">ENG</button>
+            <button className="hover:text-primary-dark text-text-dark text-lg hidden sm:block">EST</button>
+            <div className="block sm:hidden"> 
+              <SlideInMenu />
+            </div>
+            <button className="bg-primary-dark text-white px-4 py-2 rounded hover:bg-primary-dark_hover hidden sm:block">
               Log In
             </button>
           </div>
         </div>
       </header>
 
-      <nav className="w-full bg-background text-text-dark overflow-hidden h-16 flex justify-center items-center space-x-32">
+      <nav className={`w-full bg-background text-text-dark overflow-hidden ${isMenuOpen ? 'block' : 'hidden'} mt-4 sm:flex justify-center items-center space-x-0 sm:space-x-32`}>
         <Link href="/">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696]">
+          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
             All exhibitions
           </span>
         </Link>
         <Link href="/dashboard">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696]">
+          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
             Dashboard
           </span>
         </Link>
         <Link href="/archive">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696]">
+          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
             Archive
           </span>
         </Link>
+        <button className="bg-primary-dark text-white px-4 py-2 rounded hover:bg-primary-dark_hover block sm:hidden mt-2">
+          Log In
+        </button>
       </nav>
     </>
   );
 };
 
-export default Header;
+export default Header;
\ No newline at end of file
diff --git a/src/components/slide-in-menu.tsx b/src/components/slide-in-menu.tsx
new file mode 100644
index 0000000..32725a0
--- /dev/null
+++ b/src/components/slide-in-menu.tsx
@@ -0,0 +1,120 @@
+'use client'
+
+import { useState, useEffect } from 'react'
+import { Menu, X, LogIn } from 'lucide-react'
+import { Button } from "~/components/ui/button"
+import { Input } from "~/components/ui/input"
+import { Label } from "~/components/ui/label"
+import Link from "next/link"
+
+export default function Component() {
+  const [isOpen, setIsOpen] = useState(false)
+  const [selectedLanguage, setSelectedLanguage] = useState('ENG')
+
+  useEffect(() => {
+    const handleEscape = (event: KeyboardEvent) => {
+      if (event.key === 'Escape') {
+        setIsOpen(false)
+      }
+    }
+
+    document.addEventListener('keydown', handleEscape)
+    return () => document.removeEventListener('keydown', handleEscape)
+  }, [])
+
+  useEffect(() => {
+    if (isOpen) {
+      document.body.style.overflow = 'hidden'
+    } else {
+      document.body.style.overflow = ''
+    }
+
+    return () => {
+      document.body.style.overflow = ''
+    }
+  }, [isOpen])
+
+  return (
+    <>
+      <Button
+        variant="default"
+        className="sticky top-8 right-4 z-50 text-2xl"
+        onClick={() => setIsOpen(true)}>
+          âک°        
+        <span className="sr-only">Open menu</span>
+      </Button>
+
+      {isOpen && (
+        <div
+          className="fixed inset-0 bg-black bg-opacity-50 z-40"
+          onClick={() => setIsOpen(false)}
+        />
+      )}
+
+      <div
+        className={`fixed top-0 right-0 h-full w-[70vw] sm:w-[400px] bg-background p-6 overflow-y-auto transition-transform duration-300 ease-in-out z-50 ${
+          isOpen ? 'translate-x-0' : 'translate-x-full'
+        }`}
+      >
+        <Button
+          variant="ghost"
+          size="icon"
+          onClick={() => setIsOpen(false)}
+          className="absolute right-4 top-4"
+        >
+          <X className="h-4 w-4" />
+          <span className="sr-only">Close</span>
+        </Button>
+
+        <h2 className="text-2xl font-bold mb-6">Menu</h2>
+
+        <div className="space-y-4">
+          <div className="space-y-2">
+            <Label htmlFor="email">Email</Label>
+            <Input id="email" type="email" placeholder="m@example.com" />
+          </div>
+          <div className="space-y-2">
+            <Label htmlFor="password">Password</Label>
+            <Input id="password" type="password" />
+          </div>
+          <Button className="w-full bg-primary-dark text-white">
+            <LogIn className="mr-2 h-4 w-4 " /> Log In
+          </Button>
+        </div>
+
+        <div className="mt-8 space-y-2">
+          <Link href="/" className="block border-t border-b border-gray-300 py-2">
+            All exhibitions
+          </Link>
+          <Link href="/dashboard" className="block border-gray-300">
+            Dashboard
+          </Link>
+          <Link href="/archive" className="block border-t border-b border-gray-300 py-2">
+            Archive
+          </Link>
+        </div>
+
+        <div className="mt-8 absolute bottom-6 w-full">
+          <div className="flex space-x-4">
+            <h3 className="text-lg font-semibold">Language:</h3>
+            <div className="space-x-2">
+              <button
+                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'ENG' ? 'underline' : ''}`}
+                onClick={() => setSelectedLanguage('ENG')}
+              >
+                ENG
+              </button>
+              <span className="text-text-dark">|</span>
+              <button
+                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'EST' ? 'underline' : ''}`}
+                onClick={() => setSelectedLanguage('EST')}
+              >
+                EST
+              </button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </>
+  )
+}
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 3eb6759..55e463e 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -10,7 +10,7 @@ const buttonVariants = cva(
     variants: {
       variant: {
         default:
-          "bg-primary text-primary-foreground shadow hover:bg-primary/90",
+          "bg-primary-default text-primary-foreground hover:bg-primary",
         destructive:
           "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
         outline:
-- 
GitLab


From 8c0eb1cd680adad5d1dfe89f4ac7a65e0ce91693 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Tue, 5 Nov 2024 16:45:24 +0200
Subject: [PATCH 2/8] #56 refactoring the dashboard view

---
 .../exhibition-dashboard-cards.tsx            | 105 +++++-------------
 src/app/_components/exhibition-section.tsx    |  19 +---
 src/app/dashboard/page.tsx                    |  34 +-----
 src/hooks/responsive-visible-drafts.ts        |  35 ++++++
 4 files changed, 70 insertions(+), 123 deletions(-)
 create mode 100644 src/hooks/responsive-visible-drafts.ts

diff --git a/src/app/_components/exhibition-dashboard-cards.tsx b/src/app/_components/exhibition-dashboard-cards.tsx
index e39f168..40652f8 100644
--- a/src/app/_components/exhibition-dashboard-cards.tsx
+++ b/src/app/_components/exhibition-dashboard-cards.tsx
@@ -4,7 +4,7 @@ import React, { useState } from "react";
 import Image from "next/image";
 import dynamic from "next/dynamic";
 import { useRouter } from "next/navigation";
-import { Cog } from "lucide-react";
+import { Settings } from "lucide-react";
 import { configurations } from "~/constants/config";
 import {
   useDeleteExhibition,
@@ -13,32 +13,17 @@ import {
 } from "~/hooks/exhibition-actions";
 import { type Exhibition } from "~/app/_types/exhibition";
 
-const DropdownMenu = dynamic(() =>
-  import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenu),
-);
-const DropdownMenuTrigger = dynamic(() =>
-  import("~/components/ui/dropdown-menu").then(
-    (mod) => mod.DropdownMenuTrigger,
-  ),
-);
-const DropdownMenuContent = dynamic(() =>
-  import("~/components/ui/dropdown-menu").then(
-    (mod) => mod.DropdownMenuContent,
-  ),
-);
-const DropdownMenuItem = dynamic(() =>
-  import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenuItem),
-);
+const DropdownMenu = dynamic(() => import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenu));
+const DropdownMenuTrigger = dynamic(() => import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenuTrigger));
+const DropdownMenuContent = dynamic(() => import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenuContent));
+const DropdownMenuItem = dynamic(() => import("~/components/ui/dropdown-menu").then((mod) => mod.DropdownMenuItem));
 
 interface ExhibitionCardProps {
   exhibition: Exhibition;
   onClick: (id: number) => void;
 }
 
-export default function ExhibitionCard({
-  exhibition,
-  onClick,
-}: ExhibitionCardProps) {
+export default function ExhibitionCard({ exhibition, onClick }: ExhibitionCardProps) {
   const [isMenuOpen, setIsMenuOpen] = useState(false);
   const router = useRouter();
 
@@ -48,49 +33,34 @@ export default function ExhibitionCard({
 
   const handleEdit = (e: React.MouseEvent) => {
     e.stopPropagation();
-    if (exhibition.id) {
-      router.push(`/dashboard/${exhibition.id}`);
-      setIsMenuOpen(false);
-    }
+    router.push(`/dashboard/${exhibition.id}`);
+    setIsMenuOpen(false);
   };
 
   const handleChangePublishedState = (e: React.MouseEvent) => {
     e.stopPropagation();
-    if (exhibition.id) {
-      if (exhibition.isPublished) {
-        if (
-          window.confirm(
-            "Are you sure you want to move this exhibition back to drafts?",
-          )
-        ) {
-          unpublishExhibition.mutate({ id: exhibition.id });
-        }
-      } else {
-        if (
-          window.confirm("Are you sure you want to publish this exhibition?")
-        ) {
-          publishExhibition.mutate({ id: exhibition.id });
-        }
+    if (exhibition.isPublished) {
+      if (window.confirm("Are you sure you want to move this exhibition back to drafts?")) {
+        unpublishExhibition.mutate({ id: exhibition.id });
+      }
+    } else {
+      if (window.confirm("Are you sure you want to publish this exhibition?")) {
+        publishExhibition.mutate({ id: exhibition.id });
       }
-      setIsMenuOpen(false);
     }
+    setIsMenuOpen(false);
   };
 
   const handleDelete = (e: React.MouseEvent) => {
     e.stopPropagation();
-    if (
-      exhibition.id &&
-      window.confirm("Are you sure you want to delete this exhibition?")
-    ) {
+    if (window.confirm("Are you sure you want to delete this exhibition?")) {
       deleteExhibition.mutate({ id: exhibition.id });
       setIsMenuOpen(false);
     }
   };
 
-  const truncateDescription = (text: string, maxLength: number) => {
-    if (text.length <= maxLength) return text;
-    return text.slice(0, maxLength) + "...";
-  };
+  const truncateDescription = (text: string, maxLength: number) =>
+    text.length <= maxLength ? text : `${text.slice(0, maxLength)}...`;
 
   return (
     <div className="mt-8">
@@ -101,27 +71,17 @@ export default function ExhibitionCard({
         <div className="flex w-full">
           <div className="relative h-32 w-32 flex-shrink-0 overflow-hidden rounded-md bg-gray-200">
             <Image
-              src={
-                exhibition.coverImageUrl ??
-                configurations.DEFAULT_COVER_IMAGE_URL
-              }
+              src={exhibition.coverImageUrl ?? configurations.DEFAULT_COVER_IMAGE_URL}
               alt={exhibition.name ?? "Exhibition"}
               layout="fill"
               objectFit="cover"
             />
           </div>
           <div className="mt-2 flex flex-grow flex-col justify-between overflow-hidden pl-3">
-            <div>
-              <h2 className="text-dark truncate text-xl font-semibold">
-                {exhibition.name}
-              </h2>
-              <p className="mt-1 text-sm text-text-dark">
-                {truncateDescription(
-                  exhibition.description ?? "",
-                  configurations.MAX_DESCRIPTION_LENGTH,
-                )}
-              </p>
-            </div>
+            <h2 className="text-dark truncate text-xl font-semibold">{exhibition.name}</h2>
+            <p className="mt-1 text-sm text-text-dark">
+              {truncateDescription(exhibition.description ?? "", configurations.MAX_DESCRIPTION_LENGTH)}
+            </p>
           </div>
         </div>
 
@@ -133,26 +93,17 @@ export default function ExhibitionCard({
               data-testid="card-options-button"
               onClick={(e) => e.stopPropagation()}
             >
-              <Cog className="h-5 w-5" />
+              <Settings className="h-5 w-5" />
             </button>
           </DropdownMenuTrigger>
           <DropdownMenuContent align="end" className="w-36 bg-white">
-            <DropdownMenuItem
-              onClick={handleEdit}
-              className="hover:font-semibold"
-            >
+            <DropdownMenuItem onClick={handleEdit} className="hover:font-semibold">
               Edit
             </DropdownMenuItem>
-            <DropdownMenuItem
-              onClick={handleChangePublishedState}
-              className="hover:font-semibold"
-            >
+            <DropdownMenuItem onClick={handleChangePublishedState} className="hover:font-semibold">
               {exhibition.isPublished ? "Unpublish" : "Publish"}
             </DropdownMenuItem>
-            <DropdownMenuItem
-              onClick={handleDelete}
-              className="text-red-600 hover:font-semibold hover:text-red-600"
-            >
+            <DropdownMenuItem onClick={handleDelete} className="text-red-600 hover:font-semibold">
               Delete
             </DropdownMenuItem>
           </DropdownMenuContent>
diff --git a/src/app/_components/exhibition-section.tsx b/src/app/_components/exhibition-section.tsx
index 6af549e..69d12d8 100644
--- a/src/app/_components/exhibition-section.tsx
+++ b/src/app/_components/exhibition-section.tsx
@@ -33,8 +33,7 @@ const ExhibitionSection = ({
   const [currentPage, setCurrentPage] = useState(1);
 
   useEffect(() => {
-    const page = parseInt(searchParams?.get("page") ?? "1", 10);
-    setCurrentPage(page);
+    setCurrentPage(parseInt(searchParams?.get("page") ?? "1", 10));
   }, [searchParams]);
 
   const totalPages = Math.ceil(exhibitions.length / configurations.EXHIBITIONS_PER_PAGE);
@@ -42,15 +41,8 @@ const ExhibitionSection = ({
   const indexOfFirstExhibition = indexOfLastExhibition - configurations.EXHIBITIONS_PER_PAGE;
   const currentExhibitions = exhibitions.slice(indexOfFirstExhibition, indexOfLastExhibition);
 
-  const handlePageChange = (newPage: number) => {
-    router.push(`?page=${newPage}`);
-  };
 
-  const handleViewAll = () => {
-    if (viewAllPath) {
-      router.push(viewAllPath);
-    }
-  };
+  const handleViewAll = () => viewAllPath && router.push(viewAllPath);
 
   return (
     <div className="mb-10">
@@ -63,9 +55,8 @@ const ExhibitionSection = ({
         </button>
       )}
       <h1 className="text-2xl font-bold text-accent">{title}</h1>
-      
       <div className="relative">
-        <ExhibitionList exhibitions={currentExhibitions} onExhibitionClick={onExhibitionClick}/>
+        <ExhibitionList exhibitions={currentExhibitions} onExhibitionClick={onExhibitionClick} />
         {showFadeEffect && currentExhibitions.length === maxVisibleItems && (
           <div className="absolute top-0 right-0 h-full w-1/4 bg-gradient-to-l from-white to-transparent pointer-events-none"></div>
         )}
@@ -77,9 +68,7 @@ const ExhibitionSection = ({
           </div>
         )}
       </div>
-      {showPagination && (
-        <PaginationControls currentPage={currentPage} totalPages={totalPages} />
-      )}
+      {showPagination && <PaginationControls currentPage={currentPage} totalPages={totalPages} />}
     </div>
   );
 };
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 1eb15b4..f04f43c 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -7,13 +7,14 @@ import type { Exhibition } from "../_types/exhibition";
 import ExhibitionSection from "../_components/exhibition-section";
 import CreateExhibitionModal from "../_components/create-exhibition-modal";
 import MessageBanner from "../_components/message-banner";
+import useResponsiveVisibleDrafts from "~/hooks/responsive-visible-drafts";
 
 const ExhibitionPageContent = () => {
   const router = useRouter();
   const [drafts, setDrafts] = useState<Exhibition[]>([]);
   const [publishedExhibitions, setPublishedExhibitions] = useState<Exhibition[]>([]);
   const [isCreateExhibitionModalOpen, setIsCreateExhibitionModalOpen] = useState(false);
-  const [visibleDrafts, setVisibleDrafts] = useState(getInitialVisibleDrafts());
+  const visibleDrafts = useResponsiveVisibleDrafts();
 
   const { data, error, isLoading } = api.exhibition.getAll.useQuery();
 
@@ -24,35 +25,6 @@ const ExhibitionPageContent = () => {
     }
   }, [data]);
 
-  useEffect(() => {
-    const updateVisibleDrafts = () => {
-      if (window.innerWidth < 768) {
-        setVisibleDrafts(1);
-      } else if (window.innerWidth < 1200) {
-        setVisibleDrafts(2);
-      } else if (window.innerWidth < 1536) {
-        setVisibleDrafts(3);
-      } else {
-        setVisibleDrafts(4);
-      }
-    };
-
-    window.addEventListener("resize", updateVisibleDrafts);
-    updateVisibleDrafts();
-
-    return () => window.removeEventListener("resize", updateVisibleDrafts);
-  }, []);
-
-  function getInitialVisibleDrafts() {
-    if (typeof window !== "undefined") {
-      if (window.innerWidth < 768) return 1;
-      if (window.innerWidth < 1200) return 2;
-      if (window.innerWidth < 1536) return 3;
-      return 4;
-    }
-    return 4;
-  }
-
   const handleExhibitionClick = (id: number) => {
     router.push(`/dashboard/${id}`);
   };
@@ -110,4 +82,4 @@ const ExhibitionsPage = () => (
   </Suspense>
 );
 
-export default ExhibitionsPage;
+export default ExhibitionsPage;
\ No newline at end of file
diff --git a/src/hooks/responsive-visible-drafts.ts b/src/hooks/responsive-visible-drafts.ts
new file mode 100644
index 0000000..51fe8bb
--- /dev/null
+++ b/src/hooks/responsive-visible-drafts.ts
@@ -0,0 +1,35 @@
+"use client";
+
+import { useState, useEffect } from "react";
+
+const useResponsiveVisibleDrafts = () => {
+  const [visibleDrafts, setVisibleDrafts] = useState(getInitialVisibleDrafts());
+
+  useEffect(() => {
+    const updateVisibleDrafts = () => {
+      if (window.innerWidth < 768) setVisibleDrafts(1);
+      else if (window.innerWidth < 1200) setVisibleDrafts(2);
+      else if (window.innerWidth < 1536) setVisibleDrafts(3);
+      else setVisibleDrafts(4);
+    };
+
+    window.addEventListener("resize", updateVisibleDrafts);
+    updateVisibleDrafts();
+
+    return () => window.removeEventListener("resize", updateVisibleDrafts);
+  }, []);
+
+  function getInitialVisibleDrafts() {
+    if (typeof window !== "undefined") {
+      if (window.innerWidth < 768) return 1;
+      if (window.innerWidth < 1200) return 2;
+      if (window.innerWidth < 1536) return 3;
+      return 4;
+    }
+    return 4;
+  }
+
+  return visibleDrafts;
+};
+
+export default useResponsiveVisibleDrafts;
-- 
GitLab


From aa9ad4821ef89c6ec956dac979e7a4b9f167bd62 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Tue, 5 Nov 2024 17:16:39 +0200
Subject: [PATCH 3/8] #56 add test for creating exhibtion

---
 cypress/e2e/dashboard.cy.ts                   | 33 +++++++++++++++----
 .../exhibition-dashboard-cards.tsx            |  7 ++--
 src/app/dashboard/drafts/page.tsx             |  2 +-
 3 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/cypress/e2e/dashboard.cy.ts b/cypress/e2e/dashboard.cy.ts
index 8f52325..f2ca12f 100644
--- a/cypress/e2e/dashboard.cy.ts
+++ b/cypress/e2e/dashboard.cy.ts
@@ -1,26 +1,47 @@
 describe('Dashboard Page', () => {
+  const selectors = {
+    dashboardHeading: 'h1:contains("Dashboard")',
+    newExhibitionButton: 'button:contains("New Exhibition")',
+    createButton: 'button:contains("Create")',
+    viewAllButton: '[data-testid="view-all-button"]',
+    cardOptionsButton: '[data-testid="card-options-button"]',
+    editOption: 'Edit',
+    exhibitionTitleInput: 'input[placeholder="Enter exhibition title"]',
+    exhibitionDescriptionInput: 'textarea[placeholder="Enter exhibition description"]',
+    exhibitionCard: (title: string) => `[data-testid="exhibition-card"]:contains("${title}")`,
+  };
+
   beforeEach(() => {
     cy.visit('/dashboard');
   });
 
   it('should display the Dashboard heading', () => {
-    cy.contains('Dashboard').should('be.visible');
+    cy.get(selectors.dashboardHeading).should('be.visible');
   });
 
   it('should open the Create Exhibition Modal', () => {
-    cy.get('button').contains('New Exhibition').click();
-    cy.get('Button').contains('Create').should('be.visible');
+    cy.get(selectors.newExhibitionButton).click();
+    cy.get(selectors.createButton).should('be.visible');
   });
 
   it('should navigate to the drafts page by clicking the arrow', () => {
-    cy.get('[data-testid="view-all-button"]').click();
+    cy.get(selectors.viewAllButton).click();
     cy.url().should('include', '/dashboard/drafts');
   });
 
   it('should click the gear icon on a published exhibition card', () => {
-    cy.get('[data-testid="card-options-button"]').first().click();
-    cy.contains('Edit').should('be.visible');
+    cy.get(selectors.cardOptionsButton).first().click();
+    cy.contains(selectors.editOption).should('be.visible');
     cy.log('Verified that the gear icon is clickable');
   });
 
+  it('should create a new exhibition and verify its display on the dashboard', () => {
+    const exhibitionTitle = 'New Test Exhibition';
+    const exhibitionDescription = 'This is a description for the new exhibition.';
+    cy.get(selectors.newExhibitionButton).click();
+    cy.get(selectors.exhibitionTitleInput).type(exhibitionTitle);
+    cy.get(selectors.exhibitionDescriptionInput).type(exhibitionDescription);
+    cy.get(selectors.createButton).click();
+    cy.get(selectors.exhibitionCard(exhibitionTitle)).should('be.visible');
+  });
 });
\ No newline at end of file
diff --git a/src/app/_components/exhibition-dashboard-cards.tsx b/src/app/_components/exhibition-dashboard-cards.tsx
index 40652f8..acc01dd 100644
--- a/src/app/_components/exhibition-dashboard-cards.tsx
+++ b/src/app/_components/exhibition-dashboard-cards.tsx
@@ -22,7 +22,6 @@ interface ExhibitionCardProps {
   exhibition: Exhibition;
   onClick: (id: number) => void;
 }
-
 export default function ExhibitionCard({ exhibition, onClick }: ExhibitionCardProps) {
   const [isMenuOpen, setIsMenuOpen] = useState(false);
   const router = useRouter();
@@ -65,6 +64,7 @@ export default function ExhibitionCard({ exhibition, onClick }: ExhibitionCardPr
   return (
     <div className="mt-8">
       <div
+        data-testid="exhibition-card"
         className="relative flex h-48 w-full cursor-pointer overflow-hidden rounded-lg bg-background_dark p-4 md:w-[320px]"
         onClick={() => onClick(exhibition.id)}
       >
@@ -77,8 +77,8 @@ export default function ExhibitionCard({ exhibition, onClick }: ExhibitionCardPr
               objectFit="cover"
             />
           </div>
-          <div className="mt-2 flex flex-grow flex-col justify-between overflow-hidden pl-3">
-            <h2 className="text-dark truncate text-xl font-semibold">{exhibition.name}</h2>
+          <div className="flex flex-grow flex-col justify-start pl-3 pr-2">
+            <h2 className="text-dark truncate text-l font-semibold pt-4">{exhibition.name}</h2>
             <p className="mt-1 text-sm text-text-dark">
               {truncateDescription(exhibition.description ?? "", configurations.MAX_DESCRIPTION_LENGTH)}
             </p>
@@ -113,6 +113,7 @@ export default function ExhibitionCard({ exhibition, onClick }: ExhibitionCardPr
   );
 }
 
+
 export function ExhibitionList({
   exhibitions,
   onExhibitionClick,
diff --git a/src/app/dashboard/drafts/page.tsx b/src/app/dashboard/drafts/page.tsx
index 74883dc..af68381 100644
--- a/src/app/dashboard/drafts/page.tsx
+++ b/src/app/dashboard/drafts/page.tsx
@@ -33,7 +33,7 @@ const DraftsPage = () => {
       <div className="text-text-dark min-h-screen pl-32 pr-12 relative">
         <button
           onClick={handleBackToDashboard}
-          className="absolute text-4xl text-black rounded-md hover:text-gray-500 transition duration-300"
+          className="absolute text-4xl text-black rounded-md hover:text-gray-500 transition duration-300 mt-5"
           style={{ top: '-100px', left: '16px' }}
         >
           â‌¬
-- 
GitLab


From 0f66b46a33d5fed5877d9778a20cee07a187ecb2 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Wed, 6 Nov 2024 12:55:04 +0200
Subject: [PATCH 4/8] #56 fixing columns on laptop

---
 src/app/_components/exhibition-dashboard-cards.tsx | 2 +-
 src/app/_components/exhibition-visitor-cards.tsx   | 6 ++----
 src/hooks/responsive-visible-drafts.ts             | 9 +++++----
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/app/_components/exhibition-dashboard-cards.tsx b/src/app/_components/exhibition-dashboard-cards.tsx
index acc01dd..c484bf1 100644
--- a/src/app/_components/exhibition-dashboard-cards.tsx
+++ b/src/app/_components/exhibition-dashboard-cards.tsx
@@ -122,7 +122,7 @@ export function ExhibitionList({
   onExhibitionClick: (id: number) => void;
 }) {
   return (
-    <div className="l:grid-cols-2 grid grid-cols-1 gap-4 xl:grid-cols-3 2xl:grid-cols-4">
+    <div className="lg:grid-cols-2 grid grid-cols-1 gap-4 xl:grid-cols-3 2xl:grid-cols-4">
       {exhibitions.map((exhibition) => (
         <ExhibitionCard
           key={exhibition.id}
diff --git a/src/app/_components/exhibition-visitor-cards.tsx b/src/app/_components/exhibition-visitor-cards.tsx
index c9df736..c0e7dc9 100644
--- a/src/app/_components/exhibition-visitor-cards.tsx
+++ b/src/app/_components/exhibition-visitor-cards.tsx
@@ -16,7 +16,7 @@ interface ExhibitionListProps {
 
 const ExhibitionList: React.FC<ExhibitionListProps> = ({ exhibitions, onExhibitionClick }: ExhibitionListProps) => {
   return (
-    <div className="grid grid-cols-1 l:grid-cols-2 xl:grid-cols-2 2xl:grid-cols-3 gap-20">
+    <div className="grid grid-cols-1 gap-20 lg:grid-cols-2 2xl:grid-cols-3">
       {exhibitions.map((exhibition) => (
         <ExhibitionCard
           key={exhibition.id}
@@ -71,6 +71,4 @@ const ExhibitionCard: React.FC<ExhibitionCardProps> = ({ exhibition, onClick })
   );
 };
 
-
-
-export { ExhibitionList, ExhibitionCard };
\ No newline at end of file
+export { ExhibitionList, ExhibitionCard };
diff --git a/src/hooks/responsive-visible-drafts.ts b/src/hooks/responsive-visible-drafts.ts
index 51fe8bb..9cd1779 100644
--- a/src/hooks/responsive-visible-drafts.ts
+++ b/src/hooks/responsive-visible-drafts.ts
@@ -7,8 +7,8 @@ const useResponsiveVisibleDrafts = () => {
 
   useEffect(() => {
     const updateVisibleDrafts = () => {
-      if (window.innerWidth < 768) setVisibleDrafts(1);
-      else if (window.innerWidth < 1200) setVisibleDrafts(2);
+      if (window.innerWidth < 1024) setVisibleDrafts(1);
+      else if (window.innerWidth < 1280) setVisibleDrafts(2);
       else if (window.innerWidth < 1536) setVisibleDrafts(3);
       else setVisibleDrafts(4);
     };
@@ -21,8 +21,8 @@ const useResponsiveVisibleDrafts = () => {
 
   function getInitialVisibleDrafts() {
     if (typeof window !== "undefined") {
-      if (window.innerWidth < 768) return 1;
-      if (window.innerWidth < 1200) return 2;
+      if (window.innerWidth < 1024) return 1;
+      if (window.innerWidth < 1280) return 2;
       if (window.innerWidth < 1536) return 3;
       return 4;
     }
@@ -33,3 +33,4 @@ const useResponsiveVisibleDrafts = () => {
 };
 
 export default useResponsiveVisibleDrafts;
+
-- 
GitLab


From 2897140bde356947a22f9476e3d8984ad2e697cc Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Mon, 11 Nov 2024 17:32:15 +0200
Subject: [PATCH 5/8] #56 Made dashboard mobile friendly

---
 components.json                               |  2 +-
 package.json                                  |  3 +-
 pnpm-lock.yaml                                | 75 -------------------
 .../exhibition-dashboard-cards.tsx            |  3 +-
 src/app/_components/exhibition-section.tsx    | 10 +--
 src/app/_components/header.tsx                |  4 +-
 src/app/dashboard/drafts/page.tsx             | 23 +++---
 src/app/dashboard/page.tsx                    |  2 +-
 src/components/slide-in-menu.tsx              |  9 ++-
 src/hooks/responsive-visible-drafts.ts        |  8 +-
 10 files changed, 32 insertions(+), 107 deletions(-)

diff --git a/components.json b/components.json
index d272e24..299c982 100644
--- a/components.json
+++ b/components.json
@@ -6,7 +6,7 @@
   "tailwind": {
     "config": "tailwind.config.ts",
     "css": "src/styles/globals.css",
-    "baseColor": "neutral",
+    "baseColor": "slate",
     "cssVariables": true,
     "prefix": ""
   },
diff --git a/package.json b/package.json
index 7c70d25..d252bff 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,6 @@
     "@radix-ui/react-dropdown-menu": "^2.1.2",
     "@radix-ui/react-icons": "^1.3.1",
     "@radix-ui/react-label": "^2.1.0",
-    "@radix-ui/react-navigation-menu": "^1.2.1",
     "@radix-ui/react-slot": "^1.1.0",
     "@t3-oss/env-nextjs": "^0.10.1",
     "@tanstack/react-query": "^5.50.0",
@@ -87,4 +86,4 @@
     "initVersion": "7.37.0"
   },
   "packageManager": "pnpm@9.11.0"
-}
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 45a00b3..d2cab9d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -44,9 +44,6 @@ importers:
       '@radix-ui/react-label':
         specifier: ^2.1.0
         version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@radix-ui/react-navigation-menu':
-        specifier: ^1.2.1
-        version: 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@radix-ui/react-slot':
         specifier: ^1.1.0
         version: 1.1.0(@types/react@18.3.12)(react@18.3.1)
@@ -1869,19 +1866,6 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-navigation-menu@1.2.1':
-    resolution: {integrity: sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q==}
-    peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
-      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
-      react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
-    peerDependenciesMeta:
-      '@types/react':
-        optional: true
-      '@types/react-dom':
-        optional: true
-
   '@radix-ui/react-popper@1.2.0':
     resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==}
     peerDependencies:
@@ -1992,15 +1976,6 @@ packages:
       '@types/react':
         optional: true
 
-  '@radix-ui/react-use-previous@1.1.0':
-    resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==}
-    peerDependencies:
-      '@types/react': '*'
-      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
-    peerDependenciesMeta:
-      '@types/react':
-        optional: true
-
   '@radix-ui/react-use-rect@1.1.0':
     resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
     peerDependencies:
@@ -2019,19 +1994,6 @@ packages:
       '@types/react':
         optional: true
 
-  '@radix-ui/react-visually-hidden@1.1.0':
-    resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==}
-    peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
-      react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
-      react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
-    peerDependenciesMeta:
-      '@types/react':
-        optional: true
-      '@types/react-dom':
-        optional: true
-
   '@radix-ui/rect@1.1.0':
     resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
 
@@ -8183,28 +8145,6 @@ snapshots:
       '@types/react': 18.3.12
       '@types/react-dom': 18.3.1
 
-  '@radix-ui/react-navigation-menu@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
-    dependencies:
-      '@radix-ui/primitive': 1.1.0
-      '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.12)(react@18.3.1)
-      '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      react: 18.3.1
-      react-dom: 18.3.1(react@18.3.1)
-    optionalDependencies:
-      '@types/react': 18.3.12
-      '@types/react-dom': 18.3.1
-
   '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -8302,12 +8242,6 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.12
 
-  '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.12)(react@18.3.1)':
-    dependencies:
-      react: 18.3.1
-    optionalDependencies:
-      '@types/react': 18.3.12
-
   '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.12)(react@18.3.1)':
     dependencies:
       '@radix-ui/rect': 1.1.0
@@ -8322,15 +8256,6 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.12
 
-  '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
-    dependencies:
-      '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      react: 18.3.1
-      react-dom: 18.3.1(react@18.3.1)
-    optionalDependencies:
-      '@types/react': 18.3.12
-      '@types/react-dom': 18.3.1
-
   '@radix-ui/rect@1.1.0': {}
 
   '@remix-run/router@1.5.0': {}
diff --git a/src/app/_components/exhibition-dashboard-cards.tsx b/src/app/_components/exhibition-dashboard-cards.tsx
index d74af31..2493ad0 100644
--- a/src/app/_components/exhibition-dashboard-cards.tsx
+++ b/src/app/_components/exhibition-dashboard-cards.tsx
@@ -140,7 +140,7 @@ export function ExhibitionList({
   onExhibitionClick: (id: number) => void;
 }) {
   return (
-    <div className="lg:grid-cols-2 grid grid-cols-1 gap-4 xl:grid-cols-3 2xl:grid-cols-4">
+    <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-8">
       {exhibitions.map((exhibition) => (
         <ExhibitionCard
           key={exhibition.id}
@@ -149,5 +149,6 @@ export function ExhibitionList({
         />
       ))}
     </div>
+
   );
 }
\ No newline at end of file
diff --git a/src/app/_components/exhibition-section.tsx b/src/app/_components/exhibition-section.tsx
index 597dc92..2448d53 100644
--- a/src/app/_components/exhibition-section.tsx
+++ b/src/app/_components/exhibition-section.tsx
@@ -41,7 +41,6 @@ const ExhibitionSection = ({
   const indexOfFirstExhibition = indexOfLastExhibition - configurations.EXHIBITIONS_PER_PAGE;
   const currentExhibitions = exhibitions.slice(indexOfFirstExhibition, indexOfLastExhibition);
 
-
   const handleViewAll = () => viewAllPath && router.push(viewAllPath);
 
   return (
@@ -55,16 +54,16 @@ const ExhibitionSection = ({
         </button>
       )}
       <h1 className="text-2xl font-bold text-neutral">{title}</h1>
-      
+
       <div className="relative">
         <ExhibitionList exhibitions={currentExhibitions} onExhibitionClick={onExhibitionClick} />
         {showFadeEffect && currentExhibitions.length === maxVisibleItems && (
           <div className="absolute top-0 right-0 h-full w-1/4 bg-gradient-to-l from-white to-transparent pointer-events-none"></div>
         )}
         {viewAllPath && (
-          <div className="absolute top-1/2 right-8 transform -translate-y-1/2">
-            <button onClick={handleViewAll} className="text-black px-4 py-2 flex items-center group" data-testid="view-all-button">
-              <span className="ml-2 text-4xl">م€‰</span>
+          <div className="absolute top-1/2 right-0 transform -translate-y-1/2">
+            <button onClick={handleViewAll} className="text-black flex items-center group" data-testid="view-all-button">
+              <span className="text-4xl">م€‰</span>
             </button>
           </div>
         )}
@@ -75,3 +74,4 @@ const ExhibitionSection = ({
 };
 
 export default ExhibitionSection;
+
diff --git a/src/app/_components/header.tsx b/src/app/_components/header.tsx
index 6436147..dc11609 100644
--- a/src/app/_components/header.tsx
+++ b/src/app/_components/header.tsx
@@ -64,9 +64,7 @@ const Header = () => {
             Archive
           </span>
         </Link>
-        <button className="bg-primary-dark text-white px-4 py-2 rounded hover:bg-primary-dark_hover block sm:hidden mt-2">
-          Log In
-        </button>
+    
       </nav>
     </>
   );
diff --git a/src/app/dashboard/drafts/page.tsx b/src/app/dashboard/drafts/page.tsx
index 1c1234e..eb11c3b 100644
--- a/src/app/dashboard/drafts/page.tsx
+++ b/src/app/dashboard/drafts/page.tsx
@@ -30,20 +30,21 @@ const DraftsPage = () => {
 
   return (
     <Suspense fallback={<div>Loading...</div>}>
-      <div className="text-text-dark min-h-screen pl-32 pr-12 relative">
-        <button
-          onClick={handleBackToDashboard}
-          className="absolute text-4xl text-black rounded-md hover:text-gray-500 transition duration-300 mt-5"
-          style={{ top: '-100px', left: '16px' }}
-        >
-          â‌¬
-        </button>
-        <h1 className="text-3xl font-bold mb-4 text-accent mt-12">Drafts</h1>
+      <div className="text-text-dark min-h-screen px-4 sm:px-12 relative">
+        <div className="flex items-center mt-12">
+          <button
+            onClick={handleBackToDashboard}
+            className="text-4xl text-black rounded-md hover:text-gray-500 transition duration-300 mr-4 mb-10"
+          >
+            â‌¬
+          </button>
+          <h1 className="text-3xl font-bold text-dark mb-10">Drafts</h1>
+        </div>
         {isCreateExhibitionModalOpen && (
           <CreateExhibitionModal onClose={() => setIsCreateExhibitionModalOpen(false)} />
         )}
         <ExhibitionSection
-          title="Drafts"
+          title=""
           exhibitions={drafts}
           onExhibitionClick={handleExhibitionClick}
           showPagination
@@ -54,4 +55,4 @@ const DraftsPage = () => {
   );
 };
 
-export default DraftsPage;
+export default DraftsPage;
\ No newline at end of file
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 1e1389d..17f2ece 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -73,7 +73,7 @@ const ExhibitionPageContent = () => {
 
 const ExhibitionsPage = () => (
   <Suspense fallback={<div>Loading search parameters...</div>}>
-    <div className="text-text-dark min-h-screen pl-32 pr-12 py-8">
+    <div className="text-text-dark min-h-screen px-4 sm:px-12 py-8">
       <ExhibitionPageContent />
     </div>
   </Suspense>
diff --git a/src/components/slide-in-menu.tsx b/src/components/slide-in-menu.tsx
index 32725a0..7248c1c 100644
--- a/src/components/slide-in-menu.tsx
+++ b/src/components/slide-in-menu.tsx
@@ -38,7 +38,7 @@ export default function Component() {
     <>
       <Button
         variant="default"
-        className="sticky top-8 right-4 z-50 text-2xl"
+        className="sticky top-8 right-4 z-50 text-2xl text-gray-600"
         onClick={() => setIsOpen(true)}>
           âک°        
         <span className="sr-only">Open menu</span>
@@ -94,19 +94,19 @@ export default function Component() {
           </Link>
         </div>
 
-        <div className="mt-8 absolute bottom-6 w-full">
+        <div className="mt-8 w-full">
           <div className="flex space-x-4">
             <h3 className="text-lg font-semibold">Language:</h3>
             <div className="space-x-2">
               <button
-                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'ENG' ? 'underline' : ''}`}
+                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'ENG' ? 'font-bold' : ''}`}
                 onClick={() => setSelectedLanguage('ENG')}
               >
                 ENG
               </button>
               <span className="text-text-dark">|</span>
               <button
-                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'EST' ? 'underline' : ''}`}
+                className={`hover:text-primary-dark text-text-dark text-lg ${selectedLanguage === 'EST' ? 'font-bold' : ''}`}
                 onClick={() => setSelectedLanguage('EST')}
               >
                 EST
@@ -118,3 +118,4 @@ export default function Component() {
     </>
   )
 }
+
diff --git a/src/hooks/responsive-visible-drafts.ts b/src/hooks/responsive-visible-drafts.ts
index 9cd1779..dd3847d 100644
--- a/src/hooks/responsive-visible-drafts.ts
+++ b/src/hooks/responsive-visible-drafts.ts
@@ -7,9 +7,9 @@ const useResponsiveVisibleDrafts = () => {
 
   useEffect(() => {
     const updateVisibleDrafts = () => {
-      if (window.innerWidth < 1024) setVisibleDrafts(1);
+      if (window.innerWidth < 768) setVisibleDrafts(1);
       else if (window.innerWidth < 1280) setVisibleDrafts(2);
-      else if (window.innerWidth < 1536) setVisibleDrafts(3);
+      else if (window.innerWidth < 1280) setVisibleDrafts(3);
       else setVisibleDrafts(4);
     };
 
@@ -21,9 +21,9 @@ const useResponsiveVisibleDrafts = () => {
 
   function getInitialVisibleDrafts() {
     if (typeof window !== "undefined") {
-      if (window.innerWidth < 1024) return 1;
+      if (window.innerWidth < 768) return 1; 
       if (window.innerWidth < 1280) return 2;
-      if (window.innerWidth < 1536) return 3;
+      if (window.innerWidth < 1280) return 3;
       return 4;
     }
     return 4;
-- 
GitLab


From 2425cfbab146f70d42e02c12682e63af0621ade9 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Mon, 11 Nov 2024 17:42:05 +0200
Subject: [PATCH 6/8] #56 Fixed the fade effect

---
 .../_components/exhibition-dashboard-cards.tsx |  2 +-
 src/app/_components/exhibition-section.tsx     |  6 ++++--
 src/hooks/responsive-visible-drafts.ts         | 18 ++++++++++--------
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/app/_components/exhibition-dashboard-cards.tsx b/src/app/_components/exhibition-dashboard-cards.tsx
index 2493ad0..286da0b 100644
--- a/src/app/_components/exhibition-dashboard-cards.tsx
+++ b/src/app/_components/exhibition-dashboard-cards.tsx
@@ -140,7 +140,7 @@ export function ExhibitionList({
   onExhibitionClick: (id: number) => void;
 }) {
   return (
-    <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-8">
+    <div className="grid grid-cols-1 md:grid-cols-2  lg:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-4 gap-8">
       {exhibitions.map((exhibition) => (
         <ExhibitionCard
           key={exhibition.id}
diff --git a/src/app/_components/exhibition-section.tsx b/src/app/_components/exhibition-section.tsx
index 2448d53..7948d22 100644
--- a/src/app/_components/exhibition-section.tsx
+++ b/src/app/_components/exhibition-section.tsx
@@ -58,12 +58,14 @@ const ExhibitionSection = ({
       <div className="relative">
         <ExhibitionList exhibitions={currentExhibitions} onExhibitionClick={onExhibitionClick} />
         {showFadeEffect && currentExhibitions.length === maxVisibleItems && (
-          <div className="absolute top-0 right-0 h-full w-1/4 bg-gradient-to-l from-white to-transparent pointer-events-none"></div>
+          <div className="absolute top-0 right-[-50px] h-full w-1/4 bg-gradient-to-l from-white to-transparent pointer-events-none"></div>
         )}
+
+
         {viewAllPath && (
           <div className="absolute top-1/2 right-0 transform -translate-y-1/2">
             <button onClick={handleViewAll} className="text-black flex items-center group" data-testid="view-all-button">
-              <span className="text-4xl">م€‰</span>
+              <span className="text-4xl"> م€‰</span>
             </button>
           </div>
         )}
diff --git a/src/hooks/responsive-visible-drafts.ts b/src/hooks/responsive-visible-drafts.ts
index dd3847d..dd15007 100644
--- a/src/hooks/responsive-visible-drafts.ts
+++ b/src/hooks/responsive-visible-drafts.ts
@@ -7,10 +7,11 @@ const useResponsiveVisibleDrafts = () => {
 
   useEffect(() => {
     const updateVisibleDrafts = () => {
-      if (window.innerWidth < 768) setVisibleDrafts(1);
-      else if (window.innerWidth < 1280) setVisibleDrafts(2);
-      else if (window.innerWidth < 1280) setVisibleDrafts(3);
-      else setVisibleDrafts(4);
+      if (window.innerWidth < 768) setVisibleDrafts(1); // sm: 1 column
+      else if (window.innerWidth < 1024) setVisibleDrafts(2); // md: 2 columns
+      else if (window.innerWidth < 1280) setVisibleDrafts(3); // lg: 3 columns
+      else if (window.innerWidth < 1536) setVisibleDrafts(3); // xl: 3 columns
+      else setVisibleDrafts(4); // 2xl: 4 columns
     };
 
     window.addEventListener("resize", updateVisibleDrafts);
@@ -21,10 +22,11 @@ const useResponsiveVisibleDrafts = () => {
 
   function getInitialVisibleDrafts() {
     if (typeof window !== "undefined") {
-      if (window.innerWidth < 768) return 1; 
-      if (window.innerWidth < 1280) return 2;
-      if (window.innerWidth < 1280) return 3;
-      return 4;
+      if (window.innerWidth < 768) return 1; // sm: 1 column
+      if (window.innerWidth < 1024) return 2; // md: 2 columns
+      if (window.innerWidth < 1280) return 3; // lg: 3 columns
+      if (window.innerWidth < 1536) return 3; // xl: 3 columns
+      return 4; // 2xl: 4 columns
     }
     return 4;
   }
-- 
GitLab


From ccaf52a340d90fbec7c2292c5f3f7c27ef49953d Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Mon, 11 Nov 2024 17:44:49 +0200
Subject: [PATCH 7/8] #56 fix wiggly header

---
 src/app/_components/header.tsx | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/app/_components/header.tsx b/src/app/_components/header.tsx
index dc11609..70b37e5 100644
--- a/src/app/_components/header.tsx
+++ b/src/app/_components/header.tsx
@@ -50,22 +50,26 @@ const Header = () => {
 
       <nav className={`w-full bg-background text-text-dark overflow-hidden ${isMenuOpen ? 'block' : 'hidden'} mt-4 sm:flex justify-center items-center space-x-0 sm:space-x-32`}>
         <Link href="/">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
+          <span className="relative cursor-pointer text-text-dark text-lg block sm:inline-block group">
             All exhibitions
+            <span className="absolute left-0 bottom-0 w-full h-[2px] bg-[#2C5696] scale-x-0 transition-transform duration-300 ease-in-out group-hover:scale-x-100"></span>
           </span>
         </Link>
         <Link href="/dashboard">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
+          <span className="relative cursor-pointer text-text-dark text-lg block sm:inline-block group">
             Dashboard
+            <span className="absolute left-0 bottom-0 w-full h-[2px] bg-[#2C5696] scale-x-0 transition-transform duration-300 ease-in-out group-hover:scale-x-100"></span>
           </span>
         </Link>
         <Link href="/archive">
-          <span className="hover:text-primary-dark cursor-pointer text-text-dark text-lg hover:border-b-2 hover:border-[#2C5696] block sm:inline-block">
+          <span className="relative cursor-pointer text-text-dark text-lg block sm:inline-block group">
             Archive
+            <span className="absolute left-0 bottom-0 w-full h-[2px] bg-[#2C5696] scale-x-0 transition-transform duration-300 ease-in-out group-hover:scale-x-100"></span>
           </span>
         </Link>
-    
       </nav>
+
+
     </>
   );
 };
-- 
GitLab


From c3640f0b970579ec039d59121f48759b7cd774d5 Mon Sep 17 00:00:00 2001
From: Eliisabet <eliisabet.kaasik@gmail.com>
Date: Mon, 11 Nov 2024 18:19:34 +0200
Subject: [PATCH 8/8] #56 now shows "new exhibition" even if the database is
 empty

---
 src/app/dashboard/page.tsx | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 17f2ece..aa74d8b 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -36,6 +36,13 @@ const ExhibitionPageContent = () => {
       <h1 className="text-3xl font-bold mb-2 text-neutral">Dashboard</h1>
       <h2 className="text-xl mb-6 text-gray-500">Manage Exhibitions</h2>
 
+      <button
+        onClick={() => setIsCreateExhibitionModalOpen(true)}
+        className="bg-primary-dark text-text-light px-4 py-2 rounded-md hover:bg-primary-dark_hover transition duration-300 mb-4"
+      >
+        New Exhibition
+      </button>
+
       {isCreateExhibitionModalOpen && (
         <CreateExhibitionModal onClose={() => setIsCreateExhibitionModalOpen(false)} />
       )}
-- 
GitLab