Skip to content

Commit 50cef70

Browse files
authored
Merge pull request #80 from asmit27rai/responsiveness
Add responsiveness to Navbar and Chatbot
2 parents c5896d7 + dae7c7d commit 50cef70

File tree

7 files changed

+163
-84
lines changed

7 files changed

+163
-84
lines changed

client/app/components/Cards/ElectionInfoCard.tsx

+12-11
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,30 @@ const ElectionInfoCard = ({ counts, filterStatus, setFilterStatus }: any) => {
1313
{ name: "Active", image: TbCalendarDot, count: counts.active },
1414
{ name: "Ended", image: TbCalendarOff, count: counts.ended },
1515
];
16+
1617
return (
17-
<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">
18-
<div className="p-4">
19-
<h5 className="block font-sans text-xl antialiased font-semibold leading-snug tracking-normal text-blue-gray-900">
18+
<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">
19+
<div className="p-2 sm:p-4">
20+
<h5 className="block font-sans text-lg sm:text-xl antialiased font-semibold leading-snug tracking-normal text-blue-gray-900">
2021
Election List
2122
</h5>
2223
</div>
23-
<nav className="flex flex-col gap-1 p-2 font-sans text-base font-normal text-blue-gray-700">
24+
<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">
2425
{ElectionInfoImage.map((electionPart, key) => {
2526
return (
2627
<button
2728
key={key}
2829
onClick={() => setFilterStatus(key)}
29-
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 ${
30-
key === filterStatus && " bg-slate-100"
30+
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 ${
31+
key === filterStatus && "bg-slate-100"
3132
}`}
3233
>
33-
<div className="grid mr-4 place-items-center">
34-
<electionPart.image size={20} />
34+
<div className="grid mr-2 sm:mr-4 place-items-center">
35+
<electionPart.image size={18} />
3536
</div>
3637
{electionPart.name}
37-
<div className="absolute right-2 px-2 font-sans text-sm font-semibold uppercase rounded-full whitespace-nowrap text-blue-gray-900">
38-
<span className="">{electionPart.count}</span>
38+
<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">
39+
<span>{electionPart.count}</span>
3940
</div>
4041
</button>
4142
);
@@ -45,4 +46,4 @@ const ElectionInfoCard = ({ counts, filterStatus, setFilterStatus }: any) => {
4546
);
4647
};
4748

48-
export default ElectionInfoCard;
49+
export default ElectionInfoCard;

client/app/components/ChatBot/ChatBot.tsx

+19-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import React, { useState, useRef, useEffect } from "react";
44
import { motion, AnimatePresence } from "framer-motion";
55
import { ArrowUpIcon, ChatBubbleLeftRightIcon } from "@heroicons/react/24/solid";
6+
import { XMarkIcon } from "@heroicons/react/24/outline"; // Corrected the import for XMarkIcon
67

78
interface Message {
89
content: string;
@@ -49,7 +50,6 @@ const ChatBot: React.FC = () => {
4950
setMessages((prevMessages) => [...prevMessages, reply]);
5051
} catch (error) {
5152
console.error("Error:", error);
52-
// Add error message in chatbot here
5353
}
5454
};
5555

@@ -72,12 +72,19 @@ const ChatBot: React.FC = () => {
7272
animate={{ opacity: 1, scale: 1, y: 0 }}
7373
exit={{ opacity: 0, scale: 0.95, y: 20 }}
7474
transition={{ duration: 0.2 }}
75-
className="absolute bottom-16 right-0 w-96 h-[32rem] bg-white rounded-lg shadow-xl overflow-hidden flex flex-col"
75+
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"
7676
>
77-
<div className="bg-blue-600 text-white p-4 text-center font-semibold">
78-
Agora Chatbot
77+
<div className="bg-blue-600 text-white p-3 flex items-center justify-between">
78+
<h3 className="font-semibold">Agora Chatbot</h3>
79+
<button
80+
onClick={() => setIsOpen(false)} // Close chatbot on click
81+
className="text-white focus:outline-none"
82+
>
83+
<XMarkIcon className="w-6 h-6" />
84+
</button>
7985
</div>
80-
<div className="flex-grow overflow-auto p-4 space-y-4">
86+
87+
<div className="flex-grow overflow-auto p-3 space-y-3">
8188
{messages.map((msg, index) => (
8289
<motion.div
8390
key={index}
@@ -87,28 +94,23 @@ const ChatBot: React.FC = () => {
8794
className={`flex ${msg.role === "assistant" ? "justify-start" : "justify-end"}`}
8895
>
8996
<div
90-
className={`max-w-[80%] p-3 rounded-lg ${
91-
msg.role === "assistant"
92-
? "bg-gray-200 text-gray-800"
93-
: "bg-blue-600 text-white"
94-
}`}
97+
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"}`}
9598
>
9699
{msg.content}
97100
</div>
98101
</motion.div>
99102
))}
100103
<div ref={messageEndRef} />
101104
</div>
102-
<form onSubmit={handleSubmit} className="p-4 bg-gray-100">
103-
<div className="flex items-center bg-white rounded-full overflow-hidden shadow">
105+
106+
<form onSubmit={handleSubmit} className="p-3 bg-gray-100">
107+
<div className="flex items-center gap-2">
104108
<input
105109
type="text"
106110
value={inputMessage}
107-
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
108-
setInputMessage(e.target.value)
109-
}
111+
onChange={(e) => setInputMessage(e.target.value)}
110112
placeholder="Type your message..."
111-
className="flex-grow px-4 py-2 focus:outline-none"
113+
className="flex-grow px-3 py-2 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
112114
/>
113115
<button type="submit" className="bg-blue-600 text-white p-2 rounded-full">
114116
<ArrowUpIcon className="w-5 h-5" />
@@ -123,4 +125,4 @@ const ChatBot: React.FC = () => {
123125
);
124126
};
125127

