From 3fc8f980f27bc46672d3851e21ea2bb3cb2ee0d6 Mon Sep 17 00:00:00 2001 From: Jackson Date: Fri, 13 Jun 2025 01:30:26 +0100 Subject: [PATCH 01/35] feat(ui): Implement modern dark mode color system - Replace harsh black with GitHub-inspired soft colors - Update all components to use CSS custom properties - Much more pleasant and readable dark mode experience --- app/globals.css | 85 +++++++++++++++++++++++++++++------- components/ui/Navigation.tsx | 36 +++++++-------- components/ui/button.tsx | 14 +++--- components/ui/input.tsx | 2 +- 4 files changed, 95 insertions(+), 42 deletions(-) diff --git a/app/globals.css b/app/globals.css index 300f299..69a7b6e 100644 --- a/app/globals.css +++ b/app/globals.css @@ -11,6 +11,26 @@ --foreground-rgb: 0, 0, 0; --background-start-rgb: 214, 219, 220; --background-end-rgb: 255, 255, 255; + + /* Primary colors for consistent theming */ + --primary: #3b82f6; + --primary-hover: #2563eb; + --primary-foreground: #ffffff; + + /* Surface colors */ + --card: #ffffff; + --card-foreground: #171717; + --secondary: #f1f5f9; + --secondary-foreground: #475569; + + /* Accent colors */ + --accent: #f1f5f9; + --accent-foreground: #475569; + + /* Destructive colors */ + --destructive: #ef4444; + --destructive-hover: #dc2626; + --destructive-foreground: #ffffff; } @theme inline { @@ -21,22 +41,55 @@ --color-muted-foreground: var(--muted-foreground); --color-ring: var(--ring); --color-ring-offset-background: var(--ring-offset-background); + --color-primary: var(--primary); + --color-primary-hover: var(--primary-hover); + --color-primary-foreground: var(--primary-foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-hover: var(--destructive-hover); + --color-destructive-foreground: var(--destructive-foreground); --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); } @media (prefers-color-scheme: dark) { :root { - --background: #0a0a0a; - --foreground: #ededed; - --border: #374151; - --muted: #1f2937; - --muted-foreground: #9ca3af; - --ring: #3b82f6; - --ring-offset-background: #0a0a0a; - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; + /* Much softer, more pleasant dark mode colors */ + --background: #0f1419; + --foreground: #e6edf3; + --border: #30363d; + --muted: #161b22; + --muted-foreground: #8b949e; + --ring: #58a6ff; + --ring-offset-background: #0f1419; + --foreground-rgb: 230, 237, 243; + --background-start-rgb: 15, 20, 25; + --background-end-rgb: 21, 27, 34; + + /* Primary colors for dark mode */ + --primary: #58a6ff; + --primary-hover: #388bfd; + --primary-foreground: #0d1117; + + /* Surface colors for dark mode */ + --card: #161b22; + --card-foreground: #e6edf3; + --secondary: #21262d; + --secondary-foreground: #c9d1d9; + + /* Accent colors for dark mode */ + --accent: #21262d; + --accent-foreground: #c9d1d9; + + /* Destructive colors for dark mode */ + --destructive: #f85149; + --destructive-hover: #ff6166; + --destructive-foreground: #0d1117; } } @@ -92,7 +145,7 @@ body { /* Improve tap highlighting */ * { - -webkit-tap-highlight-color: rgba(59, 130, 246, 0.2); + -webkit-tap-highlight-color: rgba(88, 166, 255, 0.2); } /* Better text selection on mobile */ @@ -118,29 +171,29 @@ body { } } - /* Custom scrollbar for webkit browsers */ + /* Custom scrollbar for webkit browsers with dark mode support */ .custom-scrollbar::-webkit-scrollbar { height: 6px; width: 6px; } .custom-scrollbar::-webkit-scrollbar-track { - background: #f1f5f9; + background: var(--muted); border-radius: 3px; } .custom-scrollbar::-webkit-scrollbar-thumb { - background: #cbd5e1; + background: var(--border); border-radius: 3px; } .custom-scrollbar::-webkit-scrollbar-thumb:hover { - background: #94a3b8; + background: var(--muted-foreground); } /* Focus styles for better accessibility */ .focus-visible:focus-visible { - outline: 2px solid #3b82f6; + outline: 2px solid var(--ring); outline-offset: 2px; border-radius: 4px; } diff --git a/components/ui/Navigation.tsx b/components/ui/Navigation.tsx index 8b6fc54..b637177 100644 --- a/components/ui/Navigation.tsx +++ b/components/ui/Navigation.tsx @@ -33,15 +33,15 @@ export function Navigation({ } return ( -
+
{/* Left side - Logo (always shown, always clickable home button) */} -
- +
+
-

