Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 12674d9ded | |||
| cc83b4dd59 | |||
| d69705da5b | |||
| 6afb493534 | |||
| 535ecc204f | |||
| bc66e8e6b4 | |||
| 82d01b3134 | |||
| 14320e4102 |
@@ -1,49 +1,20 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Halant } from "next/font/google";
|
||||
import { Inter } from "next/font/google";
|
||||
import { Figtree } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { ServiceWrapper } from "@/components/ServiceWrapper";
|
||||
import Tag from "@/tag/Tag";
|
||||
|
||||
const halant = Halant({
|
||||
variable: "--font-halant", subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const figtree = Figtree({
|
||||
variable: "--font-figtree", subsets: ["latin"],
|
||||
});
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "StudyFlow - Clean Study Tracker App", description: "Track your studies with minimal design. Set goals, monitor progress, and build consistent study habits with beautiful simplicity.", keywords: "study tracker, productivity app, goal tracking, student planner, focus timer", robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
},
|
||||
openGraph: {
|
||||
title: "StudyFlow - Clean Study Tracker App", description: "Track your studies with minimal design. Set goals, monitor progress, and build consistent study habits with beautiful simplicity.", type: "website", siteName: "StudyFlow"},
|
||||
twitter: {
|
||||
card: "summary_large_image", title: "StudyFlow - Clean Study Tracker App", description: "Track your studies with minimal design. Set goals, monitor progress, and build consistent study habits with beautiful simplicity."},
|
||||
title: 'StudyFlow - Track Your Studies with Purpose',
|
||||
description: 'A clean, minimal study tracker designed for focus. Set goals, monitor progress, and build consistent study habits.',
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
}) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<ServiceWrapper>
|
||||
<body
|
||||
className={`${halant.variable} ${inter.variable} ${figtree.variable} antialiased`}
|
||||
>
|
||||
<Tag />
|
||||
{children}
|
||||
|
||||
<html lang="en">
|
||||
<body>
|
||||
{children}
|
||||
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
@@ -1411,7 +1382,6 @@ export default function RootLayout({
|
||||
}}
|
||||
/>
|
||||
</body>
|
||||
</ServiceWrapper>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
|
||||
@@ -9,7 +9,7 @@ import MetricCardTen from '@/components/sections/metrics/MetricCardTen';
|
||||
import TestimonialCardFifteen from '@/components/sections/testimonial/TestimonialCardFifteen';
|
||||
import FaqSplitText from '@/components/sections/faq/FaqSplitText';
|
||||
import FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
|
||||
import { Award, Brain, Eye, Sparkles, Target, TrendingUp, Zap } from 'lucide-react';
|
||||
import { Award, Brain, Eye, Sparkles, Target, TrendingUp, Zap, Users, Trophy, Globe } from 'lucide-react';
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
@@ -32,7 +32,8 @@ export default function LandingPage() {
|
||||
{ name: "Features", id: "features" },
|
||||
{ name: "Benefits", id: "about" },
|
||||
{ name: "Pricing", id: "metrics" },
|
||||
{ name: "FAQ", id: "faq" }
|
||||
{ name: "FAQ", id: "faq" },
|
||||
{ name: "Profile", id: "profile" }
|
||||
]}
|
||||
button={{ text: "Start Tracking", href: "#contact" }}
|
||||
animateOnLoad={true}
|
||||
@@ -131,6 +132,30 @@ export default function LandingPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="leaderboard" data-section="leaderboard">
|
||||
<MetricCardTen
|
||||
title="Global Leaderboard"
|
||||
description="Compete fairly with privacy-first leaderboards. Your rank is based on your metrics, but your personal data stays private."
|
||||
tag="Competition"
|
||||
tagIcon={Trophy}
|
||||
tagAnimation="slide-up"
|
||||
metrics={[
|
||||
{
|
||||
id: "1", title: "Your Rank", subtitle: "Monthly leaderboard position based on study consistency", category: "Personal", value: "#247"
|
||||
},
|
||||
{
|
||||
id: "2", title: "Study Streak", subtitle: "Days of consecutive study sessions maintained", category: "Achievement", value: "24 Days"
|
||||
},
|
||||
{
|
||||
id: "3", title: "Global Community", subtitle: "Anonymous students competing and studying together", category: "Community", value: "50K+"
|
||||
}
|
||||
]}
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
animationType="slide-up"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="metrics" data-section="metrics">
|
||||
<MetricCardTen
|
||||
title="Proven Results"
|
||||
@@ -174,6 +199,40 @@ export default function LandingPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="friends" data-section="friends">
|
||||
<SplitAbout
|
||||
title="Connect with Friends"
|
||||
description="Invite friends to your study circle and grow together. Share achievements, compete on leaderboards, and stay motivated as a community—all while keeping your study sessions and personal data private."
|
||||
tag="Social Features"
|
||||
tagIcon={Users}
|
||||
tagAnimation="slide-up"
|
||||
bulletPoints={[
|
||||
{
|
||||
title: "Easy Invitations", description: "Send study invitations to friends via email or shareable links. Build your private study group without exposing personal information.", icon: Sparkles
|
||||
},
|
||||
{
|
||||
title: "Friend Leaderboards", description: "Compete with your study circle on private leaderboards. Motivate each other to reach goals while keeping personal metrics visible only to trusted friends.", icon: Trophy
|
||||
},
|
||||
{
|
||||
title: "Shared Goals", description: "Create group study challenges and track collective progress. Celebrate wins together and build accountability through friendly competition.", icon: Target
|
||||
},
|
||||
{
|
||||
title: "Privacy-First Design", description: "Your detailed study data is yours alone. Friends only see metrics you choose to share. All connections are opt-in and transparent.", icon: Globe
|
||||
}
|
||||
]}
|
||||
buttons={[
|
||||
{ text: "Invite Friends", href: "#" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Aa2cXa2LmffEQPZIIbrTZKfaRM/a-minimalist-goal-setting-interface-show-1772816612158-754ad6ed.png?_wi=1"
|
||||
imageAlt="Friend Study Circle"
|
||||
mediaAnimation="slide-up"
|
||||
imagePosition="right"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="faq" data-section="faq">
|
||||
<FaqSplitText
|
||||
sideTitle="Common Questions"
|
||||
@@ -193,6 +252,15 @@ export default function LandingPage() {
|
||||
},
|
||||
{
|
||||
id: "5", title: "Can I export my study data?", content: "Yes! Premium users can export their study data as CSV or PDF reports. This is useful for tracking progress over semesters or sharing insights with teachers and tutors."
|
||||
},
|
||||
{
|
||||
id: "6", title: "How do I invite friends to StudyFlow?", content: "You can invite friends directly from your profile using email or shareable invitation links. Your friends can accept invitations to join your private study circle at their own pace."
|
||||
},
|
||||
{
|
||||
id: "7", title: "Is the leaderboard competitive?", content: "Our leaderboards are designed to motivate, not to pressure. You control what metrics are visible to your friends. Global leaderboards are anonymized, and friend leaderboards only show metrics you choose to share."
|
||||
},
|
||||
{
|
||||
id: "8", title: "How is my privacy protected?", content: "StudyFlow uses privacy-first architecture. Your detailed study sessions and personal data are encrypted and never shared without explicit consent. Friends see only the metrics you choose to share."
|
||||
}
|
||||
]}
|
||||
textPosition="left"
|
||||
@@ -212,4 +280,4 @@ export default function LandingPage() {
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
170
src/app/profile/page.tsx
Normal file
170
src/app/profile/page.tsx
Normal file
@@ -0,0 +1,170 @@
|
||||
"use client"
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
|
||||
import { User, LogOut, Settings, Award, TrendingUp, Target, Calendar, Clock } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function ProfilePage() {
|
||||
const [userStats] = useState({
|
||||
name: "Sarah Chen", email: "sarah.chen@example.com", joinDate: "January 15, 2025", totalStudyHours: 1247,
|
||||
currentStreak: 32,
|
||||
longestStreak: 89,
|
||||
goalsCompleted: 156,
|
||||
averageSessionLength: 45
|
||||
});
|
||||
|
||||
const [achievements] = useState([
|
||||
{ id: "1", name: "Week Warrior", description: "7-day study streak", earned: true },
|
||||
{ id: "2", name: "Century Club", description: "100 study hours", earned: true },
|
||||
{ id: "3", name: "Goal Master", description: "50 goals completed", earned: true },
|
||||
{ id: "4", name: "Legend", description: "500 study hours", earned: false }
|
||||
]);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="bounce-effect"
|
||||
defaultTextAnimation="background-highlight"
|
||||
borderRadius="rounded"
|
||||
contentWidth="mediumLarge"
|
||||
sizing="mediumLargeSizeMediumTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="outline"
|
||||
primaryButtonStyle="shadow"
|
||||
secondaryButtonStyle="radial-glow"
|
||||
headingFontWeight="extrabold"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingInline
|
||||
brandName="StudyFlow"
|
||||
navItems={[
|
||||
{ name: "Features", id: "features" },
|
||||
{ name: "Benefits", id: "about" },
|
||||
{ name: "Pricing", id: "metrics" },
|
||||
{ name: "FAQ", id: "faq" },
|
||||
{ name: "Profile", id: "profile" }
|
||||
]}
|
||||
button={{ text: "Logout", href: "/" }}
|
||||
animateOnLoad={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="min-h-screen pt-32 pb-20 px-4">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Profile Header */}
|
||||
<div className="mb-12">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-8 mb-12">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="w-24 h-24 rounded-full bg-gradient-to-br from-purple-400 to-purple-600 flex items-center justify-center">
|
||||
<User size={48} className="text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-2">{userStats.name}</h1>
|
||||
<p className="text-lg text-gray-600 dark:text-gray-300 mb-2">{userStats.email}</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">Member since {userStats.joinDate}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<button className="flex items-center gap-2 px-6 py-3 bg-purple-600 hover:bg-purple-700 text-white rounded-lg transition-colors">
|
||||
<Settings size={20} />
|
||||
Settings
|
||||
</button>
|
||||
<button className="flex items-center gap-2 px-6 py-3 border-2 border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors">
|
||||
<LogOut size={20} />
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-12">
|
||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<p className="text-gray-600 dark:text-gray-400">Study Hours</p>
|
||||
<Clock className="text-purple-600" size={20} />
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{userStats.totalStudyHours.toLocaleString()}</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<p className="text-gray-600 dark:text-gray-400">Current Streak</p>
|
||||
<TrendingUp className="text-orange-600" size={20} />
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{userStats.currentStreak} days</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<p className="text-gray-600 dark:text-gray-400">Goals Completed</p>
|
||||
<Target className="text-green-600" size={20} />
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{userStats.goalsCompleted}</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<p className="text-gray-600 dark:text-gray-400">Longest Streak</p>
|
||||
<Award className="text-yellow-600" size={20} />
|
||||
</div>
|
||||
<p className="text-3xl font-bold">{userStats.longestStreak} days</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Achievements Section */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold mb-8">Your Achievements</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{achievements.map((achievement) => (
|
||||
<div
|
||||
key={achievement.id}
|
||||
className={`p-6 rounded-xl border-2 transition-all ${
|
||||
achievement.earned
|
||||
? 'bg-purple-50 dark:bg-purple-900/20 border-purple-300 dark:border-purple-600'
|
||||
: 'bg-gray-50 dark:bg-gray-800 border-gray-300 dark:border-gray-600 opacity-50'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-center w-12 h-12 rounded-full bg-purple-600 mb-4">
|
||||
<Award size={24} className="text-white" />
|
||||
</div>
|
||||
<h3 className="font-bold mb-2">{achievement.name}</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 mb-3">{achievement.description}</p>
|
||||
<div className="text-xs font-semibold">
|
||||
{achievement.earned ? (
|
||||
<span className="text-green-600 dark:text-green-400">✓ Unlocked</span>
|
||||
) : (
|
||||
<span className="text-gray-500">Locked</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Study History */}
|
||||
<div className="mt-16">
|
||||
<h2 className="text-2xl font-bold mb-8">Recent Study Sessions</h2>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{ date: "Today", duration: 120, subject: "Mathematics" },
|
||||
{ date: "Yesterday", duration: 90, subject: "Physics" },
|
||||
{ date: "2 days ago", duration: 150, subject: "Biology" },
|
||||
{ date: "3 days ago", duration: 75, subject: "Chemistry" },
|
||||
{ date: "4 days ago", duration: 105, subject: "English Literature" }
|
||||
].map((session, idx) => (
|
||||
<div key={idx} className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-semibold">{session.subject}</p>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400">{session.date}</p>
|
||||
</div>
|
||||
<p className="text-lg font-bold text-purple-600">{session.duration} min</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user