126-
export default ChatBot;
128+
export default ChatBot;
+124-53
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
"use client";
22

3-
import React from "react";
3+
import React, { useState } from "react";
44
import Link from "next/link";
55
import { usePathname } from "next/navigation";
6-
import { motion } from "framer-motion";
6+
import { motion, AnimatePresence } from "framer-motion";
77
import {
88
PlusCircleIcon,
99
UserIcon,
1010
HomeIcon,
11+
XMarkIcon,
12+
Bars3Icon,
1113
} from "@heroicons/react/24/outline";
1214
import Web3Connect from "../Helper/Web3Connect";
1315
import Image from "next/image";
@@ -20,61 +22,130 @@ const menuItems = [
2022

2123
const Header = () => {
2224
const pathname = usePathname();
25+
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
26+
27+
const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);
2328

2429
return (
25-
<motion.header
26-
className="bg-white border-b border-gray-200 fixed w-full z-30 shadow-sm"
27-
initial={{ y: -100 }}
28-
animate={{ y: 0 }}
29-
transition={{ type: "spring", stiffness: 300, damping: 30 }}
30-
>
31-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
32-
<div className="flex justify-between h-16">
33-
<Link href="/" className="flex-shrink-0 flex items-center">
34-
<Image
35-
width={32}
36-
height={32}
37-
className="h-8 w-auto"
38-
src="/aossie.png"
39-
alt="Agora Blockchain"
40-
/>
41-
<h1 className="ml-3 text-xl font-bold text-gray-800 hidden sm:block">
42-
Agora Blockchain
43-
</h1>
44-
</Link>
30+
<>
31+
<motion.header
32+
className="bg-white border-b border-gray-200 fixed w-full z-30 shadow-sm"
33+
initial={{ y: -100 }}
34+
animate={{ y: 0 }}
35+
transition={{ type: "spring", stiffness: 300, damping: 30 }}
36+
>
37+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
38+
<div className="flex justify-between h-16">
39+
<Link href="/" className="flex-shrink-0 flex items-center">
40+
<Image
41+
width={32}
42+
height={32}
43+
className="h-8 w-auto"
44+
src="/aossie.png"
45+
alt="Agora Blockchain"
46+
/>
47+
<h1 className="ml-3 text-xl font-bold text-gray-800 hidden sm:block">
48+
Agora Blockchain
49+
</h1>
50+
</Link>
4551

46-
<nav className="flex items-center space-x-4">
47-
{menuItems.map((item) => (
48-
<Link key={item.name} href={item.href} className="relative">
49-
<motion.button
50-
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md ${
51-
pathname === item.href
52-
? "text-indigo-600"
53-
: "text-gray-700 hover:text-indigo-600"
54-
} bg-white hover:bg-gray-50`}
55-
whileHover={{ scale: 1.05 }}
56-
whileTap={{ scale: 0.95 }}
57-
>
58-
<item.icon className="h-5 w-5 mr-2" aria-hidden="true" />
59-
<span className="hidden sm:inline">{item.name}</span>
60-
</motion.button>
61-
{pathname === item.href && (
62-
<motion.div
63-
className="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
64-
layoutId="underline"
65-
initial={{ opacity: 0 }}
66-
animate={{ opacity: 1 }}
67-
transition={{ duration: 0.3 }}
68-
/>
69-
)}
70-
</Link>
71-
))}
72-
<Web3Connect />
73-
</nav>
52+
{/* Desktop/Tablet Navigation */}
53+
<nav className="hidden lg:flex items-center space-x-4">
54+
{menuItems.map((item) => (
55+
<Link key={item.name} href={item.href} className="relative">
56+
<motion.button
57+
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md ${
58+
pathname === item.href
59+
? "text-indigo-600"
60+
: "text-gray-700 hover:text-indigo-600"
61+
} bg-white hover:bg-gray-50`}
62+
whileHover={{ scale: 1.05 }}
63+
whileTap={{ scale: 0.95 }}
64+
>
65+
<item.icon className="h-5 w-5 mr-2" aria-hidden="true" />
66+
<span>{item.name}</span>
67+
</motion.button>
68+
{pathname === item.href && (
69+
<motion.div
70+
className="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
71+
layoutId="underline"
72+
initial={{ opacity: 0 }}
73+
animate={{ opacity: 1 }}
74+
transition={{ duration: 0.3 }}
75+
/>
76+
)}
77+
</Link>
78+
))}
79+
<div className="hidden lg:block">
80+
<Web3Connect />
81+
</div>
82+
</nav>
83+
84+
{/* Mobile/Tablet Menu Button */}
85+
<div className="lg:hidden flex items-center space-x-2">
86+
<div className="scale-90">
87+
<Web3Connect />
88+
</div>
89+
<button
90+
onClick={toggleSidebar}
91+
className="p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100"
92+
>
93+
<Bars3Icon className="h-6 w-6" />
94+
</button>
95+
</div>
96+
</div>
7497
</div>
75-
</div>
76-
</motion.header>
98+
</motion.header>
99+
100+
{/* Mobile/Tablet Sidebar */}
101+
<AnimatePresence>
102+
{isSidebarOpen && (
103+
<>
104+
<motion.div
105+
className="fixed inset-0 bg-black bg-opacity-50 z-40"
106+
initial={{ opacity: 0 }}
107+
animate={{ opacity: 1 }}
108+
exit={{ opacity: 0 }}
109+
onClick={toggleSidebar}
110+
/>
111+
<motion.div
112+
className="fixed right-0 top-0 h-full w-72 bg-white z-50 shadow-lg"
113+
initial={{ x: "100%" }}
114+
animate={{ x: 0 }}
115+
exit={{ x: "100%" }}
116+
transition={{ type: "spring", damping: 20 }}
117+
>
118+
<div className="p-6">
119+
<button
120+
onClick={toggleSidebar}
121+
className="absolute top-4 right-4 p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100"
122+
>
123+
<XMarkIcon className="h-6 w-6" />
124+
</button>
125+
<div className="mt-8 space-y-6">
126+
{menuItems.map((item) => (
127+
<Link
128+
key={item.name}
129+
href={item.href}
130+
onClick={toggleSidebar}
131+
className={`flex items-center p-4 rounded-lg transition-colors ${
132+
pathname === item.href
133+
? "bg-indigo-50 text-indigo-600"
134+
: "text-gray-700 hover:bg-gray-50"
135+
}`}
136+
>
137+
<item.icon className="h-6 w-6 mr-4" />
138+
<span className="text-base font-medium">{item.name}</span>
139+
</Link>
140+
))}
141+
</div>
142+
</div>
143+
</motion.div>
144+
</>
145+
)}
146+
</AnimatePresence>
147+
</>
77148
);
78149
};
79150