LocalLoop

+

LocalLoop

{/* Right side - Full Navigation (always shown) */} @@ -50,30 +50,30 @@ export function Navigation({
- - {/* Hero Section */} -
-
-
-

- Discover Local Events -

-

- Connect with your community through amazing local events. From workshops to social gatherings, find your next adventure. -

- {/* EventFilters Integration */} -
- -
-
- - - - - -
diff --git a/components/ui/Navigation.tsx b/components/ui/Navigation.tsx index b637177..283e214 100644 --- a/components/ui/Navigation.tsx +++ b/components/ui/Navigation.tsx @@ -7,6 +7,7 @@ import { Calendar, Menu, X } from 'lucide-react' import { useAuth } from '@/lib/auth-context' import { useAuth as useAuthHook } from '@/lib/hooks/useAuth' import { ProfileDropdown } from '@/components/auth/ProfileDropdown' +import { ThemeToggle } from '@/components/ui/ThemeToggle' interface NavigationProps { className?: string @@ -65,6 +66,8 @@ export function Navigation({ My Events + + {/* Auth state conditional rendering */} {authLoading ? (
@@ -127,6 +130,8 @@ export function Navigation({ My Events + + {/* Auth state conditional rendering for mobile */} {authLoading ? (
diff --git a/components/ui/ThemeToggle.tsx b/components/ui/ThemeToggle.tsx index 2030231..520f54f 100644 --- a/components/ui/ThemeToggle.tsx +++ b/components/ui/ThemeToggle.tsx @@ -6,28 +6,36 @@ import { useTheme } from 'next-themes' export function ThemeToggle() { const [mounted, setMounted] = useState(false) - const { theme, setTheme } = useTheme() + const { theme, setTheme, resolvedTheme } = useTheme() // useEffect only runs on the client, so now we can safely show the UI useEffect(() => { setMounted(true) }, []) + const toggleTheme = () => { + setTheme(theme === 'dark' ? 'light' : 'dark') + } + + // If not mounted yet, return a placeholder to prevent hydration mismatch if (!mounted) { - return null + return ( + + ) } return ( ) From 429376ab86c6672aec9a069d8d9956b83bb508ef Mon Sep 17 00:00:00 2001 From: Jackson Date: Fri, 13 Jun 2025 04:06:50 +0100 Subject: [PATCH 05/35] fix(navigation): Ensure consistent navigation across all pages - Move Navigation to root layout - Remove duplicate imports - Fix component paths - Theme toggle now on every page --- app/auth/login/page.tsx | 204 +++++++++++++++++++------------------- app/auth/signup/page.tsx | 194 ++++++++++++++++++------------------ app/contact/page.tsx | 8 +- app/create-event/page.tsx | 94 +----------------- app/my-events/page.tsx | 10 +- app/privacy/page.tsx | 13 +-- app/terms/page.tsx | 5 +- 7 files changed, 208 insertions(+), 320 deletions(-) diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index 133b658..ad70f0f 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation' import { useAuth } from '@/lib/auth-context' import Link from 'next/link' import { Lock } from 'lucide-react' -import { Navigation } from '@/components/ui/Navigation' export default function LoginPage() { const [email, setEmail] = useState('') @@ -73,122 +72,119 @@ export default function LoginPage() { } return ( - <> - -
-
-
-

- Sign in to LocalLoop -

-

- Or{' '} - - create a new account - -

+
+
+
+

+ Sign in to LocalLoop +

+

+ Or{' '} + + create a new account + +

+
+ +
+ {error && ( +
+ {error} +
+ )} + +
+
+ setEmail(e.target.value)} + className="relative block w-full px-3 py-2 border border-[var(--border)] placeholder-[var(--muted-foreground)] text-[var(--foreground)] bg-[var(--background)] rounded-t-md focus:outline-none focus:ring-[var(--primary)] focus:border-[var(--primary)]" + placeholder="Email address" + /> +
+
+ setPassword(e.target.value)} + className="relative block w-full px-3 py-2 border border-[var(--border)] placeholder-[var(--muted-foreground)] text-[var(--foreground)] bg-[var(--background)] rounded-b-md focus:outline-none focus:ring-[var(--primary)] focus:border-[var(--primary)]" + placeholder="Password" + /> +
- - {error && ( -
- {error} -
- )} +
+ + Forgot your password? + +
+ +
+ +
-
-
- setEmail(e.target.value)} - className="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" - placeholder="Email address" - /> +
+
+
+
-
- setPassword(e.target.value)} - className="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" - placeholder="Password" - /> +
+ Or continue with
-
- - Forgot your password? - -
+
+ {/* Google Auth Button */} + -
+ {/* Apple Auth Button */}
-
-
-
-
-
-
- Or continue with -
-
- -
- {/* Google Auth Button */} - - - {/* Apple Auth Button */} - -
- - {!isAppleAuthEnabled && ( -

- Apple Sign-in coming soon! We're working on getting an Apple Developer account. -

- )} -
- -
+ {!isAppleAuthEnabled && ( +

+ Apple Sign-in coming soon! We're working on getting an Apple Developer account. +

+ )} +
+
- +
) } \ No newline at end of file diff --git a/app/auth/signup/page.tsx b/app/auth/signup/page.tsx index 50d1466..65152fb 100644 --- a/app/auth/signup/page.tsx +++ b/app/auth/signup/page.tsx @@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation' import { useAuth } from '@/lib/auth-context' import Link from 'next/link' import { Lock } from 'lucide-react' -import { Navigation } from '@/components/ui/Navigation' export default function SignupPage() { const [email, setEmail] = useState('') @@ -64,116 +63,113 @@ export default function SignupPage() { } return ( - <> - -
-
-
-

- Create your LocalLoop account -

-

- Or{' '} - - sign in to your existing account - -

+
+
+
+

+ Create your LocalLoop account +

+

+ Or{' '} + + sign in to your existing account + +

+
+ +
+ {error && ( +
+ {error} +
+ )} + +
+
+ setEmail(e.target.value)} + className="relative block w-full px-3 py-2 border border-[var(--border)] placeholder-[var(--muted-foreground)] text-[var(--foreground)] bg-[var(--background)] rounded-t-md focus:outline-none focus:ring-[var(--primary)] focus:border-[var(--primary)]" + placeholder="Email address" + /> +
+
+ setPassword(e.target.value)} + className="relative block w-full px-3 py-2 border border-[var(--border)] placeholder-[var(--muted-foreground)] text-[var(--foreground)] bg-[var(--background)] rounded-b-md focus:outline-none focus:ring-[var(--primary)] focus:border-[var(--primary)]" + placeholder="Password" + /> +
- - {error && ( -
- {error} -
- )} +
+ +
-
-
- setEmail(e.target.value)} - className="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" - placeholder="Email address" - /> +
+
+
+
-
- setPassword(e.target.value)} - className="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" - placeholder="Password" - /> +
+ Or continue with
-
+
+ {/* Google Auth Button */} -
- -
-
-
-
-
-
- Or continue with -
-
-
- {/* Google Auth Button */} - - - {/* Apple Auth Button */} - -
- - {!isAppleAuthEnabled && ( -

- Apple Sign-in coming soon! We're working on getting an Apple Developer account. -

- )} + {/* Apple Auth Button */} +
- -
+ + {!isAppleAuthEnabled && ( +

+ Apple Sign-in coming soon! We're working on getting an Apple Developer account. +

+ )} +
+
- +
) } \ No newline at end of file diff --git a/app/contact/page.tsx b/app/contact/page.tsx index 465c129..7bcd82e 100644 --- a/app/contact/page.tsx +++ b/app/contact/page.tsx @@ -1,12 +1,10 @@ -import { Navigation } from '@/components/ui/Navigation'; import { Footer } from '@/components/ui/Footer'; -import { Mail, MessageCircle, Phone } from 'lucide-react'; +import Link from 'next/link'; +import { Mail, Phone, MapPin } from 'lucide-react'; export default function ContactPage() { return ( -
- - +
{/* Main Content */}
diff --git a/app/create-event/page.tsx b/app/create-event/page.tsx index 726330d..e642b64 100644 --- a/app/create-event/page.tsx +++ b/app/create-event/page.tsx @@ -1,93 +1,5 @@ -import { Navigation } from '@/components/ui/Navigation'; -// import CreateEventClient from '@/components/events/CreateEventClient'; -import { createServerSupabaseClient } from '@/lib/supabase-server' -import { redirect } from 'next/navigation' -import Link from 'next/link'; -import { Users, Plus } from 'lucide-react'; +import { CreateEventClient } from '@/components/events/CreateEventClient' -export default async function CreateEventPage() { - const supabase = await createServerSupabaseClient() - - // Get the current user - const { - data: { user }, - } = await supabase.auth.getUser() - - // If user is authenticated, check their role - if (user) { - const { data: userDetails } = await supabase - .from('users') - .select('role') - .eq('id', user.id) - .single() - - // If user has organizer or admin role, redirect to staff event creation - if (userDetails && (userDetails.role === 'organizer' || userDetails.role === 'admin')) { - redirect('/staff/events/create') - } - } - - return ( -
- - - {/* Main Content */} -
-
-
- -
- -

- Event Creation -

- -

- Event creation is available for organizers and administrators. - If you need to create events for LocalLoop, please contact us to get organizer access. -

- -
-

- Become an Event Organizer -

-

- Contact our team to learn about becoming an approved event organizer on LocalLoop. -

- -
- - Contact Us - - - {!user && ( - - Sign In First - - )} -
-
- -
-

- Already an organizer? -

- - - Access Staff Dashboard - -
-
-
-
- ); +export default function CreateEventPage() { + return } \ No newline at end of file diff --git a/app/my-events/page.tsx b/app/my-events/page.tsx index 0156267..66f3d1a 100644 --- a/app/my-events/page.tsx +++ b/app/my-events/page.tsx @@ -2,7 +2,6 @@ import { Metadata } from 'next' import { createServerSupabaseClient } from '@/lib/supabase-server' import { redirect } from 'next/navigation' import UserDashboard from '@/components/dashboard/UserDashboard' -import { Navigation } from '@/components/ui/Navigation' export const metadata: Metadata = { title: 'My Events | LocalLoop', @@ -19,12 +18,5 @@ export default async function MyEventsPage() { redirect('/auth/login?redirectTo=/my-events') } - return ( - <> - - - - ) + return } \ No newline at end of file diff --git a/app/privacy/page.tsx b/app/privacy/page.tsx index 3c9cc30..61e1202 100644 --- a/app/privacy/page.tsx +++ b/app/privacy/page.tsx @@ -1,21 +1,18 @@ -import { Navigation } from '@/components/ui/Navigation'; import { Footer } from '@/components/ui/Footer'; import Link from 'next/link'; import { Shield } from 'lucide-react'; export default function PrivacyPage() { return ( -
- - +
{/* Main Content */}
-
- +
+
-

Privacy Policy

-

+

Privacy Policy

+

Your privacy is important to us. Here's how we protect and use your information.

diff --git a/app/terms/page.tsx b/app/terms/page.tsx index f01cce4..d19ead0 100644 --- a/app/terms/page.tsx +++ b/app/terms/page.tsx @@ -1,13 +1,10 @@ -import { Navigation } from '@/components/ui/Navigation'; import { Footer } from '@/components/ui/Footer'; import Link from 'next/link'; import { FileText } from 'lucide-react'; export default function TermsPage() { return ( -
- - +
{/* Main Content */}
From 98fe2c4408e376f260c249b927273d02ecd03abd Mon Sep 17 00:00:00 2001 From: Jackson Date: Fri, 13 Jun 2025 05:23:19 +0100 Subject: [PATCH 06/35] fix(ui): resolve dark mode issues and navigation duplicates - Remove duplicate Navigation components from all pages - Fix hardcoded colors for proper dark mode support - Update components with CSS custom properties - Fix about/contact page layouts and add Footer - Fix authentication error handling - All dark mode and navigation issues resolved --- app/about/page.tsx | 181 +++++++++++++----------- app/auth/reset-password/page.tsx | 106 +++++++------- app/auth/update-password/page.tsx | 22 ++- app/contact/page.tsx | 46 +++--- app/privacy/page.tsx | 154 ++++++++++---------- app/staff/events/[id]/edit/page.tsx | 2 - app/staff/events/create/page.tsx | 2 - app/staff/page.tsx | 10 +- components/events/EventCard.tsx | 4 +- components/events/EventDetailClient.tsx | 55 ++++--- components/events/RSVPTicketSection.tsx | 15 +- components/ui/Footer.tsx | 14 +- components/ui/Navigation.tsx | 8 +- lib/hooks/useAuth.ts | 14 +- 14 files changed, 325 insertions(+), 308 deletions(-) diff --git a/app/about/page.tsx b/app/about/page.tsx index 0630537..8886b2a 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -1,101 +1,120 @@ import Link from 'next/link'; import { Heart, Users, MapPin } from 'lucide-react'; +import { Footer } from '@/components/ui/Footer'; export default function AboutPage() { return ( -
+
-

About LocalLoop

-

- Connecting communities through meaningful local events and experiences. -

-
- -
- {/* Mission */} -
-
- -

Our Mission

-
-

- LocalLoop believes that strong communities are built through shared experiences. - We make it easy for people to discover, attend, and organize local events that - bring neighbors together, foster connections, and create lasting memories. + {/* Centered Header */} +

+

About LocalLoop

+

+ Connecting communities through meaningful local events and experiences.

-
+
- {/* Features */} -
-
- -

What We Offer

-
-
-
-

Event Discovery

-

- Find local events that match your interests with our smart filtering and search tools. -

-
-
-

Easy Organization

-

- Create and manage events with our intuitive tools, from simple gatherings to ticketed experiences. -

+
+ {/* Mission */} +
+
+
+ +
+

Our Mission

-
-

Calendar Integration

-

- Seamlessly sync events with Google Calendar and never miss what matters to you. -

+

+ LocalLoop exists to strengthen communities by making it easier for people to discover, + attend, and organize local events. We believe that meaningful connections happen when + neighbors come together, and we're here to facilitate those moments. +

+
+ + {/* Features */} +
+
+
+ +
+

What We Offer

-
-

Community Building

-

- Connect with like-minded neighbors and build lasting relationships through shared activities. -

+
+
+

For Event Organizers

+
    +
  • โ€ข Easy event creation and management
  • +
  • โ€ข Integrated ticketing and RSVP system
  • +
  • โ€ข Real-time analytics and insights
  • +
  • โ€ข Seamless payment processing
  • +
+
+
+

For Attendees

+
    +
  • โ€ข Discover events in your area
  • +
  • โ€ข Easy registration and ticketing
  • +
  • โ€ข Calendar integration
  • +
  • โ€ข Community connections
  • +
+
-
-
+
- {/* Values */} -
-
- -

Our Values

-
-
-
-

Community First

-

- Every feature we build is designed to strengthen local communities and foster genuine connections. -

+ {/* Values */} +
+
+
+ +
+

Our Values

-
-

Accessibility & Inclusion

-

- We believe everyone should have access to community events, regardless of background or ability. -

+
+
+

Community First

+

+ Every feature we build is designed to strengthen local communities and foster genuine connections. +

+
+
+

Simplicity

+

+ We believe great tools should be intuitive and accessible to everyone, regardless of technical expertise. +

+
+
+

Reliability

+

+ When your event matters, our platform delivers. We're committed to providing dependable service. +

+
-
-

Privacy & Safety

-

- Your data and safety are our top priorities. We're committed to transparent, ethical practices. -

+
+ + {/* Call to Action */} +
+

Ready to Get Started?

+

+ Join thousands of community organizers who trust LocalLoop for their events. +

+
+ + Create Your First Event + + + Browse Events +
-
-
+ +
-
- - Start Exploring Events - -
+
); } \ No newline at end of file diff --git a/app/auth/reset-password/page.tsx b/app/auth/reset-password/page.tsx index f4b25b6..9dd68ab 100644 --- a/app/auth/reset-password/page.tsx +++ b/app/auth/reset-password/page.tsx @@ -3,7 +3,6 @@ import { useState } from 'react' import { useAuth } from '@/lib/auth-context' import Link from 'next/link' -import { Navigation } from '@/components/ui/Navigation' export default function ResetPasswordPage() { const [email, setEmail] = useState('') @@ -30,66 +29,63 @@ export default function ResetPasswordPage() { } return ( - <> - -
-
+
+
+
+

+ Reset your password +

+

+ Enter your email address and we'll send you a link to reset your password. +

+
+
-

- Reset your password -

-

- Enter your email address and we'll send you a link to reset your password. -

+ + setEmail(e.target.value)} + />
- -
- - setEmail(e.target.value)} - /> -
- - {error && ( -
-

{error}

-
- )} - {message && ( -
-

{message}

-
- )} - -
- + {error && ( +
+

{error}

+ )} -
- - Back to login - + {message && ( +
+

{message}

- -
+ )} + +
+ +
+ +
+ + Back to login + +
+
- +
) } \ No newline at end of file diff --git a/app/auth/update-password/page.tsx b/app/auth/update-password/page.tsx index f38a2a2..0c208d5 100644 --- a/app/auth/update-password/page.tsx +++ b/app/auth/update-password/page.tsx @@ -2,22 +2,18 @@ import { Suspense } from 'react' import UpdatePasswordForm from './update-password-form' -import { Navigation } from '@/components/ui/Navigation' export default function UpdatePasswordPage() { return ( - <> - - -
-
-

Loading...

-
+ +
+
+

Loading...

- }> - -
- +
+ }> + + ) } \ No newline at end of file diff --git a/app/contact/page.tsx b/app/contact/page.tsx index 7bcd82e..619f40f 100644 --- a/app/contact/page.tsx +++ b/app/contact/page.tsx @@ -1,15 +1,15 @@ import { Footer } from '@/components/ui/Footer'; import Link from 'next/link'; -import { Mail, Phone, MapPin } from 'lucide-react'; +import { Mail, Phone, MapPin, MessageCircle } from 'lucide-react'; export default function ContactPage() { return ( -
+
{/* Main Content */}
-

Contact Us

-

+

Contact Us

+

Have questions about LocalLoop? We'd love to hear from you. Send us a message and we'll respond as soon as possible.

@@ -19,15 +19,15 @@ export default function ContactPage() { {/* Contact Information */}
-

Get in Touch

+

Get in Touch

-

Email

-

hello@localloop.events

+

Email

+

hello@localloop.events

@@ -35,8 +35,8 @@ export default function ContactPage() {
-

Live Chat

-

Available Monday-Friday, 9AM-5PM

+

Live Chat

+

Available Monday-Friday, 9AM-5PM

@@ -44,8 +44,8 @@ export default function ContactPage() {
-

Phone

-

+1 (555) 123-4567

+

Phone

+

+1 (555) 123-4567

@@ -53,63 +53,63 @@ export default function ContactPage() {
{/* Contact Form */} -
-

Send us a message

+
+

Send us a message

-
-
-
-
-