Add dark mode

This commit is contained in:
MartinBraquet
2025-07-30 05:12:55 +02:00
parent 887c40c2c6
commit 90a1e990b4
24 changed files with 178 additions and 93 deletions

View File

@@ -2,6 +2,7 @@
import Link from "next/link";
import {useSession, signOut} from "next-auth/react";
import ThemeToggle from "@/lib/client/theme";
export default function Header() {
const {data: session} = useSession();
@@ -9,11 +10,12 @@ export default function Header() {
console.log(session);
return (
<header className="w-full bg-white shadow-md py-4 px-8">
<header className="w-full shadow-md py-4 px-8">
<nav className="flex justify-between items-center">
<Link href="/" className="text-xl font-bold text-gray-800 hover:text-blue-600 transition-colors">
<Link href="/" className="text-xl font-bold hover:text-blue-600 transition-colors">
BayesBond
</Link>
<ThemeToggle />
<div className="flex items-center space-x-4">
{session ? (

View File

@@ -25,7 +25,7 @@ export default function AuthError() {
// })();
//
// return (
// <div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
// <div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
// <div className="max-w-md w-full space-y-8 text-center">
// <div className="rounded-full bg-red-100 p-3 inline-flex items-center justify-center">
// <svg
@@ -42,7 +42,7 @@ export default function AuthError() {
// />
// </svg>
// </div>
// <h2 className="mt-6 text-3xl font-extrabold text-gray-900">
// <h2 className="mt-6 text-3xl font-extrabold ">
// Verification Error
// </h2>
// <p className="mt-2 text-sm text-gray-600">{errorMessage}</p>
@@ -55,7 +55,7 @@ export default function AuthError() {
// </Link>
// <Link
// href="/login"
// className="w-full flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
// className="w-full flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover: focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
// >
// Go to Login
// </Link>

View File

@@ -2,7 +2,7 @@ import Link from "next/link";
export default function VerificationSuccess() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8 text-center">
<div className="rounded-full bg-green-100 p-3 inline-flex items-center justify-center">
<svg
@@ -19,7 +19,7 @@ export default function VerificationSuccess() {
/>
</svg>
</div>
<h2 className="mt-6 text-3xl font-extrabold text-gray-900">
<h2 className="mt-6 text-3xl font-extrabold ">
Email Verified Successfully!
</h2>
<p className="mt-2 text-sm text-gray-600">

View File

@@ -265,10 +265,10 @@ function RegisterComponent() {
const conflictOptions = Object.values(ConflictStyle);
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
<h2 className="mt-6 text-center text-3xl font-extrabold ">
Complete Your Profile
</h2>
</div>
@@ -343,7 +343,7 @@ function RegisterComponent() {
required
value={gender || ''}
onChange={(e) => setGender(e.target.value as Gender)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
>
<option value="">Select your gender</option>
{genderOptions.map((g) => (
@@ -364,7 +364,7 @@ function RegisterComponent() {
type="text"
value={location}
onChange={(e) => setLocation(e.target.value)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="City, Country"
/>
</div>
@@ -378,7 +378,7 @@ function RegisterComponent() {
name="personalityType"
value={personalityType || ''}
onChange={(e) => setPersonalityType(e.target.value as PersonalityType)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
>
<option value="">Select your personality type</option>
{personalityOptions.map((type) => (
@@ -398,7 +398,7 @@ function RegisterComponent() {
name="conflictStyle"
value={conflictStyle || ''}
onChange={(e) => setConflictStyle(e.target.value as ConflictStyle)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
>
<option value="">Select your conflict style</option>
{conflictOptions.map((style) => (
@@ -428,7 +428,7 @@ function RegisterComponent() {
<button
type="button"
onClick={() => setShowDropdown(!showDropdown)}
className="px-3 py-2 border-l border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
className="px-3 py-2 border-l border-gray-300 text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
>
<svg className="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
fill="currentColor">
@@ -449,13 +449,13 @@ function RegisterComponent() {
{(showDropdown || newInterest) && (
<div
className="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
className="absolute z-10 mt-1 w-full shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
{/* New interest option */}
{newInterest && !allInterests.some(i =>
i.name.toLowerCase() === newInterest.toLowerCase()
) && (
<div
className="text-gray-900 cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
className=" cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
onClick={() => addNewInterest()}
>
<div className="flex items-center">
@@ -474,7 +474,7 @@ function RegisterComponent() {
.map((interest) => (
<div
key={interest.id}
className="text-gray-900 cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
className=" cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
onClick={() => {
toggleInterest(interest.id);
setNewInterest('');
@@ -541,7 +541,7 @@ function RegisterComponent() {
required
value={description}
onChange={(e) => setDescription(e.target.value)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Tell us about yourself, your background, and what you're looking for in connections."
/>
</div>
@@ -556,7 +556,7 @@ function RegisterComponent() {
rows={2}
value={contactInfo}
onChange={(e) => setContactInfo(e.target.value)}
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-md relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="How can people reach you? (Email, social media, etc.)"
/>
</div>

View File

@@ -5,6 +5,8 @@
:root {
--background: #ffffff;
--foreground: #171717;
/*--background: #0a0a0a;*/
/*--foreground: #ffffff;*/
}
/*@media (prefers-color-scheme: dark) {*/
@@ -27,6 +29,34 @@ html, body {
padding: 0;
}
a {
color: cornflowerblue;
/* Style all headings globally */
h1, h2, h3, h4, h5, h6 {
font-family: 'Inter', sans-serif; /* Clean modern font */
font-weight: 600; /* Semi-bold for clarity */
/*color: #111827; !* Near-black text for readability *!*/
line-height: 1.25;
margin-top: 1.5rem;
margin-bottom: 0.5rem;
}
/* Size scaling */
h1 {
font-size: 2rem; /* ~32px */
}
h2 {
font-size: 1.5rem; /* ~24px */
}
h3 {
font-size: 1.25rem; /* ~20px */
}
h4 {
font-size: 1.125rem; /* ~18px */
}
h5 {
font-size: 1rem; /* ~16px */
}
h6 {
font-size: 0.875rem; /* ~14px */
color: #374151; /* Slightly lighter for subheadings */
}

View File

@@ -1,14 +1,16 @@
// app/layout.tsx
import "./globals.css";
import Header from "./Header";
import Providers from "./providers";
import {ThemeProvider} from 'next-themes';
import {Metadata} from "next";
import Header from "@/app/Header";
import Providers from "@/app/providers";
export const metadata: Metadata = {
title: "BayesBond",
description: "A bonding platform for rational thinkers",
};
export default function RootLayout(
{
children,
@@ -16,13 +18,15 @@ export default function RootLayout(
children: React.ReactNode;
}) {
return (
<html lang="en">
<html lang="en" suppressHydrationWarning>
<body>
<Providers>
<div className="min-h-screen flex flex-col">
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<div className="min-h-screen flex flex-col dark:bg-gray-900 dark:text-white">
<Header/>
<main className="flex-1">{children}</main>
{children}
</div>
</ThemeProvider>
</Providers>
</body>
</html>

View File

@@ -1,9 +1,10 @@
export default function LearnMorePage() {
return (
<div className="text-gray-600 min-h-screen bg-gray-50 p-6">
<div className={`text-gray-600 dark:text-white min-h-screen p-6 `}>
<div className="max-w-3xl mx-auto">
<h1 className="text-3xl font-bold text-gray-900 mb-4">About BayesBond</h1>
<div className="et_pb_text_inner"><h1 id="abstract">Abstract</h1>
<h1 className="text-3xl font-bold mb-4 text-center">About BayesBond</h1>
<div className="et_pb_text_inner">
{/*<h1 id="abstract">Abstract</h1>*/}
<p>Forming and maintaining close connections is fundamental for most peoples mental healthand hence overall
well-being. However, currently available meeting platforms, lacking transparency and searchability, are
deeply failing to bring together thoughtful people. This article lays the path for a platform designed to
@@ -14,6 +15,7 @@ export default function LearnMorePage() {
donation-supported, open source, and democratically governed. The goal of this article is to better
understand the community needs, as well as to gather feedback and collaboration for the suggested
implementation.</p>
<p className="mt-2">For more information, read the <a href="https://martinbraquet.com/meeting-rational">full article here</a>.</p>
<h3 id="how-to-help">How to Help</h3>
<h5 id="give-suggestions-or-contribute">Give Suggestions or Contribute</h5>
<p>Give suggestions or show your inclination to contribute through this <a
@@ -34,8 +36,6 @@ export default function LearnMorePage() {
<h5 id="github-repo">GitHub repo</h5>
<p>Where all the source code and instructions for development are: <a
href="https://github.com/BayesBond/BayesBond">https://github.com/BayesBond/BayesBond</a></p>
<p><a
href="https://martinbraquet.com/meeting-rational">Full article here</a></p>
</div>
</div>
</div>

View File

@@ -67,10 +67,10 @@ function RegisterComponent() {
console.log('Form rendering');
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
<h2 className="mt-6 text-center text-3xl font-extrabold ">
Sign in to your account
</h2>
</div>
@@ -85,7 +85,7 @@ function RegisterComponent() {
name="email"
type="email"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Email address"
/>
</div>
@@ -98,7 +98,7 @@ function RegisterComponent() {
name="password"
type="password"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Password"
/>
</div>
@@ -122,7 +122,7 @@ function RegisterComponent() {
<div className="w-full border-t border-gray-300"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="px-2 bg-gray-50 text-gray-500">Or continue with</span>
<span className="px-2 text-gray-500">Or continue with</span>
</div>
</div>
@@ -130,7 +130,7 @@ function RegisterComponent() {
type="button"
onClick={handleGoogleSignIn}
disabled={isLoading}
className="w-full flex items-center justify-center gap-2 py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-70 disabled:cursor-not-allowed"
className="w-full flex items-center justify-center gap-2 py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover: focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-70 disabled:cursor-not-allowed"
>
<FcGoogle className="w-5 h-5"/>
Sign in with Google

View File

@@ -10,21 +10,21 @@ import Link from "next/link";
export default function HomePage() {
const profilePage = () => {
return (
<main className="min-h-screen bg-gray-50 text-gray-900 flex flex-col">
<main className="min-h-screen flex flex-col">
<ProfilePage />
</main>
)
}
return (
<main className="min-h-screen bg-gray-50 text-gray-900 flex flex-col">
<main className="min-h-screen flex flex-col">
{/* Header */}
<header className="flex justify-between items-center p-6 max-w-6xl mx-auto w-full">
<a
href="https://github.com/BayesBond/BayesBond"
target="_blank"
rel="noopener noreferrer"
className="text-gray-700 hover:text-gray-900 transition"
className="text-gray-700 hover: transition"
>
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.699 1.028 1.595 1.028 2.688 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
@@ -34,7 +34,7 @@ export default function HomePage() {
{/* Hero Section */}
<section className="flex flex-col items-center justify-center flex-1 text-center px-4">
<h1 className="text-5xl md:text-6xl font-extrabold text-gray-900 max-w-3xl leading-tight">
<h1 className="text-5xl md:text-6xl font-extrabold max-w-3xl leading-tight">
BayesBond
</h1>
<p className="mt-6 text-lg md:text-xl text-gray-600 max-w-2xl">

View File

@@ -1,9 +1,9 @@
export default function PrivacyPage() {
return (
<main className="max-w-4xl mx-auto p-8 text-gray-800">
<main className="max-w-4xl mx-auto p-8">
<h1 className="text-3xl font-semibold text-center mb-6">Privacy Policy</h1>
<p className="text-center text-gray-500 mb-12">
<p className="text-center mb-12">
Effective Date: January 1, 2025
</p>
@@ -43,7 +43,7 @@ export default function PrivacyPage() {
support@bayesbond.com.
</p>
<p className="text-gray-600 italic mt-8">
<p className="italic mt-8">
For questions about this Privacy Policy, reach out at support@bayesbond.com.
</p>
</section>

View File

@@ -43,11 +43,11 @@ export default function ProfilePage() {
const intellectualInterests: any = profile?.intellectualInterests ?? [];
return (
<div className="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
<div className="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8 ">
<div className=" shadow overflow-hidden sm:rounded-lg ">
<div className="px-4 py-5 sm:px-6 flex justify-between items-center">
<div>
<h3 className="text-lg leading-6 font-medium text-gray-900">My Profile</h3>
<h3 className="text-lg leading-6 font-medium ">My Profile</h3>
<p className="mt-1 max-w-2xl text-sm text-gray-500">View and update your profile information</p>
</div>
<Link
@@ -61,7 +61,7 @@ export default function ProfilePage() {
<dl className="sm:divide-y sm:divide-gray-200">
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Profile Picture</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
<div className="h-24 w-24 rounded-full overflow-hidden bg-gray-100">
{image ? (
<Image
@@ -82,51 +82,51 @@ export default function ProfilePage() {
</div>
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 ">
<dt className="text-sm font-medium text-gray-500">Name</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{name || 'Not provided'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Email</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{email}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Location</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{location || 'Not provided'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">About</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{description || 'Not provided'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Gender</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{gender || 'Not specified'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Personality Type</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{personalityType || 'Not specified'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Conflict Style</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{conflictStyle || 'Not specified'}
</dd>
</div>
<div className="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Interests</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<dd className="mt-1 text-sm sm:mt-0 sm:col-span-2">
{intellectualInterests.length > 0 ? (
<div className="flex flex-wrap gap-2">
{intellectualInterests.map((value: any, index: number) => (

View File

@@ -98,7 +98,7 @@ export function ProfileFilters({filters, onFilterChange, onToggleFilter, onReset
<button
onClick={() => setShowFilters(!showFilters)}
className="px-4 py-2 bg-white border rounded-lg hover:bg-gray-50 flex items-center gap-2 whitespace-nowrap"
className="px-4 py-2 border rounded-lg flex items-center gap-2 whitespace-nowrap"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
@@ -110,7 +110,7 @@ export function ProfileFilters({filters, onFilterChange, onToggleFilter, onReset
</div>
{showFilters && (
<div className="bg-white p-4 rounded-lg shadow-sm border space-y-4">
<div className=" p-4 rounded-lg shadow-sm border space-y-4">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Gender</label>
@@ -147,7 +147,7 @@ export function ProfileFilters({filters, onFilterChange, onToggleFilter, onReset
<button
type="button"
onClick={() => setShowDropdown(!showDropdown)}
className="px-3 py-2 border-l border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
className="px-3 py-2 border-l border-gray-300 text-gray-500 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
>
<svg className="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
fill="currentColor">
@@ -160,7 +160,7 @@ export function ProfileFilters({filters, onFilterChange, onToggleFilter, onReset
{(showDropdown) && (
<div
className="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
className="absolute z-10 mt-1 w-full dark:bg-gray-900 shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
{/* Filtered interests */}
{allInterests
.filter(interest =>
@@ -169,7 +169,7 @@ export function ProfileFilters({filters, onFilterChange, onToggleFilter, onReset
.map((interest) => (
<div
key={interest.id}
className="text-gray-900 cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
className=" dark:text-white cursor-default select-none relative py-2 pl-3 pr-9 hover:bg-blue-50"
onClick={() => {
onToggleFilter('interests', interest.name);
toggleInterest(interest.id);

View File

@@ -13,7 +13,6 @@ export default function Post() {
const {id} = useParams();
const [user, setUser] = useState<ProfileData | null>(null);
const [image, setImage] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchImage() {
@@ -37,13 +36,13 @@ export default function Post() {
return (
<div className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<article className="max-w-3xl mx-auto bg-white shadow-lg rounded-lg overflow-hidden">
<div className="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
<article className="max-w-3xl mx-auto shadow-lg rounded-lg overflow-hidden">
{/* Profile Header with Image */}
<div className="bg-gradient-to-r h-16 relative">
{image ? (
<div className="absolute -bottom-16 left-8">
<div className="h-32 w-32 rounded-full border-4 border-white overflow-hidden bg-white">
<div className="h-32 w-32 rounded-full border-4 border-white overflow-hidden ">
<Image
src={image}
alt={user.name || 'Profile picture'}
@@ -70,7 +69,7 @@ export default function Post() {
{/* Profile Content */}
<div className="pt-20 px-8 pb-8">
<h1 className="text-3xl font-bold text-gray-900 mb-2">
<h1 className="text-3xl font-bold mb-2">
{user.name}
</h1>

View File

@@ -2,7 +2,6 @@
import Link from "next/link";
import {useCallback, useEffect, useState} from "react";
import {useDebounce} from "use-debounce";
import LoadingSpinner from "@/lib/client/LoadingSpinner";
import {ProfileData} from "@/lib/client/schema";
import {ProfileFilters} from "./ProfileFilters";
@@ -76,9 +75,9 @@ export default function ProfilePage() {
};
return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen flex flex-col items-center py-12 px-4 sm:px-6 lg:px-8">
<div className="w-full max-w-6xl">
<h1 className="text-4xl sm:text-5xl font-extrabold mb-8 text-gray-900">Profiles</h1>
<h1 className="text-4xl sm:text-5xl font-extrabold mb-8">Profiles</h1>
<ProfileFilters
filters={filters}
@@ -97,14 +96,14 @@ export default function ProfilePage() {
profiles.map((user) => (
<Link key={user.id} href={`/profiles/${user.id}`} className="group">
<div
className="border rounded-lg shadow-sm bg-white p-6 hover:shadow-md transition-shadow duration-300 h-full">
className="border rounded-lg shadow-sm p-6 hover:shadow-md transition-shadow duration-300 h-full">
<div className="flex items-start space-x-4">
<div className="flex-1">
<h2 className="text-xl font-semibold text-gray-900 group-hover:underline mb-1">
<h2 className="text-xl font-semibold group-hover:underline mb-1">
{user.name}
</h2>
{user?.profile?.description && (
<p className="text-sm text-gray-600 line-clamp-2">
<p className="text-sm line-clamp-2">
{user.profile.description}
</p>
)}
@@ -140,7 +139,7 @@ export default function ProfilePage() {
) : (
<div className="col-span-full text-center py-12">
<svg
className="mx-auto h-12 w-12 text-gray-400"
className="mx-auto h-12 w-12"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
@@ -154,8 +153,8 @@ export default function ProfilePage() {
d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<h3 className="mt-2 text-sm font-medium text-gray-900">No profiles found</h3>
<p className="mt-1 text-sm text-gray-500">
<h3 className="mt-2 text-sm font-medium">No profiles found</h3>
<p className="mt-1 text-sm ">
Try adjusting your search or filter to find what you're looking for.
</p>
</div>

View File

@@ -1,7 +1,10 @@
"use client";
import { SessionProvider } from "next-auth/react";
import {SessionProvider} from "next-auth/react";
import {ThemeProvider} from 'next-themes';
export default function Providers({ children }: { children: React.ReactNode }) {
return <SessionProvider>{children}</SessionProvider>;
return <SessionProvider><ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>;</SessionProvider>;
}

View File

@@ -94,7 +94,7 @@ function RegisterComponent() {
}
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
{registrationSuccess ? (
<div className="text-center">
@@ -113,7 +113,7 @@ function RegisterComponent() {
/>
</svg>
</div>
<h2 className="mt-6 text-3xl font-extrabold text-gray-900">
<h2 className="mt-6 text-3xl font-extrabold ">
Check your email
</h2>
<p className="mt-2 text-sm text-gray-600">
@@ -134,7 +134,7 @@ function RegisterComponent() {
<div className="mt-6">
<Link
href="/login"
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
>
Back to Login
</Link>
@@ -148,7 +148,7 @@ function RegisterComponent() {
may be deleted at any time. To get release updates, fill in this <a
href='https://forms.gle/tKnXUMAbEreMK6FC6'>form</a>.
</h2>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
<h2 className="mt-6 text-center text-3xl font-extrabold ">
Create your account
</h2>
</div>
@@ -163,7 +163,7 @@ function RegisterComponent() {
name="name"
type="text"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Full name"
/>
</div>
@@ -176,7 +176,7 @@ function RegisterComponent() {
name="email"
type="email"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Email address"
/>
</div>
@@ -189,7 +189,7 @@ function RegisterComponent() {
name="password"
type="password"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="Password"
/>
</div>
@@ -226,7 +226,7 @@ function RegisterComponent() {
<div className="w-full border-t border-gray-300"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="px-2 bg-gray-50 text-gray-500">Or sign up with</span>
<span className="px-2 text-gray-500">Or sign up with</span>
</div>
</div>
@@ -234,7 +234,7 @@ function RegisterComponent() {
type="button"
onClick={handleGoogleSignUp}
disabled={isLoading}
className="w-full flex items-center justify-center gap-2 py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-70 disabled:cursor-not-allowed"
className="w-full flex items-center justify-center gap-2 py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover: focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-70 disabled:cursor-not-allowed"
>
<FcGoogle className="w-5 h-5"/>
Continue with Google

View File

@@ -2,9 +2,9 @@ import SetupInstructions from "./setup-instructions";
export default function SetupPage() {
return (
<div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center p-8">
<div className="max-w-3xl w-full bg-white rounded-lg shadow-lg p-8">
<h1 className="text-3xl font-bold text-center mb-6 text-gray-900">
<div className="min-h-screen flex flex-col items-center justify-center p-8">
<div className="max-w-3xl w-full rounded-lg shadow-lg p-8">
<h1 className="text-3xl font-bold text-center mb-6 ">
Welcome to BayesBond
</h1>
<p className="text-gray-600 mb-8 text-center">

View File

@@ -1,9 +1,9 @@
export default function TermsPage() {
return (
<main className="max-w-4xl mx-auto p-8 text-gray-800">
<main className="max-w-4xl mx-auto p-8 text-gray-800 dark:text-white">
<h1 className="text-3xl font-semibold text-center mb-6">Terms & Conditions</h1>
<p className="text-center text-gray-500 mb-12">
<p className="text-center text-gray-500 dark:text-white mb-12">
Effective Date: January 1, 2025
</p>

View File

@@ -2,7 +2,7 @@ import React from "react";
export default function LoadingSpinner() {
return (
<div className="flex items-center justify-center min-h-screen bg-white">
<div className="flex items-center justify-center min-h-screen ">
<div className="w-12 h-12 border-4 border-gray-300 border-t-gray-800 rounded-full animate-spin" />
</div>
);

32
lib/client/theme.tsx Normal file
View File

@@ -0,0 +1,32 @@
'use client';
import {useTheme} from 'next-themes';
import {useEffect, useState} from 'react';
export default function ThemeToggle() {
const {theme, setTheme} = useTheme();
const [mounted, setMounted] = useState(false);
// Fix hydration mismatch
useEffect(() => setMounted(true), []);
if (!mounted) return null;
const isDark = theme === 'dark';
return (
<button
onClick={() => setTheme(isDark ? 'light' : 'dark')}
className={`relative inline-flex h-6 w-12 items-center rounded-full transition-colors duration-300 ${
isDark ? 'bg-gray-300' : 'bg-gray-700'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-gray-200 transition-transform duration-300 ${
isDark ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
);
}

11
package-lock.json generated
View File

@@ -23,6 +23,7 @@
"lucide-react": "^0.503.0",
"next": "^15.4.4",
"next-auth": "^4.24.11",
"next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.0.0",
"react-icons": "^5.5.0",
@@ -7309,6 +7310,16 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/next-themes": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
"integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",

View File

@@ -24,6 +24,7 @@
"lucide-react": "^0.503.0",
"next": "^15.4.4",
"next-auth": "^4.24.11",
"next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.0.0",
"react-icons": "^5.5.0",

3
styles/links.modules.css Normal file
View File

@@ -0,0 +1,3 @@
a {
color: cornflowerblue;
}

View File

@@ -14,5 +14,6 @@ export default {
},
},
},
darkMode: 'class', // required for next-themes
plugins: [ ],
} satisfies Config;