11 Commits

Author SHA1 Message Date
933880d830 Add src/hooks/useAuth.ts 2026-03-07 00:41:22 +00:00
0906646855 Update src/app/upload/page.tsx 2026-03-07 00:41:22 +00:00
6f56cbc2b2 Add src/app/signup/page.tsx 2026-03-07 00:41:21 +00:00
6cea95adad Update src/app/page.tsx 2026-03-07 00:41:21 +00:00
d4d784344d Add src/app/login/page.tsx 2026-03-07 00:41:20 +00:00
02b638d722 Update src/app/gallery/page.tsx 2026-03-07 00:41:19 +00:00
a12b220feb Add src/app/contact/page.tsx 2026-03-07 00:41:19 +00:00
7d34b861d5 Merge version_2 into main
Merge version_2 into main
2026-03-07 00:28:47 +00:00
742fc9738b Update src/app/page.tsx 2026-03-07 00:28:43 +00:00
41276b5e00 Update src/app/layout.tsx 2026-03-07 00:28:43 +00:00
afeb9be483 Merge version_1 into main
Merge version_1 into main
2026-03-07 00:26:35 +00:00
8 changed files with 716 additions and 625 deletions

136
src/app/contact/page.tsx Normal file
View File

@@ -0,0 +1,136 @@
"use client";
import { MessageCircle } from "lucide-react";
import Input from "@/components/form/Input";
import { useState } from "react";
import { Loader } from "lucide-react";
export default function ContactPage() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [loading, setLoading] = useState(false);
const [submitted, setSubmitted] = useState(false);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setLoading(true);
try {
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 1000));
setSubmitted(true);
setName("");
setEmail("");
setMessage("");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen bg-background">
<div className="max-w-2xl mx-auto px-4 py-12">
<div className="text-center mb-12">
<MessageCircle className="w-12 h-12 text-primary-cta mx-auto mb-4" />
<h1 className="text-4xl font-bold text-foreground mb-2">Get in Touch</h1>
<p className="text-foreground/75">Have a question? We'd love to hear from you.</p>
</div>
<div className="bg-card rounded-lg p-8">
{submitted ? (
<div className="text-center py-8">
<div className="mb-4 text-green-500">
<MessageCircle className="w-12 h-12 mx-auto" />
</div>
<h2 className="text-xl font-bold text-foreground mb-2">Thank you!</h2>
<p className="text-foreground/75 mb-6">We've received your message and will get back to you soon.</p>
<button
onClick={() => setSubmitted(false)}
className="text-primary-cta hover:underline font-medium"
>
Send another message
</button>
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Name
</label>
<Input
type="text"
placeholder="Your name"
value={name}
onChange={setName}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Email
</label>
<Input
type="email"
placeholder="Your email"
value={email}
onChange={setEmail}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Message
</label>
<textarea
placeholder="Your message"
value={message}
onChange={(e) => setMessage(e.target.value)}
required
rows={6}
className="w-full px-4 py-2 bg-secondary-cta text-foreground placeholder-foreground/50 rounded-lg border border-foreground/10 focus:outline-none focus:border-primary-cta transition-colors resize-none"
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-primary-cta text-white py-3 px-4 rounded-lg font-medium hover:opacity-90 transition-opacity disabled:opacity-50 flex items-center justify-center gap-2"
>
{loading ? (
<>
<Loader className="w-4 h-4 animate-spin" />
Sending...
</>
) : (
"Send Message"
)}
</button>
</form>
)}
</div>
{/* FAQ section */}
<div className="mt-12">
<h2 className="text-2xl font-bold text-foreground mb-6">Frequently Asked Questions</h2>
<div className="space-y-4">
<div className="bg-card rounded-lg p-6">
<h3 className="font-semibold text-foreground mb-2">What is your response time?</h3>
<p className="text-foreground/75">We aim to respond to all inquiries within 24 hours during business days.</p>
</div>
<div className="bg-card rounded-lg p-6">
<h3 className="font-semibold text-foreground mb-2">How can I report content?</h3>
<p className="text-foreground/75">Click the report button on any content and let us know the issue. Our team reviews all reports promptly.</p>
</div>
<div className="bg-card rounded-lg p-6">
<h3 className="font-semibold text-foreground mb-2">Do you have technical support?</h3>
<p className="text-foreground/75">Yes! Email support@mediahub.com for technical issues and we'll help you out.</p>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@@ -1,213 +1,34 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
import ProductCardTwo from "@/components/sections/product/ProductCardTwo";
import SocialProofOne from "@/components/sections/socialProof/SocialProofOne";
import FooterSimple from "@/components/sections/footer/FooterSimple";
import Link from "next/link";
import { ImageIcon } from "lucide-react";
export default function GalleryPage() {
return (
<ThemeProvider
defaultButtonVariant="hover-magnetic"
defaultTextAnimation="reveal-blur"
borderRadius="rounded"
contentWidth="compact"
sizing="medium"
background="aurora"
cardStyle="gradient-mesh"
primaryButtonStyle="flat"
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<div id="nav" data-section="nav">
<NavbarStyleFullscreen
navItems={[
{ name: "Home", id: "/" },
{ name: "Explore", id: "/gallery" },
{ name: "Upload", id: "upload" },
{ name: "Support", id: "contact" },
{ name: "Join Now", id: "#" },
]}
brandName="MediaHub"
bottomLeftText="Creative Community"
bottomRightText="support@mediahub.com"
/>
</div>
<div className="min-h-screen bg-background">
<div className="max-w-6xl mx-auto px-4 py-12">
<div className="mb-8">
<h1 className="text-4xl font-bold text-foreground mb-2">Creative Gallery</h1>
<p className="text-foreground/75">Discover amazing photos and videos from our creative community</p>
</div>
<div id="gallery" data-section="gallery">
<ProductCardTwo
title="Featured Content Gallery"
description="Discover amazing photos and videos from our creative community"
tag="Gallery"
tagIcon={ImageIcon}
products={[
{
id: "1",
brand: "Sarah Chen",
name: "Sunset Mountain Photography",
price: "4.9★",
rating: 5,
reviewCount: "2.3k",
imageSrc: "http://img.b2bpic.net/free-photo/beautiful-setting-sun-forest-mountain-landscape_181624-23715.jpg?_wi=2",
imageAlt: "sunset mountain landscape photography",
},
{
id: "2",
brand: "Alex Rodriguez",
name: "Urban Street Art",
price: "4.8★",
rating: 5,
reviewCount: "1.9k",
imageSrc: "http://img.b2bpic.net/free-photo/woman-blue-coat-street_158595-2575.jpg?_wi=2",
imageAlt: "urban street art photography city",
},
{
id: "3",
brand: "Maya Patel",
name: "Nature's Beautiful Details",
price: "4.9★",
rating: 5,
reviewCount: "3.1k",
imageSrc: "http://img.b2bpic.net/free-photo/macro-shot-anthurium-flower_23-2147836286.jpg?_wi=2",
imageAlt: "macro photography nature details close-up",
},
{
id: "4",
brand: "James Wilson",
name: "Travel Vlog Collection",
price: "4.7★",
rating: 5,
reviewCount: "2.7k",
imageSrc: "http://img.b2bpic.net/free-photo/camera-man-filming-couple-inside-transparent-bubble-tent-glamping-professional-camera_1268-24534.jpg?_wi=2",
imageAlt: "travel vlog video production cinematography",
},
{
id: "5",
brand: "Emma Thompson",
name: "Creative Animations",
price: "4.8★",
rating: 5,
reviewCount: "1.5k",
imageSrc: "http://img.b2bpic.net/free-photo/video-creator-woman-editing-music-video-dual-monitors-agency-studio_482257-119068.jpg?_wi=2",
imageAlt: "animation creative video motion graphics",
},
{
id: "6",
brand: "Lucas Kim",
name: "Design & Art Showcase",
price: "4.9★",
rating: 5,
reviewCount: "2.2k",
imageSrc: "http://img.b2bpic.net/free-vector/design-process-landing-page-concept_52683-25329.jpg?_wi=2",
imageAlt: "graphic design art illustration showcase",
},
{
id: "7",
brand: "Sophie Turner",
name: "Fashion & Lifestyle",
price: "4.8★",
rating: 5,
reviewCount: "1.8k",
imageSrc: "http://img.b2bpic.net/free-psd/fashion-magazine-template-design_23-2150583108.jpg?_wi=2",
imageAlt: "fashion magazine template design",
},
{
id: "8",
brand: "David Chen",
name: "Architecture & Design",
price: "4.9★",
rating: 5,
reviewCount: "2.4k",
imageSrc: "http://img.b2bpic.net/free-photo/three-frames-shelf_23-2147755106.jpg?_wi=2",
imageAlt: "architecture and design showcase",
},
{
id: "9",
brand: "Jessica Park",
name: "Food & Culinary",
price: "4.7★",
rating: 5,
reviewCount: "1.6k",
imageSrc: "http://img.b2bpic.net/free-photo/professional-camera-recording-cooking-show-content-with-chefs-restaurant-kitchen-filming-people-making-food-recipe-dish-with-fresh-ingredients-gastronomy-cuisine-online-class_482257-46088.jpg?_wi=2",
imageAlt: "professional camera recording cooking show",
},
]}
gridVariant="bento-grid-inverted"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
/>
{/* Gallery Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{[1, 2, 3, 4, 5, 6].map((item) => (
<div
key={item}
className="bg-card rounded-lg overflow-hidden hover:shadow-lg transition-shadow cursor-pointer group"
>
<div className="aspect-video bg-background/50 flex items-center justify-center group-hover:bg-background transition-colors">
<ImageIcon className="w-12 h-12 text-foreground/30" />
</div>
<div className="p-4">
<h3 className="font-semibold text-foreground mb-1">Featured Content</h3>
<p className="text-sm text-foreground/75">By Creative Community</p>
</div>
</div>
))}
</div>
</div>
<div id="social-proof" data-section="social-proof">
<SocialProofOne
title="Trusted by Creative Communities"
description="Join creators from around the world who share their work on MediaHub"
tag="Social Proof"
textboxLayout="default"
useInvertedBackground={false}
names={[
"Photography Studios",
"Video Production Houses",
"Design Agencies",
"Artists Collective",
"Content Creators",
"Freelance Portfolio",
"Creative Networks",
"Digital Artists",
]}
speed={40}
showCard={true}
/>
</div>
<div id="footer" data-section="footer">
<FooterSimple
columns={[
{
title: "Platform",
items: [
{ label: "Upload", href: "/upload" },
{ label: "Explore", href: "/gallery" },
{ label: "Collections", href: "#collections" },
{ label: "Trending", href: "#trending" },
],
},
{
title: "Community",
items: [
{ label: "Creators", href: "#creators" },
{ label: "Challenges", href: "#challenges" },
{ label: "Support", href: "/support" },
{ label: "Blog", href: "#blog" },
],
},
{
title: "Resources",
items: [
{ label: "Help Center", href: "#help" },
{ label: "API Docs", href: "#docs" },
{ label: "Contact", href: "mailto:support@mediahub.com" },
{ label: "Status", href: "#status" },
],
},
{
title: "Legal",
items: [
{ label: "Privacy Policy", href: "#privacy" },
{ label: "Terms of Service", href: "#terms" },
{ label: "Cookie Policy", href: "#cookies" },
{ label: "Guidelines", href: "#guidelines" },
],
},
]}
bottomLeftText="© 2025 MediaHub. All rights reserved."
bottomRightText="Made with creativity and passion"
/>
</div>
</ThemeProvider>
</div>
);
}
}

View File

@@ -7,37 +7,23 @@ import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag";
const halant = Halant({
variable: "--font-halant",
subsets: ["latin"],
variable: "--font-halant", subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
});
const inter = Inter({
variable: "--font-inter",
subsets: ["latin"],
variable: "--font-inter", subsets: ["latin"],
});
const nunito = Nunito({
variable: "--font-nunito",
subsets: ["latin"],
variable: "--font-nunito", subsets: ["latin"],
});
export const metadata: Metadata = {
title: "MediaHub - Share Creative Photos & Videos",
description: "Upload, organize, and share stunning photos and videos like Pinterest. Connect with creators worldwide in our vibrant community platform.",
keywords: "photo sharing, video platform, creative community, portfolio, content creators, media gallery",
openGraph: {
title: "MediaHub - Share Your Creative Vision",
description: "Join thousands of creators sharing beautiful photos and videos. Upload, organize, and connect with the community.",
url: "https://mediahub.com",
siteName: "MediaHub",
type: "website",
},
title: "MediaHub - Share Creative Photos & Videos", description: "Upload, organize, and share stunning photos and videos like Pinterest. Connect with creators worldwide in our vibrant community platform.", keywords: "photo sharing, video platform, creative community, portfolio, content creators, media gallery", openGraph: {
title: "MediaHub - Share Your Creative Vision", description: "Join thousands of creators sharing beautiful photos and videos. Upload, organize, and connect with the community.", url: "https://mediahub.com", siteName: "MediaHub", type: "website"},
twitter: {
card: "summary_large_image",
title: "MediaHub - Creative Media Sharing",
description: "Share your photos and videos with a vibrant creative community.",
},
card: "summary_large_image", title: "MediaHub - Creative Media Sharing", description: "Share your photos and videos with a vibrant creative community."},
};
export default function RootLayout({
@@ -1424,4 +1410,4 @@ export default function RootLayout({
</ServiceWrapper>
</html>
);
}
}

99
src/app/login/page.tsx Normal file
View File

@@ -0,0 +1,99 @@
"use client";
import { useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import Input from "@/components/form/Input";
import Link from "next/link";
import { Mail, Lock, Loader } from "lucide-react";
export default function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const { login } = useAuth();
const router = useRouter();
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError("");
setLoading(true);
try {
await login(email, password);
router.push("/");
} catch (err: any) {
setError(err.message || "Login failed. Please try again.");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-background px-4">
<div className="w-full max-w-md bg-card rounded-lg p-8 shadow-lg">
<h1 className="text-3xl font-bold text-foreground mb-2">Welcome Back</h1>
<p className="text-foreground/75 mb-6">Sign in to your MediaHub account</p>
{error && (
<div className="mb-4 p-3 bg-red-500/10 border border-red-500 rounded-lg text-red-500 text-sm">
{error}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Email Address
</label>
<Input
type="email"
placeholder="Enter your email"
value={email}
onChange={setEmail}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Password
</label>
<Input
type="password"
placeholder="Enter your password"
value={password}
onChange={setPassword}
required
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-primary-cta text-white py-2 px-4 rounded-lg font-medium hover:opacity-90 transition-opacity disabled:opacity-50 flex items-center justify-center gap-2"
>
{loading ? (
<>
<Loader className="w-4 h-4 animate-spin" />
Signing in...
</>
) : (
"Sign In"
)}
</button>
</form>
<div className="mt-6 text-center">
<p className="text-foreground/75 text-sm">
Don't have an account?{" "}
<Link href="/signup" className="text-primary-cta hover:underline font-medium">
Create one
</Link>
</p>
</div>
</div>
</div>
);
}

View File

@@ -13,8 +13,36 @@ import ContactFaq from "@/components/sections/contact/ContactFaq";
import FooterSimple from "@/components/sections/footer/FooterSimple";
import Link from "next/link";
import { Sparkles, Zap, Upload, Images, FileCheck, Grid, Smartphone, Eye, Users, MessageCircle, Heart, ImageIcon, Check, Phone } from "lucide-react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { useState } from "react";
export default function HomePage() {
const { user, logout } = useAuth();
const router = useRouter();
const [showLogoutMenu, setShowLogoutMenu] = useState(false);
const handleLogout = async () => {
await logout();
setShowLogoutMenu(false);
router.push("/");
};
const navItems = user
? [
{ name: "Home", id: "/" },
{ name: "Explore", id: "/gallery" },
{ name: "Upload", id: "/upload" },
{ name: "Support", id: "/contact" },
]
: [
{ name: "Home", id: "/" },
{ name: "Explore", id: "/gallery" },
{ name: "Upload", id: "/upload" },
{ name: "Support", id: "/contact" },
{ name: "Join Now", id: "/login" },
];
return (
<ThemeProvider
defaultButtonVariant="hover-magnetic"
@@ -30,17 +58,31 @@ export default function HomePage() {
>
<div id="nav" data-section="nav">
<NavbarStyleFullscreen
navItems={[
{ name: "Home", id: "/" },
{ name: "Explore", id: "/gallery" },
{ name: "Upload", id: "upload" },
{ name: "Support", id: "contact" },
{ name: "Join Now", id: "#" },
]}
navItems={navItems}
brandName="MediaHub"
bottomLeftText="Creative Community"
bottomRightText="support@mediahub.com"
bottomRightText={user ? `${user.email}` : "support@mediahub.com"}
/>
{user && (
<div className="fixed top-4 right-4 z-50">
<button
onClick={() => setShowLogoutMenu(!showLogoutMenu)}
className="px-4 py-2 rounded-lg bg-primary-cta text-white text-sm font-medium hover:opacity-90 transition-opacity"
>
{user.email}
</button>
{showLogoutMenu && (
<div className="absolute top-12 right-0 bg-card rounded-lg shadow-lg p-2 w-32">
<button
onClick={handleLogout}
className="w-full text-left px-4 py-2 text-sm hover:bg-background rounded transition-colors"
>
Logout
</button>
</div>
)}
</div>
)}
</div>
<div id="hero" data-section="hero">
@@ -51,7 +93,7 @@ export default function HomePage() {
tag="Creative Community"
tagIcon={Sparkles}
buttons={[
{ text: "Start Uploading", href: "/upload" },
{ text: "Upload Free Now", href: "/upload" },
{ text: "Explore Gallery", href: "/gallery" },
]}
imageSrc="http://img.b2bpic.net/free-vector/template-dashboard-user-panel_23-2148371519.jpg?_wi=1"
@@ -67,13 +109,8 @@ export default function HomePage() {
tagIcon={Zap}
features={[
{
id: "1",
title: "Easy Upload System",
description: "Upload multiple photos and videos at once with our intuitive drag-and-drop interface. Organize content into collections instantly.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/elegant-uber-driver-giving-taxi-ride_23-2149241774.jpg?_wi=1",
imageAlt: "drag drop upload interface modern",
},
id: "1", title: "Easy Upload System", description: "Upload multiple photos and videos at once with our intuitive drag-and-drop interface. Organize content into collections instantly.", media: {
imageSrc: "http://img.b2bpic.net/free-photo/elegant-uber-driver-giving-taxi-ride_23-2149241774.jpg?_wi=1", imageAlt: "drag drop upload interface modern"},
items: [
{ icon: Upload, text: "Drag & drop upload" },
{ icon: Images, text: "Batch processing" },
@@ -82,13 +119,8 @@ export default function HomePage() {
reverse: false,
},
{
id: "2",
title: "Beautiful Gallery Display",
description: "Showcase your work in stunning layouts that adapt to any device. Your portfolio looks amazing everywhere.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/three-frames-shelf_23-2147755106.jpg?_wi=1",
imageAlt: "photo gallery grid layout responsive",
},
id: "2", title: "Beautiful Gallery Display", description: "Showcase your work in stunning layouts that adapt to any device. Your portfolio looks amazing everywhere.", media: {
imageSrc: "http://img.b2bpic.net/free-photo/three-frames-shelf_23-2147755106.jpg?_wi=1", imageAlt: "photo gallery grid layout responsive"},
items: [
{ icon: Grid, text: "Dynamic layouts" },
{ icon: Smartphone, text: "Mobile responsive" },
@@ -97,13 +129,8 @@ export default function HomePage() {
reverse: true,
},
{
id: "3",
title: "Community Engagement",
description: "Connect with other creators, get feedback, and discover inspiring content. Build meaningful relationships in our vibrant community.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/company-partners-working-office_23-2148352762.jpg?_wi=1",
imageAlt: "community engagement social interaction platform",
},
id: "3", title: "Community Engagement", description: "Connect with other creators, get feedback, and discover inspiring content. Build meaningful relationships in our vibrant community.", media: {
imageSrc: "http://img.b2bpic.net/free-photo/company-partners-working-office_23-2148352762.jpg?_wi=1", imageAlt: "community engagement social interaction platform"},
items: [
{ icon: Users, text: "Creator network" },
{ icon: MessageCircle, text: "Comments & feedback" },
@@ -126,65 +153,23 @@ export default function HomePage() {
tagIcon={ImageIcon}
products={[
{
id: "1",
brand: "Sarah Chen",
name: "Sunset Mountain Photography",
price: "4.9★",
rating: 5,
reviewCount: "2.3k",
imageSrc: "http://img.b2bpic.net/free-photo/beautiful-setting-sun-forest-mountain-landscape_181624-23715.jpg?_wi=1",
imageAlt: "sunset mountain landscape photography",
},
id: "1", brand: "Sarah Chen", name: "Sunset Mountain Photography", price: "4.9★", rating: 5,
reviewCount: "2.3k", imageSrc: "http://img.b2bpic.net/free-photo/beautiful-setting-sun-forest-mountain-landscape_181624-23715.jpg?_wi=1", imageAlt: "sunset mountain landscape photography"},
{
id: "2",
brand: "Alex Rodriguez",
name: "Urban Street Art",
price: "4.8★",
rating: 5,
reviewCount: "1.9k",
imageSrc: "http://img.b2bpic.net/free-photo/woman-blue-coat-street_158595-2575.jpg?_wi=1",
imageAlt: "urban street art photography city",
},
id: "2", brand: "Alex Rodriguez", name: "Urban Street Art", price: "4.8★", rating: 5,
reviewCount: "1.9k", imageSrc: "http://img.b2bpic.net/free-photo/woman-blue-coat-street_158595-2575.jpg?_wi=1", imageAlt: "urban street art photography city"},
{
id: "3",
brand: "Maya Patel",
name: "Nature's Beautiful Details",
price: "4.9★",
rating: 5,
reviewCount: "3.1k",
imageSrc: "http://img.b2bpic.net/free-photo/macro-shot-anthurium-flower_23-2147836286.jpg?_wi=1",
imageAlt: "macro photography nature details close-up",
},
id: "3", brand: "Maya Patel", name: "Nature's Beautiful Details", price: "4.9★", rating: 5,
reviewCount: "3.1k", imageSrc: "http://img.b2bpic.net/free-photo/macro-shot-anthurium-flower_23-2147836286.jpg?_wi=1", imageAlt: "macro photography nature details close-up"},
{
id: "4",
brand: "James Wilson",
name: "Travel Vlog Collection",
price: "4.7★",
rating: 5,
reviewCount: "2.7k",
imageSrc: "http://img.b2bpic.net/free-photo/camera-man-filming-couple-inside-transparent-bubble-tent-glamping-professional-camera_1268-24534.jpg?_wi=1",
imageAlt: "travel vlog video production cinematography",
},
id: "4", brand: "James Wilson", name: "Travel Vlog Collection", price: "4.7★", rating: 5,
reviewCount: "2.7k", imageSrc: "http://img.b2bpic.net/free-photo/camera-man-filming-couple-inside-transparent-bubble-tent-glamping-professional-camera_1268-24534.jpg?_wi=1", imageAlt: "travel vlog video production cinematography"},
{
id: "5",
brand: "Emma Thompson",
name: "Creative Animations",
price: "4.8★",
rating: 5,
reviewCount: "1.5k",
imageSrc: "http://img.b2bpic.net/free-photo/video-creator-woman-editing-music-video-dual-monitors-agency-studio_482257-119068.jpg?_wi=1",
imageAlt: "animation creative video motion graphics",
},
id: "5", brand: "Emma Thompson", name: "Creative Animations", price: "4.8★", rating: 5,
reviewCount: "1.5k", imageSrc: "http://img.b2bpic.net/free-photo/video-creator-woman-editing-music-video-dual-monitors-agency-studio_482257-119068.jpg?_wi=1", imageAlt: "animation creative video motion graphics"},
{
id: "6",
brand: "Lucas Kim",
name: "Design & Art Showcase",
price: "4.9★",
rating: 5,
reviewCount: "2.2k",
imageSrc: "http://img.b2bpic.net/free-vector/design-process-landing-page-concept_52683-25329.jpg?_wi=1",
imageAlt: "graphic design art illustration showcase",
},
id: "6", brand: "Lucas Kim", name: "Design & Art Showcase", price: "4.9★", rating: 5,
reviewCount: "2.2k", imageSrc: "http://img.b2bpic.net/free-vector/design-process-landing-page-concept_52683-25329.jpg?_wi=1", imageAlt: "graphic design art illustration showcase"},
]}
gridVariant="bento-grid"
animationType="slide-up"
@@ -198,10 +183,7 @@ export default function HomePage() {
heading={[
{ type: "text", content: "Upload, Share & Connect" },
{
type: "image",
src: "http://img.b2bpic.net/free-vector/cute-influencer-talent-agency-logo-template_742173-17610.jpg",
alt: "MediaHub logo",
},
type: "image", src: "http://img.b2bpic.net/free-vector/cute-influencer-talent-agency-logo-template_742173-17610.jpg", alt: "MediaHub logo"},
{ type: "text", content: "with Creative Minds Worldwide" },
]}
buttons={[
@@ -219,77 +201,17 @@ export default function HomePage() {
tag="Testimonials"
testimonials={[
{
id: "1",
name: "Sarah Chen, Photographer",
date: "Date: 15 January 2025",
title: "This platform changed how I share my work!",
quote: "MediaHub has been incredible for my photography career. The community is supportive, the tools are intuitive, and I've gained thousands of followers in just three months. Highly recommended!",
tag: "Professional",
avatarSrc: "http://img.b2bpic.net/free-photo/blonde-businesswoman-portrait-with-copy-space_1194-633470.jpg",
avatarAlt: "female photographer portrait professional",
imageSrc: "http://img.b2bpic.net/free-psd/fashion-magazine-template-design_23-2150583108.jpg?_wi=1",
imageAlt: "photographer working studio portfolio showcase",
},
id: "1", name: "Sarah Chen, Photographer", date: "Date: 15 January 2025", title: "This platform changed how I share my work!", quote: "MediaHub has been incredible for my photography career. The community is supportive, the tools are intuitive, and I've gained thousands of followers in just three months. Highly recommended!", tag: "Professional", avatarSrc: "http://img.b2bpic.net/free-photo/blonde-businesswoman-portrait-with-copy-space_1194-633470.jpg", avatarAlt: "female photographer portrait professional", imageSrc: "http://img.b2bpic.net/free-psd/fashion-magazine-template-design_23-2150583108.jpg?_wi=1", imageAlt: "photographer working studio portfolio showcase"},
{
id: "2",
name: "Alex Rodriguez, Videographer",
date: "Date: 10 January 2025",
title: "Perfect for showcasing video content",
quote: "The video upload system is seamless and fast. My videos look stunning on the platform, and the engagement from the community is amazing. It's like having a personal studio.",
tag: "Creator",
avatarSrc: "http://img.b2bpic.net/free-photo/dark-blonde-bearded-man-crosses-his-hands-chest-posing-black-shirt_8353-1116.jpg",
avatarAlt: "male videographer portrait professional",
imageSrc: "http://img.b2bpic.net/free-photo/professional-camera-recording-cooking-show-content-with-chefs-restaurant-kitchen-filming-people-making-food-recipe-dish-with-fresh-ingredients-gastronomy-cuisine-online-class_482257-46088.jpg?_wi=1",
imageAlt: "videographer filming equipment camera setup",
},
id: "2", name: "Alex Rodriguez, Videographer", date: "Date: 10 January 2025", title: "Perfect for showcasing video content", quote: "The video upload system is seamless and fast. My videos look stunning on the platform, and the engagement from the community is amazing. It's like having a personal studio.", tag: "Creator", avatarSrc: "http://img.b2bpic.net/free-photo/dark-blonde-bearded-man-crosses-his-hands-chest-posing-black-shirt_8353-1116.jpg", avatarAlt: "male videographer portrait professional", imageSrc: "http://img.b2bpic.net/free-photo/professional-camera-recording-cooking-show-content-with-chefs-restaurant-kitchen-filming-people-making-food-recipe-dish-with-fresh-ingredients-gastronomy-cuisine-online-class_482257-46088.jpg?_wi=1", imageAlt: "videographer filming equipment camera setup"},
{
id: "3",
name: "Maya Patel, Designer",
date: "Date: 5 January 2025",
title: "Best discovery platform for designers",
quote: "I found my best clients through MediaHub. The ability to organize work into collections and get direct feedback is invaluable. The platform truly celebrates creative work.",
tag: "Designer",
avatarSrc: "http://img.b2bpic.net/free-photo/front-view-female-office-worker-black-strict-jacket-posing-with-displeased-expression-light-pink-wall_140725-58762.jpg",
avatarAlt: "female designer creative professional avatar",
imageSrc: "http://img.b2bpic.net/free-photo/side-view-man-holding-palette_23-2150170337.jpg",
imageAlt: "graphic designer at computer workspace",
},
id: "3", name: "Maya Patel, Designer", date: "Date: 5 January 2025", title: "Best discovery platform for designers", quote: "I found my best clients through MediaHub. The ability to organize work into collections and get direct feedback is invaluable. The platform truly celebrates creative work.", tag: "Designer", avatarSrc: "http://img.b2bpic.net/free-photo/front-view-female-office-worker-black-strict-jacket-posing-with-displeased-expression-light-pink-wall_140725-58762.jpg", avatarAlt: "female designer creative professional avatar", imageSrc: "http://img.b2bpic.net/free-photo/side-view-man-holding-palette_23-2150170337.jpg", imageAlt: "graphic designer at computer workspace"},
{
id: "4",
name: "James Wilson, Content Creator",
date: "Date: 22 December 2024",
title: "Community support is unmatched",
quote: "The collaborative spirit here is refreshing. I've connected with amazing creators, received constructive feedback, and grown my audience exponentially. This is the platform for serious creators.",
tag: "Influencer",
avatarSrc: "http://img.b2bpic.net/free-photo/portrait-handsome-beard-man_23-2148328561.jpg",
avatarAlt: "male content creator influencer avatar",
imageSrc: "http://img.b2bpic.net/free-photo/smiling-woman-filming-headphones-review-with-smartphone-social-media-influencer-streaming-vlog-about-headset-recommendation-with-mobile-phone-microphone-home-recording-studio_482257-37431.jpg",
imageAlt: "content creator streaming setup studio",
},
id: "4", name: "James Wilson, Content Creator", date: "Date: 22 December 2024", title: "Community support is unmatched", quote: "The collaborative spirit here is refreshing. I've connected with amazing creators, received constructive feedback, and grown my audience exponentially. This is the platform for serious creators.", tag: "Influencer", avatarSrc: "http://img.b2bpic.net/free-photo/portrait-handsome-beard-man_23-2148328561.jpg", avatarAlt: "male content creator influencer avatar", imageSrc: "http://img.b2bpic.net/free-photo/smiling-woman-filming-headphones-review-with-smartphone-social-media-influencer-streaming-vlog-about-headset-recommendation-with-mobile-phone-microphone-home-recording-studio_482257-37431.jpg", imageAlt: "content creator streaming setup studio"},
{
id: "5",
name: "Emma Thompson, Artist",
date: "Date: 18 December 2024",
title: "Simple, beautiful, and effective",
quote: "No complicated features - just a clean platform for sharing art. My portfolio looks professional, and potential clients can easily view my work. Love it!",
tag: "Artist",
avatarSrc: "http://img.b2bpic.net/free-photo/smiling-artist_23-2147781629.jpg",
avatarAlt: "female artist painter portrait avatar",
imageSrc: "http://img.b2bpic.net/free-photo/oil-paint-tubes-painting_23-2149537673.jpg",
imageAlt: "artist painting studio artwork creation",
},
id: "5", name: "Emma Thompson, Artist", date: "Date: 18 December 2024", title: "Simple, beautiful, and effective", quote: "No complicated features - just a clean platform for sharing art. My portfolio looks professional, and potential clients can easily view my work. Love it!", tag: "Artist", avatarSrc: "http://img.b2bpic.net/free-photo/smiling-artist_23-2147781629.jpg", avatarAlt: "female artist painter portrait avatar", imageSrc: "http://img.b2bpic.net/free-photo/oil-paint-tubes-painting_23-2149537673.jpg", imageAlt: "artist painting studio artwork creation"},
{
id: "6",
name: "Lucas Kim, Animator",
date: "Date: 12 December 2024",
title: "Great for animation projects",
quote: "Animations render beautifully here. The platform's algorithm surfaces quality content, which helps my work reach the right audience. Excellent experience overall!",
tag: "Animator",
avatarSrc: "http://img.b2bpic.net/free-photo/close-up-portrait-middle-aged-man-with-beard-hairstyle-dressed-elegant-blue-suit-textured-dark-background-studio_613910-19853.jpg",
avatarAlt: "male animator motion graphics professional",
imageSrc: "http://img.b2bpic.net/free-photo/woman-interacting-with-intelligent-ai-chatbot-pc-mockup-display_482257-119869.jpg",
imageAlt: "animator motion graphics computer setup",
},
id: "6", name: "Lucas Kim, Animator", date: "Date: 12 December 2024", title: "Great for animation projects", quote: "Animations render beautifully here. The platform's algorithm surfaces quality content, which helps my work reach the right audience. Excellent experience overall!", tag: "Animator", avatarSrc: "http://img.b2bpic.net/free-photo/close-up-portrait-middle-aged-man-with-beard-hairstyle-dressed-elegant-blue-suit-textured-dark-background-studio_613910-19853.jpg", avatarAlt: "male animator motion graphics professional", imageSrc: "http://img.b2bpic.net/free-photo/woman-interacting-with-intelligent-ai-chatbot-pc-mockup-display_482257-119869.jpg", imageAlt: "animator motion graphics computer setup"},
]}
textboxLayout="default"
useInvertedBackground={false}
@@ -304,15 +226,7 @@ export default function HomePage() {
textboxLayout="default"
useInvertedBackground={false}
names={[
"Photography Studios",
"Video Production Houses",
"Design Agencies",
"Artists Collective",
"Content Creators",
"Freelance Portfolio",
"Creative Networks",
"Digital Artists",
]}
"Photography Studios", "Video Production Houses", "Design Agencies", "Artists Collective", "Content Creators", "Freelance Portfolio", "Creative Networks", "Digital Artists"]}
speed={40}
showCard={true}
/>
@@ -327,41 +241,23 @@ export default function HomePage() {
imageAlt="customer support team helping client"
faqs={[
{
id: "1",
title: "How do I upload photos and videos?",
content:
"Simply navigate to the Upload section, click the upload button, and drag & drop your files or select them from your computer. You can upload multiple files at once. Supported formats include JPG, PNG, MP4, MOV, and WebM.",
},
id: "1", title: "How do I upload photos and videos?", content:
"Simply navigate to the Upload section, click the upload button, and drag & drop your files or select them from your computer. You can upload multiple files at once. Supported formats include JPG, PNG, MP4, MOV, and WebM."},
{
id: "2",
title: "What are the file size limits?",
content:
"Photos can be up to 50MB each, and videos can be up to 500MB. For larger files, consider compressing or splitting into multiple uploads. Premium members enjoy higher limits.",
},
id: "2", title: "What are the file size limits?", content:
"Photos can be up to 50MB each, and videos can be up to 500MB. For larger files, consider compressing or splitting into multiple uploads. Premium members enjoy higher limits."},
{
id: "3",
title: "Can I organize my content into collections?",
content:
"Yes! You can create unlimited collections to organize your work by project, theme, or any category you prefer. Collections help you showcase specific body of work to your audience.",
},
id: "3", title: "Can I organize my content into collections?", content:
"Yes! You can create unlimited collections to organize your work by project, theme, or any category you prefer. Collections help you showcase specific body of work to your audience."},
{
id: "4",
title: "How do I control who sees my uploads?",
content:
"Each upload can be set to public (visible to everyone), friends only, or private. You can also password-protect collections for additional privacy and control.",
},
id: "4", title: "How do I control who sees my uploads?", content:
"Each upload can be set to public (visible to everyone), friends only, or private. You can also password-protect collections for additional privacy and control."},
{
id: "5",
title: "Is there a community moderation policy?",
content:
"Yes, we maintain strict guidelines to ensure a safe and respectful community. All content is reviewed, and we encourage users to report inappropriate material. Our team responds within 24 hours.",
},
id: "5", title: "Is there a community moderation policy?", content:
"Yes, we maintain strict guidelines to ensure a safe and respectful community. All content is reviewed, and we encourage users to report inappropriate material. Our team responds within 24 hours."},
{
id: "6",
title: "Can I collaborate with other creators?",
content:
"Absolutely! You can invite other creators to contribute to shared collections, leave feedback on their work, and participate in community challenges and features.",
},
id: "6", title: "Can I collaborate with other creators?", content:
"Absolutely! You can invite other creators to contribute to shared collections, leave feedback on their work, and participate in community challenges and features."},
]}
mediaPosition="left"
mediaAnimation="slide-up"
@@ -377,38 +273,24 @@ export default function HomePage() {
ctaTitle="Get in Touch with Our Support Team"
ctaDescription="Have questions about uploads or need technical support? Our friendly team is here to help you succeed on MediaHub."
ctaButton={{
text: "Contact Support",
href: "mailto:support@mediahub.com",
}}
text: "Contact Support", href: "mailto:support@mediahub.com"}}
ctaIcon={MessageCircle}
useInvertedBackground={false}
animationType="slide-up"
accordionAnimationType="smooth"
faqs={[
{
id: "1",
title: "What is your response time for support tickets?",
content:
"We aim to respond to all support inquiries within 24 hours during business days. Priority support members receive responses within 2 hours.",
},
id: "1", title: "What is your response time for support tickets?", content:
"We aim to respond to all support inquiries within 24 hours during business days. Priority support members receive responses within 2 hours."},
{
id: "2",
title: "Do you offer API access for developers?",
content:
"Yes! We provide a comprehensive API for integrating MediaHub features into your applications. Check our developer documentation for details.",
},
id: "2", title: "Do you offer API access for developers?", content:
"Yes! We provide a comprehensive API for integrating MediaHub features into your applications. Check our developer documentation for details."},
{
id: "3",
title: "How can I report inappropriate content?",
content:
"Click the 'Report' button on any content, select the reason, and submit. Our moderation team reviews all reports and takes appropriate action.",
},
id: "3", title: "How can I report inappropriate content?", content:
"Click the 'Report' button on any content, select the reason, and submit. Our moderation team reviews all reports and takes appropriate action."},
{
id: "4",
title: "Can I delete my account and all my content?",
content:
"Yes, you can request account deletion from your settings. Your account and all associated content will be permanently deleted within 30 days.",
},
id: "4", title: "Can I delete my account and all my content?", content:
"Yes, you can request account deletion from your settings. Your account and all associated content will be permanently deleted within 30 days."},
]}
/>
</div>
@@ -417,8 +299,7 @@ export default function HomePage() {
<FooterSimple
columns={[
{
title: "Platform",
items: [
title: "Platform", items: [
{ label: "Upload", href: "/upload" },
{ label: "Explore", href: "/gallery" },
{ label: "Collections", href: "#collections" },
@@ -426,17 +307,15 @@ export default function HomePage() {
],
},
{
title: "Community",
items: [
title: "Community", items: [
{ label: "Creators", href: "#creators" },
{ label: "Challenges", href: "#challenges" },
{ label: "Support", href: "/support" },
{ label: "Support", href: "/contact" },
{ label: "Blog", href: "#blog" },
],
},
{
title: "Resources",
items: [
title: "Resources", items: [
{ label: "Help Center", href: "#help" },
{ label: "API Docs", href: "#docs" },
{ label: "Contact", href: "mailto:support@mediahub.com" },
@@ -444,8 +323,7 @@ export default function HomePage() {
],
},
{
title: "Legal",
items: [
title: "Legal", items: [
{ label: "Privacy Policy", href: "#privacy" },
{ label: "Terms of Service", href: "#terms" },
{ label: "Cookie Policy", href: "#cookies" },
@@ -459,4 +337,4 @@ export default function HomePage() {
</div>
</ThemeProvider>
);
}
}

124
src/app/signup/page.tsx Normal file
View File

@@ -0,0 +1,124 @@
"use client";
import { useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import Input from "@/components/form/Input";
import Link from "next/link";
import { Loader } from "lucide-react";
export default function SignupPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const { signup } = useAuth();
const router = useRouter();
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError("");
if (password !== confirmPassword) {
setError("Passwords do not match");
return;
}
if (password.length < 6) {
setError("Password must be at least 6 characters");
return;
}
setLoading(true);
try {
await signup(email, password);
router.push("/");
} catch (err: any) {
setError(err.message || "Signup failed. Please try again.");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-background px-4">
<div className="w-full max-w-md bg-card rounded-lg p-8 shadow-lg">
<h1 className="text-3xl font-bold text-foreground mb-2">Join MediaHub</h1>
<p className="text-foreground/75 mb-6">Create your account and start sharing</p>
{error && (
<div className="mb-4 p-3 bg-red-500/10 border border-red-500 rounded-lg text-red-500 text-sm">
{error}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Email Address
</label>
<Input
type="email"
placeholder="Enter your email"
value={email}
onChange={setEmail}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Password
</label>
<Input
type="password"
placeholder="Create a password"
value={password}
onChange={setPassword}
required
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Confirm Password
</label>
<Input
type="password"
placeholder="Confirm your password"
value={confirmPassword}
onChange={setConfirmPassword}
required
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-primary-cta text-white py-2 px-4 rounded-lg font-medium hover:opacity-90 transition-opacity disabled:opacity-50 flex items-center justify-center gap-2"
>
{loading ? (
<>
<Loader className="w-4 h-4 animate-spin" />
Creating account...
</>
) : (
"Create Account"
)}
</button>
</form>
<div className="mt-6 text-center">
<p className="text-foreground/75 text-sm">
Already have an account?{" "}
<Link href="/login" className="text-primary-cta hover:underline font-medium">
Sign in
</Link>
</p>
</div>
</div>
</div>
);
}

View File

@@ -1,183 +1,75 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
import HeroBillboard from "@/components/sections/hero/HeroBillboard";
import FeatureCardTen from "@/components/sections/feature/FeatureCardTen";
import InlineImageSplitTextAbout from "@/components/sections/about/InlineImageSplitTextAbout";
import FooterSimple from "@/components/sections/footer/FooterSimple";
import { Upload, Images, FileCheck, Zap } from "lucide-react";
import Link from "next/link";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { Upload, AlertCircle } from "lucide-react";
export default function UploadPage() {
const { user, loading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!loading && !user) {
router.push("/login?redirect=/upload");
}
}, [user, loading, router]);
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="text-center">
<div className="animate-spin mb-4">
<Upload className="w-8 h-8 text-primary-cta" />
</div>
<p className="text-foreground">Loading...</p>
</div>
</div>
);
}
if (!user) {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="max-w-md bg-card rounded-lg p-8 text-center">
<AlertCircle className="w-12 h-12 text-red-500 mx-auto mb-4" />
<h2 className="text-xl font-bold text-foreground mb-2">Sign in required</h2>
<p className="text-foreground/75">You must be logged in to upload content.</p>
</div>
</div>
);
}
return (
<ThemeProvider
defaultButtonVariant="hover-magnetic"
defaultTextAnimation="reveal-blur"
borderRadius="rounded"
contentWidth="compact"
sizing="medium"
background="aurora"
cardStyle="gradient-mesh"
primaryButtonStyle="flat"
secondaryButtonStyle="solid"
headingFontWeight="light"
>
{/* Navbar */}
<div id="nav" data-section="nav">
<NavbarStyleFullscreen
brandName="MediaHub"
navItems={[
{ name: "Home", id: "/" },
{ name: "Explore", id: "/gallery" },
{ name: "Upload", id: "/upload" },
{ name: "Support", id: "/support" },
{ name: "Join Now", id: "#" },
]}
bottomLeftText="Creative Community"
bottomRightText="support@mediahub.com"
/>
</div>
<div className="min-h-screen bg-background">
<div className="max-w-4xl mx-auto px-4 py-12">
<div className="bg-card rounded-lg p-8">
<h1 className="text-3xl font-bold text-foreground mb-2">Upload Content</h1>
<p className="text-foreground/75 mb-8">
Welcome, {user.email}! Share your creative work with the community.
</p>
{/* Hero Section */}
<div id="hero" data-section="hero">
<HeroBillboard
title="Upload Your Creative Vision with the World"
description="Share your stunning photos and videos instantly. Our intuitive upload system makes it effortless to share, organize, and showcase your best work to a thriving global community."
background={{ variant: "sparkles-gradient" }}
tag="Upload Made Easy"
tagIcon={Zap}
buttons={[
{ text: "Start Uploading Now", href: "/upload" },
{ text: "Learn More", href: "/gallery" },
]}
imageSrc="http://img.b2bpic.net/free-vector/template-dashboard-user-panel_23-2148371519.jpg?_wi=2"
imageAlt="Upload interface dashboard"
/>
</div>
{/* Drag and drop area */}
<div className="border-2 border-dashed border-foreground/20 rounded-lg p-12 text-center mb-8 hover:border-foreground/40 transition-colors cursor-pointer">
<Upload className="w-12 h-12 text-foreground/50 mx-auto mb-4" />
<h3 className="text-lg font-semibold text-foreground mb-2">Drag and drop your files</h3>
<p className="text-foreground/75 mb-4">or click to browse from your computer</p>
<p className="text-sm text-foreground/50">Supported formats: JPG, PNG, MP4, MOV, WebM</p>
</div>
{/* Features Section */}
<div id="features" data-section="features">
<FeatureCardTen
title="Seamless Upload & Organization"
description="Everything you need to upload, organize, and manage your creative content with ease"
tag="Upload Features"
tagIcon={Zap}
features={[
{
id: "1",
title: "Drag & Drop Upload System",
description: "Upload multiple photos and videos at once with our intuitive drag-and-drop interface. Batch processing saves time and keeps your workflow smooth.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/elegant-uber-driver-giving-taxi-ride_23-2149241774.jpg?_wi=2",
},
items: [
{ icon: Upload, text: "Drag & drop upload" },
{ icon: Images, text: "Batch processing" },
{ icon: FileCheck, text: "Auto-organization" },
],
reverse: false,
},
{
id: "2",
title: "Smart File Management",
description: "Automatically organize your uploads into collections. Tag, categorize, and manage your entire portfolio from one powerful dashboard.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/three-frames-shelf_23-2147755106.jpg?_wi=3",
},
items: [
{ icon: Images, text: "Auto-categorization" },
{ icon: FileCheck, text: "Smart tagging" },
{ icon: Upload, text: "Bulk operations" },
],
reverse: true,
},
{
id: "3",
title: "Quality & Format Support",
description: "Support for all major formats - JPG, PNG, MP4, MOV, WebM and more. Automatic optimization ensures your content looks perfect everywhere.",
media: {
imageSrc: "http://img.b2bpic.net/free-photo/company-partners-working-office_23-2148352762.jpg?_wi=2",
},
items: [
{ icon: FileCheck, text: "Format support" },
{ icon: Images, text: "Auto-optimization" },
{ icon: Upload, text: "Quality preservation" },
],
reverse: false,
},
]}
textboxLayout="default"
animationType="slide-up"
useInvertedBackground={false}
/>
{/* Upload info */}
<div className="bg-background rounded-lg p-6">
<h3 className="font-semibold text-foreground mb-4">Upload Tips:</h3>
<ul className="space-y-2 text-foreground/75 text-sm">
<li> Photos up to 50MB each</li>
<li> Videos up to 500MB each</li>
<li> Organize into collections for easy management</li>
<li> Set privacy controls for each upload</li>
<li> Add tags and descriptions for better discovery</li>
</ul>
</div>
</div>
</div>
{/* CTA Section */}
<div id="process" data-section="process">
<InlineImageSplitTextAbout
heading={[
{ type: "text", content: "Ready to" },
{
type: "image",
src: "http://img.b2bpic.net/free-vector/cute-influencer-talent-agency-logo-template_742173-17610.jpg",
alt: "MediaHub logo",
},
{ type: "text", content: "Share Your Work?" },
]}
buttons={[
{ text: "Begin Uploading", href: "/upload" },
{ text: "Explore Gallery", href: "/gallery" },
]}
useInvertedBackground={false}
/>
</div>
{/* Footer */}
<div id="footer" data-section="footer">
<FooterSimple
columns={[
{
title: "Platform",
items: [
{ label: "Upload", href: "/upload" },
{ label: "Explore", href: "/gallery" },
{ label: "Collections", href: "#collections" },
{ label: "Trending", href: "#trending" },
],
},
{
title: "Community",
items: [
{ label: "Creators", href: "#creators" },
{ label: "Challenges", href: "#challenges" },
{ label: "Support", href: "/support" },
{ label: "Blog", href: "#blog" },
],
},
{
title: "Resources",
items: [
{ label: "Help Center", href: "#help" },
{ label: "API Docs", href: "#docs" },
{ label: "Contact", href: "mailto:support@mediahub.com" },
{ label: "Status", href: "#status" },
],
},
{
title: "Legal",
items: [
{ label: "Privacy Policy", href: "#privacy" },
{ label: "Terms of Service", href: "#terms" },
{ label: "Cookie Policy", href: "#cookies" },
{ label: "Guidelines", href: "#guidelines" },
],
},
]}
bottomLeftText="© 2025 MediaHub. All rights reserved."
bottomRightText="Made with creativity and passion"
/>
</div>
</ThemeProvider>
</div>
);
}
}

