pushing css for pages and small features

This commit is contained in:
PawelC4
2025-11-09 01:28:33 -05:00
parent 44b5a4dc49
commit 26255b64fc
4 changed files with 234 additions and 103 deletions
+84 -29
View File
@@ -1,38 +1,74 @@
"use client"; "use client";
import React, { useState } from "react"; import React, { useState } from "react";
import { useRouter } from "next/navigation"; // import { useRouter } from "next/navigation"; // Removed Next.js import
import Link from 'next/link'; // import Link from 'next/link'; // Removed Next.js import
function Dashboard() { // 2. Changed from 'export default function' export default function Dashboard() {
const router = useRouter(); // const router = useRouter(); // Removed Next.js hook
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [sideBarOpen, setSidebarOpen] = useState(true); const [sideBarOpen, setSidebarOpen] = useState(true);
// 1. Add state to track sort order
const [sortOrder, setSortOrder] = useState("newest"); // 'newest' or 'oldest'
const projects = [ const projects = [
{ name: "Alpha Project", createdAt: "2025-01-01" }, { name: "Alpha Project", createdAt: "2025-01-01" },
{ name: "Beta Board", createdAt: "2025-02-15" }, { name: "Beta Board", createdAt: "2025-02-15" },
{ name: "Gamma Tasl", createdAt: "2025-03-10" }, { name: "Gamma Tasl", createdAt: "2025-03-10" },
]; ];
const filtered = projects.filter((p) =>
// 2. Update sorting logic to use the sortOrder state
const sortedProjects = [...projects].sort((a, b) => {
// Get numeric timestamps to avoid TypeScript error
const dateA = new Date(a.createdAt).getTime();
const dateB = new Date(b.createdAt).getTime();
if (sortOrder === "newest") {
return dateB - dateA; // Newest first
} else {
return dateA - dateB; // Oldest first
}
});
// 3. Filter the *sorted* array based on the query
const filtered = sortedProjects.filter((p) =>
p.name.toLowerCase().includes(query.toLowerCase()) p.name.toLowerCase().includes(query.toLowerCase())
); );
// Helper function to handle navigation for the "Create" button
const handleCreateClick = () => {
// Use standard window navigation instead of Next.js router
// Also corrected typo from "dashbaord" to "dashboard"
window.location.href = "/dashboard/create";
};
// 4. Function to toggle the sort order
const toggleSortOrder = () => {
setSortOrder(currentOrder => (currentOrder === "newest" ? "oldest" : "newest"));
};
return ( return (
<div className="flex min-h-screen bg-zinc-50 dark:bg-black font-sans transition-all duration-300"> <div
className="flex min-h-screen font-sans transition-all duration-300"
style={{ backgroundColor: '#FEEEDF' }} // Main background
>
<aside <aside
className={`${sideBarOpen ? "w-64" : "w-16" className={`${sideBarOpen ? "w-64" : "w-16"
} bg-white dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-800 transition-all duration-300 flex flex-col`} } border-r transition-all duration-300 flex flex-col`}
style={{ backgroundColor: '#99A48A', borderColor: '#8A947E' }} // Sidebar background and border
> >
<div className="flex items-center justify-between p-4 border-b border-zinc-200 dark:border-zinc-800"> <div
className="flex items-center justify-between p-4 "
style={{ borderColor: '#8A947E' }} // Sidebar border
>
{sideBarOpen && ( {sideBarOpen && (
<span className="text-lg font-semibold text-zinc-800 dark:text-zinc-100"> <span className="text-lg font-semibold text-white">
More More
</span> </span>
)} )}
<button <button
onClick={() => setSidebarOpen(!sideBarOpen)} onClick={() => setSidebarOpen(!sideBarOpen)}
className="text-zinc-600 dark:text-zinc-300 hover:text-blue-500 transition-colors" className="text-white hover:text-gray-200 transition-colors"
title="Toggle Sidebar" title="Toggle Sidebar"
> >
☰ ☰
@@ -40,32 +76,34 @@ function Dashboard() { // 2. Changed from 'export default function'
</div> </div>
<nav <nav
className={`flex flex-col p-4 gap-3 text-zinc-700 dark:text-zinc-300 transition-opacity duration-200 ${sideBarOpen ? "opacity-100" : "opacity-0" className={`flex flex-col p-4 gap-3 text-white transition-opacity duration-200 ${sideBarOpen ? "opacity-100" : "opacity-0"
}`} }`}
> >
<Link <a
href="/" href="/"
className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors" className="hover:text-gray-200 transition-colors"
> >
Home Home
</Link> </a>
<p <p
className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors" className="hover:text-gray-200 transition-colors"
> >
Settings Settings
</p> </p>
{/* 3. Added the Logout link here */} <a
<Link
href="/auth/logout" href="/auth/logout"
className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors" className="hover:text-gray-200 transition-colors"
> >
Logout Logout
</Link> </a>
</nav> </nav>
</aside> </aside>
<div className="flex-1 flex flex-col min-w-0"> <div className="flex-1 flex flex-col min-w-0">
<header className="sticky top-0 z-10 bg-white dark:bg-black/80 backdrop-blur-sm border-b border-zinc-200 dark:border-zinc-800"> <header
className="sticky top-0 z-10 backdrop-blur-sm border-b"
style={{ backgroundColor: 'rgba(153, 164, 138, 0.9)', borderColor: '#8A947E' }} // Top bar background (semi-transparent) and border
>
<div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between gap-4"> <div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between gap-4">
<div className="flex-1"> <div className="flex-1">
<input <input
@@ -73,15 +111,17 @@ function Dashboard() { // 2. Changed from 'export default function'
value={query} value={query}
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
placeholder="Search projects, boards or tasks..." placeholder="Search projects, boards or tasks..."
className="w-full max-w-md px-4 py-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-blue-500" className="w-full max-w-md px-4 py-2 rounded-md border text-black focus:outline-none focus:ring-2 focus:ring-blue-500"
style={{ backgroundColor: '#F7F7F7', borderColor: '#D1D1D1' }} // Search bar "off-white"
/> />
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
type="button" type="button"
onClick={() => router.push("/dashbaord/create")} onClick={handleCreateClick} // Use the new handler
className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md shadow-sm" className="text-white px-4 py-2 rounded-md shadow-sm hover:opacity-90"
style={{ backgroundColor: '#EA627F' }} // Create button
> >
Create Create
</button> </button>
@@ -90,25 +130,40 @@ function Dashboard() { // 2. Changed from 'export default function'
</header> </header>
<main className="max-w-7xl w-full mx-auto px-6 py-10"> <main className="max-w-7xl w-full mx-auto px-6 py-10">
<h1 className="text-2xl font-semibold text-black dark:text-zinc-50 mb-4"> <div className="flex justify-between items-center mb-4">
Project Names <h1 className="text-2xl font-semibold text-black">
</h1> Project Names
</h1>
<button
type="button"
onClick={toggleSortOrder}
className="px-3 py-1 text-sm font-medium border rounded-md"
style={{
color: '#333',
backgroundColor: '#F7F7F7', // "off-white"
borderColor: '#D1D1D1'
}}
>
Sort by: {sortOrder === 'newest' ? 'Newest' : 'Oldest'}
</button>
</div>
<section> <section>
<ul className="space-y-3"> <ul className="space-y-3">
{filtered.map((project, index) => ( {filtered.map((project, index) => (
<li <li
key={index} key={index}
className="flex justify-between p-4 bg-white dark:bg-zinc-900 border border-zinc-100 dark:border-zinc-800 rounded-md text-zinc-800 dark:text-zinc-100" className="flex justify-between p-4 border rounded-md"
style={{ backgroundColor: '#B8C0AD', color: '#222', borderColor: '#A9B29E' }} // Project boxes
> >
<span>{project.name}</span> <span>{project.name}</span>
<span className="text-zinc-500 dark:text-zinc-400 text-sm"> <span className="text-gray-700 text-sm">
Created: {project.createdAt} Created: {project.createdAt}
</span> </span>
</li> </li>
))} ))}
{filtered.length === 0 && ( {filtered.length === 0 && (
<li className="text-zinc-500">No results found</li> <li className="text-gray-600">No results found</li>
)} )}
</ul> </ul>
</section> </section>
+140 -50
View File
@@ -1,9 +1,10 @@
"use client"; "use client";
import React, { useState, useEffect } from "react"; import React, { useState } from "react";
import { motion, useMotionValue, useTransform, useAnimation } from "framer-motion"; import { motion, useMotionValue, useTransform } from "framer-motion";
import { useRouter } from "next/navigation";
// Removed local fallback JSX declaration — use the official React type definitions instead:
// install @types/react and @types/react-dom so JSX.IntrinsicElements is provided by those packages.
// 1. Updated ColorWay interface // 1. Updated ColorWay interface
interface ColorWay { interface ColorWay {
card: string; card: string;
@@ -28,31 +29,126 @@ interface CardData {
tracks: string[]; tracks: string[];
} }
const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) => { const cardData: CardData[] = [
const [cards, setCards] = useState<CardData[]>(initialCards); {
const router = useRouter();
// Update cards state when initialCards prop changes id: 1,
useEffect(() => {
setCards(initialCards);
}, [initialCards]);
const removeCard = () => { title: " WEBSITE",
summary:
"FFind out what makes GoonMAXXER unique.With this innovative website you will be able to explore various features and functionalities that set GoonMAXXER apart from the rest.",
tracks: ["Gemini", "Auth0", "VibeCODING", "SmellyMaxxing", "shitposting"],
},
{
id: 2,
title: "Intro to React",
summary:
"Learn the fundamentals of React, including components, state, and props.",
tracks: ["React", "JS", "Frontend"],
},
{
id: 3,
title: "State Management",
summary:
"Explore complex state solutions with Zustand, Redux, and Context API.",
tracks: ["React", "Zustand", "State"],
},
{
id: 4,
title: "Next.js 14",
summary: "Master the app router, server actions, and data fetching.",
tracks: ["Next.js", "React", "Fullstack"],
},
{
id: 5,
title: "UI/UX Principles",
summary:
"A complete guide to user-centric design, prototyping, and testing.",
tracks: ["Design", "UI", "UX"],
},
{
id: 6,
title: "Node.js Essentials",
summary:
"Build scalable, high-performance backend applications with Node.js.",
tracks: ["Node", "Backend", "JS"],
},
{
id: 7,
title: "TypeScript",
summary:
"Add static typing to your JavaScript projects for robust, large-scale apps.",
tracks: ["TypeScript", "JS", "DevOps"],
},
{
id: 8,
title: "Framer Motion",
summary: "Create production-ready animations for your React applications.",
tracks: ["React", "Animation", "Framer"],
},
].reverse();
const SwipeCards: React.FC = () => {
const [cards, setCards] = useState<CardData[]>(cardData);
const onSwipe = () => {
setCards((prev) => prev.slice(0, prev.length - 1)); setCards((prev) => prev.slice(0, prev.length - 1));
}; };
const handleAccept = (cardData: CardData) => {
removeCard();
// Redirect to chatbot with card data
router.push(`/chatbot?title=${encodeURIComponent(cardData.title)}&summary=${encodeURIComponent(cardData.summary)}`);
};
const handleReject = () => {
removeCard();
};
const handleReset = () => { const handleReset = () => {
setCards([]); // Reset to initial cards setCards(cardData);
}; };
return ( return (
@@ -60,8 +156,8 @@ const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) =>
className="grid h-screen w-full place-items-center bg-orange-100" className="grid h-screen w-full place-items-center bg-orange-100"
// -gradient-to-tr from-orange-200 to-orange-100 // -gradient-to-tr from-orange-200 to-orange-100
style={{ style={{
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 32 32' width='32' height='32' fill='none' viewBox='0 0 32 32' width='32' height='32' fill='none'
stroke-width='2' stroke='%23d4d4d4'%3e%3cpath d='M0 .5H31.5V32'/%3e%3c/svg%3e")`, stroke-width='2' stroke='%23d4d4d4'%3e%3cpath d='M0 .5H31.5V32'/%3e%3c/svg%3e")`,
}} }}
> >
@@ -74,8 +170,7 @@ const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) =>
cardData={card} cardData={card}
colorWay={colorWay} colorWay={colorWay}
isFront={index === cards.length - 1} isFront={index === cards.length - 1}
onAccept={handleAccept} onSwipe={onSwipe}
onReject={handleReject}
/> />
); );
}) })
@@ -104,11 +199,10 @@ interface CardProps {
cardData: CardData; cardData: CardData;
colorWay: ColorWay; colorWay: ColorWay;
isFront: boolean; isFront: boolean;
onAccept: (cardData: CardData) => void; onSwipe: () => void;
onReject: () => void;
} }
const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onReject }) => { const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onSwipe }) => {
const { title, summary, tracks } = cardData; const { title, summary, tracks } = cardData;
const x = useMotionValue(0); const x = useMotionValue(0);
@@ -118,30 +212,20 @@ const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onRe
[-250, -100, 0, 100, 250], [-250, -100, 0, 100, 250],
[0, 1, 1, 1, 0], [0, 1, 1, 1, 0],
); );
const controls = useAnimation();
const acceptOpacity = useTransform(x, [50, 150], [0, 1]); const acceptOpacity = useTransform(x, [50, 150], [0, 1]);
const rejectOpacity = useTransform(x, [-150, -50], [1, 0]); const rejectOpacity = useTransform(x, [-150, -50], [1, 0]);
const badgeRotate = useTransform(x, [-150, 150], [-15, 15]); const badgeRotate = useTransform(x, [-150, 150], [-15, 15]);
const handleDragEnd = async (event: MouseEvent | TouchEvent | PointerEvent, info: { offset: { x: number } }) => { const handleDragEnd = (event: MouseEvent | TouchEvent | PointerEvent, info: { offset: { x: number } }) => {
if (info.offset.x > 100) { if (Math.abs(info.offset.x) > 100) {
// Card accepted onSwipe();
await controls.start({ x: 1000, opacity: 0, transition: { duration: 0.1 } }); // Animate off-screen quickly
onAccept(cardData); // Then call onAccept which removes the card and redirects
} else if (info.offset.x < -100) {
// Card rejected
await controls.start({ x: -1000, opacity: 0, transition: { duration: 0.1 } }); // Animate off-screen quickly
onReject(); // Then call onReject which removes the card
} else {
// Card not swiped far enough, snap back to center
controls.start({ x: 0, rotate: 0, opacity: 1, transition: { type: "spring", stiffness: 300, damping: 30 } });
} }
}; };
return ( return (
<motion.div <motion.div
className="absolute flex h-[56rem] w-[42rem] flex-col justify-between overflow-hidden rounded-2xl p-6 shadow-2xl hover:cursor-grab active:cursor-grabbing" className="absolute flex h-[48rem] w-[36rem] flex-col justify-between overflow-hidden rounded-2xl p-6 shadow-2xl hover:cursor-grab active:cursor-grabbing"
style={{ style={{
x, x,
rotate, rotate,
@@ -151,7 +235,10 @@ const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onRe
zIndex: isFront ? 2 : 1, zIndex: isFront ? 2 : 1,
pointerEvents: isFront ? "auto" : "none", pointerEvents: isFront ? "auto" : "none",
}} }}
animate={controls} animate={{
scale: isFront ? 1 : 0.95,
y: isFront ? 0 : -40,
}}
transition={{ type: "spring", stiffness: 300, damping: 30 }} transition={{ type: "spring", stiffness: 300, damping: 30 }}
drag={isFront ? "x" : false} drag={isFront ? "x" : false}
dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }} dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
@@ -175,20 +262,24 @@ const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onRe
<div className="relative z-0"> <div className="relative z-0">
{/* 3. Applied the specific titleColor here */} {/* 3. Applied the specific titleColor here */}
<h2 <h2
className="mb-4 text-center text-3xl font-bold" className="mb-4 text-center text-7xl font-bold"
style={{ color: colorWay.titleColor }} style={{ color: colorWay.titleColor }}
> >
{title} {title}
</h2> </h2>
{/* This summary <p> will inherit colorWay.text from the parent */} {/* This summary <p> will inherit colorWay.text from the parent */}
<p className="text-center text-xl font-light">{summary}</p> <p className="text-center text-3xl font-light">{summary}</p>
</div> </div>
<div className="relative z-0 flex flex-wrap items-center justify-center gap-2"> <div className="relative z-0 flex flex-wrap items-center justify-center gap-2">
{tracks.slice(0, 2).map((track, index) => ( {/* This <h3> will also inherit colorWay.text */}
<h3 className="mb-4 w-full text-center text-4xl font-semibold">
Tracks
</h3>
{tracks.map((track) => (
<span <span
key={track} key={track}
className="flex items-center justify-center rounded-full px-8 py-3 text-sm font-medium" className="flex items-center justify-center rounded-full px-8 py-3 text-2xl font-medium"
style={{ style={{
// This logic now correctly contrasts with the main text color // This logic now correctly contrasts with the main text color
backgroundColor: backgroundColor:
@@ -198,7 +289,6 @@ const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onRe
}} }}
> >
{track} {track}
{index === 0 && tracks.length > 1 && ", "}
</span> </span>
))} ))}
</div> </div>
@@ -207,4 +297,4 @@ const Card: React.FC<CardProps> = ({ cardData, colorWay, isFront, onAccept, onRe
}; };
export default SwipeCards; export default SwipeCards;
+1
View File
@@ -14,6 +14,7 @@ export interface GenerateConfig {
temperature: number; temperature: number;
topP: number; topP: number;
responseMimeType: string; responseMimeType: string;
maxOutputTokens?: number;
} }
export interface ChatSetting { export interface ChatSetting {
+9 -24
View File
@@ -1,4 +1,5 @@
import Image from "next/image"; import Image from "next/image";
import Link from "next/link";
export default function Home() { export default function Home() {
return ( return (
@@ -8,19 +9,19 @@ export default function Home() {
> >
<header className="absolute top-6 left-8 right-8 flex items-center justify-between text-sm font-medium text-zinc-700 dark:text-zinc-300"> <header className="absolute top-6 left-8 right-8 flex items-center justify-between text-sm font-medium text-zinc-700 dark:text-zinc-300">
<Image <Image
className="dark:invert"
src="/next.svg" src="/logo.svg"
alt="Next.js logo" alt="logo.js logo"
width={100} width={100}
height={20} height={20}
priority priority
/> />
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<a href="/signin" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> <a href="/dashboard" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">
Sign in Dashboard
</a> </a>
<a href="/register" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"> <a href="/cards" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">
Register Cards
</a> </a>
</div> </div>
</header> </header>
@@ -39,29 +40,13 @@ export default function Home() {
className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400" className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400"
> >
Got a hackathon coming up? Tell us your track, your team’s skills, what you’re passionate about, and more — and we’ll provide you with the perfect project idea!{" "} Got a hackathon coming up? Tell us your track, your team’s skills, what you’re passionate about, and more — and we’ll provide you with the perfect project idea!{" "}
{/* <a
                href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
                className="font-medium text-zinc-950 dark:text-zinc-50"
              >
                Templates
              </a>{" "}
              or the{" "}
              <a
                href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
                className="font-medium text-zinc-950 dark:text-zinc-50"
              >
                Learning
              </a>{" "} */}
{/* center. */}
</p> </p>
{/* <ProtectedNavButton>Get Started</ProtectedNavButton> */}
<button <button
style={{ backgroundColor: "#173C46", color: "white" }} style={{ backgroundColor: "#173C46", color: "white" }}
className="px-4 py-1.5 rounded-md shadow-md font-semibold hover:opacity-90 transition-opacity" className="px-4 py-1.5 rounded-md shadow-md font-semibold hover:opacity-90 transition-opacity"
> >
{/* {children} */} <Link href="/dashboard">Get Started</Link>
Get Started
</button> </button>
</div> </div>