80-
export default Header;
151+
export default Header;

client/app/components/Pages/HomePage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Dashboard from "./Dashboard";
55
const HomePage = () => {
66
const { isConnected } = useAccount();
77
return (
8-
<main className="h-screen pt-20 w-full bg-white ">
8+
<main className="h-screen pt-20 w-full bg-white overflow-hidden">
99
{isConnected ? <Dashboard /> : <LoginPage />}
1010
</main>
1111
);

client/app/election/[id]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@ const ElectionPage = ({ params }: { params: { id: `0x${string}` } }) => {
7878
);
7979
};
8080

81-
export default ElectionPage;
81+
export default ElectionPage;

client/app/globals.css

+5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
body {
66
background-color: #ffffff;
7+
margin: 0;
8+
overflow: hidden;
79
}
810

11+
html {
12+
scroll-behavior: smooth;
13+
}
914

1015
::-webkit-scrollbar {
1116
width: 1px;

client/app/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import HomePage from "./components/Pages/HomePage";
33

44
export default function Home() {
55
return (
6-
<main className="flex min-h-screen w-screen flex-col items-center justify-between ">
6+
<main className="flex min-h-screen w-screen flex-col items-center justify-between overflow-hidden">
77
<HomePage />
88
</main>
99
);

0 commit comments

Comments
 (0)