155
src/hooks/useAuth.ts Normal file
View File

@@ -0,0 +1,155 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
interface User {
id: string;
email: string;
createdAt: string;
}
interface AuthState {
user: User | null;
loading: boolean;
error: string | null;
}
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
export function useAuth() {
const [state, setState] = useState<AuthState>({
user: null,
loading: true,
error: null,
});
const router = useRouter();
// Check session on mount
useEffect(() => {
checkSession();
}, []);
const checkSession = useCallback(async () => {
try {
const response = await fetch(`${API_BASE_URL}/api/auth/session`, {
credentials: "include"});
if (response.ok) {
const data = await response.json();
setState({
user: data.user,
loading: false,
error: null,
});
} else {
setState({
user: null,
loading: false,
error: null,
});
}
} catch (error) {
setState({
user: null,
loading: false,
error: "Failed to check session"});
}
}, []);
const login = useCallback(
async (email: string, password: string) => {
setState((prev) => ({ ...prev, loading: true, error: null }));
try {
const response = await fetch(`${API_BASE_URL}/api/auth/login`, {
method: "POST", headers: {
"Content-Type": "application/json"},
credentials: "include", body: JSON.stringify({ email, password }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "Login failed");
}
const data = await response.json();
setState({
user: data.user,
loading: false,
error: null,
});
} catch (error: any) {
setState({
user: null,
loading: false,
error: error.message || "Login failed"});
throw error;
}
},
[]
);
const signup = useCallback(
async (email: string, password: string) => {
setState((prev) => ({ ...prev, loading: true, error: null }));
try {
const response = await fetch(`${API_BASE_URL}/api/auth/signup`, {
method: "POST", headers: {
"Content-Type": "application/json"},
credentials: "include", body: JSON.stringify({ email, password }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "Signup failed");
}
const data = await response.json();
setState({
user: data.user,
loading: false,
error: null,
});
} catch (error: any) {
setState({
user: null,
loading: false,
error: error.message || "Signup failed"});
throw error;
}
},
[]
);
const logout = useCallback(async () => {
setState((prev) => ({ ...prev, loading: true }));
try {
await fetch(`${API_BASE_URL}/api/auth/logout`, {
method: "POST", credentials: "include"});
setState({
user: null,
loading: false,
error: null,
});
} catch (error: any) {
setState({
user: null,
loading: false,
error: error.message || "Logout failed"});
}
}, []);
return {
user: state.user,
loading: state.loading,
error: state.error,
login,
signup,
logout,
checkSession,
};
}