Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add responsiveness to Navbar and Chatbot #80

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions client/app/components/Cards/ElectionInfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,30 @@ const ElectionInfoCard = ({ counts, filterStatus, setFilterStatus }: any) => {
{ name: "Active", image: TbCalendarDot, count: counts.active },
{ name: "Ended", image: TbCalendarOff, count: counts.ended },
];

return (
<div className="relative flex border border-gray-300 w-full flex-col rounded-xl bg-white p-4 text-gray-700 bg-clip-border shadow-xl shadow-blue-gray-900/5">
<div className="p-4">
<h5 className="block font-sans text-xl antialiased font-semibold leading-snug tracking-normal text-blue-gray-900">
<div className="relative flex border border-gray-300 w-full max-w-sm sm:max-w-full flex-col rounded-xl bg-white p-2 sm:p-4 text-gray-700 bg-clip-border shadow-xl shadow-blue-gray-900/5">
<div className="p-2 sm:p-4">
<h5 className="block font-sans text-lg sm:text-xl antialiased font-semibold leading-snug tracking-normal text-blue-gray-900">
Election List
</h5>
</div>
<nav className="flex flex-col gap-1 p-2 font-sans text-base font-normal text-blue-gray-700">
<nav className="flex flex-col gap-1 p-1 sm:p-2 font-sans text-sm sm:text-base font-normal text-blue-gray-700 overflow-y-auto">
{ElectionInfoImage.map((electionPart, key) => {
return (
<button
key={key}
onClick={() => setFilterStatus(key)}
className={`flex relative items-center w-full p-3 leading-tight transition-all rounded-lg outline-none text-start hover:bg-blue-gray-50 hover:bg-opacity-80 hover:text-blue-gray-900 focus:bg-blue-gray-50 focus:bg-opacity-80 focus:text-blue-gray-900 active:bg-blue-gray-50 active:bg-opacity-80 active:text-blue-gray-900 ${
key === filterStatus && " bg-slate-100"
className={`flex relative items-center w-full p-2 sm:p-3 leading-tight transition-all rounded-lg outline-none text-start hover:bg-blue-gray-50 hover:bg-opacity-80 hover:text-blue-gray-900 focus:bg-blue-gray-50 focus:bg-opacity-80 focus:text-blue-gray-900 active:bg-blue-gray-50 active:bg-opacity-80 active:text-blue-gray-900 ${
key === filterStatus && "bg-slate-100"
}`}
>
<div className="grid mr-4 place-items-center">
<electionPart.image size={20} />
<div className="grid mr-2 sm:mr-4 place-items-center">
<electionPart.image size={18} />
</div>
{electionPart.name}
<div className="absolute right-2 px-2 font-sans text-sm font-semibold uppercase rounded-full whitespace-nowrap text-blue-gray-900">
<span className="">{electionPart.count}</span>
<div className="absolute right-2 px-1 sm:px-2 font-sans text-xs sm:text-sm font-semibold uppercase rounded-full whitespace-nowrap text-blue-gray-900">
<span>{electionPart.count}</span>
</div>
</button>
);
Expand All @@ -45,4 +46,4 @@ const ElectionInfoCard = ({ counts, filterStatus, setFilterStatus }: any) => {
);
};

export default ElectionInfoCard;
export default ElectionInfoCard;
36 changes: 19 additions & 17 deletions client/app/components/ChatBot/ChatBot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React, { useState, useRef, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ArrowUpIcon, ChatBubbleLeftRightIcon } from "@heroicons/react/24/solid";
import { XMarkIcon } from "@heroicons/react/24/outline"; // Corrected the import for XMarkIcon

interface Message {
content: string;
Expand Down Expand Up @@ -49,7 +50,6 @@ const ChatBot: React.FC = () => {
setMessages((prevMessages) => [...prevMessages, reply]);
} catch (error) {
console.error("Error:", error);
// Add error message in chatbot here
}
};

Expand All @@ -72,12 +72,19 @@ const ChatBot: React.FC = () => {
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 20 }}
transition={{ duration: 0.2 }}
className="absolute bottom-16 right-0 w-96 h-[32rem] bg-white rounded-lg shadow-xl overflow-hidden flex flex-col"
className="absolute bottom-16 right-0 w-[280px] xs:w-[320px] sm:w-[350px] md:w-[380px] h-[450px] bg-white rounded-lg shadow-xl overflow-hidden flex flex-col"
>
<div className="bg-blue-600 text-white p-4 text-center font-semibold">
Agora Chatbot
<div className="bg-blue-600 text-white p-3 flex items-center justify-between">
<h3 className="font-semibold">Agora Chatbot</h3>
<button
onClick={() => setIsOpen(false)} // Close chatbot on click
className="text-white focus:outline-none"
>
<XMarkIcon className="w-6 h-6" />
</button>
</div>
<div className="flex-grow overflow-auto p-4 space-y-4">

<div className="flex-grow overflow-auto p-3 space-y-3">
{messages.map((msg, index) => (
<motion.div
key={index}
Expand All @@ -87,28 +94,23 @@ const ChatBot: React.FC = () => {
className={`flex ${msg.role === "assistant" ? "justify-start" : "justify-end"}`}
>
<div
className={`max-w-[80%] p-3 rounded-lg ${
msg.role === "assistant"
? "bg-gray-200 text-gray-800"
: "bg-blue-600 text-white"
}`}
className={`max-w-[85%] p-2.5 rounded-lg text-sm ${msg.role === "assistant" ? "bg-gray-200 text-gray-800" : "bg-blue-600 text-white"}`}
>
{msg.content}
</div>
</motion.div>
))}
<div ref={messageEndRef} />
</div>
<form onSubmit={handleSubmit} className="p-4 bg-gray-100">
<div className="flex items-center bg-white rounded-full overflow-hidden shadow">

<form onSubmit={handleSubmit} className="p-3 bg-gray-100">
<div className="flex items-center gap-2">
<input
type="text"
value={inputMessage}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setInputMessage(e.target.value)
}
onChange={(e) => setInputMessage(e.target.value)}
placeholder="Type your message..."
className="flex-grow px-4 py-2 focus:outline-none"
className="flex-grow px-3 py-2 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
/>
<button type="submit" className="bg-blue-600 text-white p-2 rounded-full">
<ArrowUpIcon className="w-5 h-5" />
Expand All @@ -123,4 +125,4 @@ const ChatBot: React.FC = () => {
);
};

export default ChatBot;
export default ChatBot;
177 changes: 124 additions & 53 deletions client/app/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"use client";

import React from "react";
import React, { useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { motion } from "framer-motion";
import { motion, AnimatePresence } from "framer-motion";
import {
PlusCircleIcon,
UserIcon,
HomeIcon,
XMarkIcon,
Bars3Icon,
} from "@heroicons/react/24/outline";
import Web3Connect from "../Helper/Web3Connect";
import Image from "next/image";
Expand All @@ -20,61 +22,130 @@ const menuItems = [

const Header = () => {
const pathname = usePathname();
const [isSidebarOpen, setIsSidebarOpen] = useState(false);

const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);

return (
<motion.header
className="bg-white border-b border-gray-200 fixed w-full z-30 shadow-sm"
initial={{ y: -100 }}
animate={{ y: 0 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<Link href="/" className="flex-shrink-0 flex items-center">
<Image
width={32}
height={32}
className="h-8 w-auto"
src="/aossie.png"
alt="Agora Blockchain"
/>
<h1 className="ml-3 text-xl font-bold text-gray-800 hidden sm:block">
Agora Blockchain
</h1>
</Link>
<>
<motion.header
className="bg-white border-b border-gray-200 fixed w-full z-30 shadow-sm"
initial={{ y: -100 }}
animate={{ y: 0 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<Link href="/" className="flex-shrink-0 flex items-center">
<Image
width={32}
height={32}
className="h-8 w-auto"
src="/aossie.png"
alt="Agora Blockchain"
/>
<h1 className="ml-3 text-xl font-bold text-gray-800 hidden sm:block">
Agora Blockchain
</h1>
</Link>

<nav className="flex items-center space-x-4">
{menuItems.map((item) => (
<Link key={item.name} href={item.href} className="relative">
<motion.button
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md ${
pathname === item.href
? "text-indigo-600"
: "text-gray-700 hover:text-indigo-600"
} bg-white hover:bg-gray-50`}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<item.icon className="h-5 w-5 mr-2" aria-hidden="true" />
<span className="hidden sm:inline">{item.name}</span>
</motion.button>
{pathname === item.href && (
<motion.div
className="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
layoutId="underline"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
/>
)}
</Link>
))}
<Web3Connect />
</nav>
{/* Desktop/Tablet Navigation */}
<nav className="hidden lg:flex items-center space-x-4">
{menuItems.map((item) => (
<Link key={item.name} href={item.href} className="relative">
<motion.button
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md ${
pathname === item.href
? "text-indigo-600"
: "text-gray-700 hover:text-indigo-600"
} bg-white hover:bg-gray-50`}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<item.icon className="h-5 w-5 mr-2" aria-hidden="true" />
<span>{item.name}</span>
</motion.button>
{pathname === item.href && (
<motion.div
className="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
layoutId="underline"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
/>
)}
</Link>
))}
<div className="hidden lg:block">
<Web3Connect />
</div>
</nav>

{/* Mobile/Tablet Menu Button */}
<div className="lg:hidden flex items-center space-x-2">
<div className="scale-90">
<Web3Connect />
</div>
<button
onClick={toggleSidebar}
className="p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100"
>
<Bars3Icon className="h-6 w-6" />
</button>
</div>
</div>
</div>
</div>
</motion.header>
</motion.header>

{/* Mobile/Tablet Sidebar */}
<AnimatePresence>
{isSidebarOpen && (
<>
<motion.div
className="fixed inset-0 bg-black bg-opacity-50 z-40"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={toggleSidebar}
/>
<motion.div
className="fixed right-0 top-0 h-full w-72 bg-white z-50 shadow-lg"
initial={{ x: "100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ type: "spring", damping: 20 }}
>
<div className="p-6">
<button
onClick={toggleSidebar}
className="absolute top-4 right-4 p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100"
>
<XMarkIcon className="h-6 w-6" />
</button>
<div className="mt-8 space-y-6">
{menuItems.map((item) => (
<Link
key={item.name}
href={item.href}
onClick={toggleSidebar}
className={`flex items-center p-4 rounded-lg transition-colors ${
pathname === item.href
? "bg-indigo-50 text-indigo-600"
: "text-gray-700 hover:bg-gray-50"
}`}
>
<item.icon className="h-6 w-6 mr-4" />
<span className="text-base font-medium">{item.name}</span>
</Link>
))}
</div>
</div>
</motion.div>
</>
)}
</AnimatePresence>
</>
);
};

export default Header;
export default Header;
2 changes: 1 addition & 1 deletion client/app/components/Pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Dashboard from "./Dashboard";
const HomePage = () => {
const { isConnected } = useAccount();
return (
<main className="h-screen pt-20 w-full bg-white ">
<main className="h-screen pt-20 w-full bg-white overflow-hidden">
{isConnected ? <Dashboard /> : <LoginPage />}
</main>
);
Expand Down
2 changes: 1 addition & 1 deletion client/app/election/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,4 @@ const ElectionPage = ({ params }: { params: { id: `0x${string}` } }) => {
);
};

export default ElectionPage;
export default ElectionPage;
5 changes: 5 additions & 0 deletions client/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}

html {
scroll-behavior: smooth;
}

::-webkit-scrollbar {
width: 1px;
Expand Down
2 changes: 1 addition & 1 deletion client/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import HomePage from "./components/Pages/HomePage";

export default function Home() {
return (
<main className="flex min-h-screen w-screen flex-col items-center justify-between ">
<main className="flex min-h-screen w-screen flex-col items-center justify-between overflow-hidden">
<HomePage />
</main>
);
Expand Down