Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a9faf3177 | |||
| b2f88446d6 | |||
| 619ef115ec | |||
| 8ac4045516 | |||
| 8d45975582 | |||
| 2348fc6351 | |||
| 5851115755 | |||
| c472c108dc | |||
| 94d69027e6 |
318
src/app/create-account/page.tsx
Normal file
318
src/app/create-account/page.tsx
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
|
||||||
|
import FooterBase from '@/components/sections/footer/FooterBase';
|
||||||
|
import Input from '@/components/form/Input';
|
||||||
|
import { Mail, Lock, User, CheckCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
export default function CreateAccountPage() {
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
firstName: "", lastName: "", email: "", password: "", confirmPassword: ""
|
||||||
|
});
|
||||||
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
const [passwordStrength, setPasswordStrength] = useState<'weak' | 'fair' | 'strong' | ''>('');
|
||||||
|
|
||||||
|
const calculatePasswordStrength = (password: string) => {
|
||||||
|
if (!password) {
|
||||||
|
setPasswordStrength('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (password.length < 8) {
|
||||||
|
setPasswordStrength('weak');
|
||||||
|
} else if (password.length < 12 || !/[A-Z]/.test(password) || !/[0-9]/.test(password)) {
|
||||||
|
setPasswordStrength('fair');
|
||||||
|
} else {
|
||||||
|
setPasswordStrength('strong');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateForm = () => {
|
||||||
|
const newErrors: Record<string, string> = {};
|
||||||
|
|
||||||
|
if (!formData.firstName.trim()) {
|
||||||
|
newErrors.firstName = "First name is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.lastName.trim()) {
|
||||||
|
newErrors.lastName = "Last name is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.email) {
|
||||||
|
newErrors.email = "Email is required";
|
||||||
|
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
|
||||||
|
newErrors.email = "Please enter a valid email";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.password) {
|
||||||
|
newErrors.password = "Password is required";
|
||||||
|
} else if (formData.password.length < 8) {
|
||||||
|
newErrors.password = "Password must be at least 8 characters";
|
||||||
|
} else if (!/[A-Z]/.test(formData.password)) {
|
||||||
|
newErrors.password = "Password must contain at least one uppercase letter";
|
||||||
|
} else if (!/[0-9]/.test(formData.password)) {
|
||||||
|
newErrors.password = "Password must contain at least one number";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.confirmPassword) {
|
||||||
|
newErrors.confirmPassword = "Please confirm your password";
|
||||||
|
} else if (formData.password !== formData.confirmPassword) {
|
||||||
|
newErrors.confirmPassword = "Passwords do not match";
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrors(newErrors);
|
||||||
|
return Object.keys(newErrors).length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!validateForm()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsSubmitting(true);
|
||||||
|
try {
|
||||||
|
// Simulate API call
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
console.log("Account creation with:", formData);
|
||||||
|
// Handle successful account creation
|
||||||
|
} finally {
|
||||||
|
setIsSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInputChange = (field: string, value: string) => {
|
||||||
|
setFormData(prev => ({ ...prev, [field]: value }));
|
||||||
|
if (field === 'password') {
|
||||||
|
calculatePasswordStrength(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeProvider
|
||||||
|
defaultButtonVariant="directional-hover"
|
||||||
|
defaultTextAnimation="background-highlight"
|
||||||
|
borderRadius="rounded"
|
||||||
|
contentWidth="medium"
|
||||||
|
sizing="largeSmallSizeMediumTitles"
|
||||||
|
background="floatingGradient"
|
||||||
|
cardStyle="gradient-mesh"
|
||||||
|
primaryButtonStyle="primary-glow"
|
||||||
|
secondaryButtonStyle="glass"
|
||||||
|
headingFontWeight="medium"
|
||||||
|
>
|
||||||
|
<div id="nav" data-section="nav">
|
||||||
|
<NavbarStyleCentered
|
||||||
|
navItems={[
|
||||||
|
{ name: "Features", id: "features" },
|
||||||
|
{ name: "Pricing", id: "pricing" },
|
||||||
|
{ name: "Testimonials", id: "testimonials" },
|
||||||
|
{ name: "FAQ", id: "faq" },
|
||||||
|
{ name: "Contact", id: "contact" }
|
||||||
|
]}
|
||||||
|
button={{ text: "Start Free Trial", href: "/contact" }}
|
||||||
|
brandName="TradeLogs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="min-h-screen flex items-center justify-center py-20 px-4">
|
||||||
|
<div className="w-full max-w-md">
|
||||||
|
<div className="text-center mb-8">
|
||||||
|
<h1 className="text-4xl font-bold mb-2">Create Your Account</h1>
|
||||||
|
<p className="text-foreground/60">Join thousands of traders improving their performance</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-5">
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="firstName" className="block text-sm font-medium mb-2">
|
||||||
|
First Name
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={formData.firstName}
|
||||||
|
onChange={(value) => handleInputChange('firstName', value)}
|
||||||
|
type="text"
|
||||||
|
placeholder="John"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.firstName && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.firstName}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="lastName" className="block text-sm font-medium mb-2">
|
||||||
|
Last Name
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={formData.lastName}
|
||||||
|
onChange={(value) => handleInputChange('lastName', value)}
|
||||||
|
type="text"
|
||||||
|
placeholder="Doe"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.lastName && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.lastName}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="email" className="block text-sm font-medium mb-2">
|
||||||
|
Email Address
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={formData.email}
|
||||||
|
onChange={(value) => handleInputChange('email', value)}
|
||||||
|
type="email"
|
||||||
|
placeholder="you@example.com"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.email && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.email}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="password" className="block text-sm font-medium mb-2">
|
||||||
|
Password
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={formData.password}
|
||||||
|
onChange={(value) => handleInputChange('password', value)}
|
||||||
|
type="password"
|
||||||
|
placeholder="Create a strong password"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{formData.password && (
|
||||||
|
<div className="mt-2 flex items-center gap-2">
|
||||||
|
<div className="flex gap-1 flex-1">
|
||||||
|
<div className={`h-1 flex-1 rounded ${
|
||||||
|
passwordStrength === 'weak' || passwordStrength === 'fair' || passwordStrength === 'strong'
|
||||||
|
? 'bg-red-500'
|
||||||
|
: 'bg-gray-300'
|
||||||
|
}`} />
|
||||||
|
<div className={`h-1 flex-1 rounded ${
|
||||||
|
passwordStrength === 'fair' || passwordStrength === 'strong'
|
||||||
|
? 'bg-yellow-500'
|
||||||
|
: 'bg-gray-300'
|
||||||
|
}`} />
|
||||||
|
<div className={`h-1 flex-1 rounded ${
|
||||||
|
passwordStrength === 'strong'
|
||||||
|
? 'bg-green-500'
|
||||||
|
: 'bg-gray-300'
|
||||||
|
}`} />
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-medium">
|
||||||
|
{passwordStrength === 'weak' && 'Weak'}
|
||||||
|
{passwordStrength === 'fair' && 'Fair'}
|
||||||
|
{passwordStrength === 'strong' && 'Strong'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{errors.password && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.password}</p>
|
||||||
|
)}
|
||||||
|
<p className="text-xs text-foreground/50 mt-2">
|
||||||
|
Password must be at least 8 characters with uppercase letters and numbers
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="confirmPassword" className="block text-sm font-medium mb-2">
|
||||||
|
Confirm Password
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={formData.confirmPassword}
|
||||||
|
onChange={(value) => handleInputChange('confirmPassword', value)}
|
||||||
|
type="password"
|
||||||
|
placeholder="Re-enter your password"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.confirmPassword && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.confirmPassword}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="terms"
|
||||||
|
className="w-4 h-4 rounded border-secondary-cta mt-1"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<label htmlFor="terms" className="text-sm text-foreground/70">
|
||||||
|
I agree to the{" "}
|
||||||
|
<a href="#" className="text-primary-cta hover:underline">
|
||||||
|
Terms of Service
|
||||||
|
</a>
|
||||||
|
{" "}and{" "}
|
||||||
|
<a href="#" className="text-primary-cta hover:underline">
|
||||||
|
Privacy Policy
|
||||||
|
</a>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
className="w-full py-3 px-4 bg-primary-cta text-white rounded-lg font-medium hover:opacity-90 disabled:opacity-50 transition-opacity"
|
||||||
|
>
|
||||||
|
{isSubmitting ? "Creating Account..." : "Create Account"}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className="mt-6 text-center text-sm">
|
||||||
|
<p className="text-foreground/60">
|
||||||
|
Already have an account?{" "}
|
||||||
|
<a href="/login" className="text-primary-cta font-medium hover:underline">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" data-section="footer">
|
||||||
|
<FooterBase
|
||||||
|
logoText="TradeLogs"
|
||||||
|
copyrightText="© 2025 TradeLogs. All rights reserved."
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: "Product", items: [
|
||||||
|
{ label: "Features", href: "/#features" },
|
||||||
|
{ label: "Pricing", href: "/#pricing" },
|
||||||
|
{ label: "Security", href: "#" },
|
||||||
|
{ label: "API Docs", href: "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Company", items: [
|
||||||
|
{ label: "About Us", href: "#" },
|
||||||
|
{ label: "Blog", href: "#" },
|
||||||
|
{ label: "Careers", href: "#" },
|
||||||
|
{ label: "Contact", href: "/#contact" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Legal", items: [
|
||||||
|
{ label: "Privacy Policy", href: "#" },
|
||||||
|
{ label: "Terms of Service", href: "#" },
|
||||||
|
{ label: "Disclaimer", href: "#" },
|
||||||
|
{ label: "Sitemap", href: "#" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
185
src/app/dashboard/page.tsx
Normal file
185
src/app/dashboard/page.tsx
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
|
||||||
|
import FeatureCardEight from '@/components/sections/feature/FeatureCardEight';
|
||||||
|
import MetricCardSeven from '@/components/sections/metrics/MetricCardSeven';
|
||||||
|
import TestimonialCardSixteen from '@/components/sections/testimonial/TestimonialCardSixteen';
|
||||||
|
import FooterBase from '@/components/sections/footer/FooterBase';
|
||||||
|
import { TrendingUp, BarChart3, PieChart, Activity, Target, DollarSign, AlertCircle, CheckCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
export default function DashboardPage() {
|
||||||
|
return (
|
||||||
|
<ThemeProvider
|
||||||
|
defaultButtonVariant="directional-hover"
|
||||||
|
defaultTextAnimation="background-highlight"
|
||||||
|
borderRadius="rounded"
|
||||||
|
contentWidth="medium"
|
||||||
|
sizing="largeSmallSizeMediumTitles"
|
||||||
|
background="floatingGradient"
|
||||||
|
cardStyle="gradient-mesh"
|
||||||
|
primaryButtonStyle="primary-glow"
|
||||||
|
secondaryButtonStyle="glass"
|
||||||
|
headingFontWeight="medium"
|
||||||
|
>
|
||||||
|
<div id="nav" data-section="nav">
|
||||||
|
<NavbarStyleCentered
|
||||||
|
navItems={[
|
||||||
|
{ name: "Dashboard", id: "dashboard" },
|
||||||
|
{ name: "Journal", id: "journal" },
|
||||||
|
{ name: "Analytics", id: "analytics" },
|
||||||
|
{ name: "Performance", id: "performance" },
|
||||||
|
{ name: "Settings", id: "settings" }
|
||||||
|
]}
|
||||||
|
button={{ text: "Logout", href: "/" }}
|
||||||
|
brandName="TradeLogs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="journal" data-section="journal">
|
||||||
|
<FeatureCardEight
|
||||||
|
title="Trading Journal Entries"
|
||||||
|
description="Log and manage your trades with detailed analysis, emotional tracking, and strategic notes for continuous improvement."
|
||||||
|
tag="Journal Management"
|
||||||
|
textboxLayout="default"
|
||||||
|
useInvertedBackground={false}
|
||||||
|
features={[
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Quick Trade Entry", description: "Log trades in seconds with preset templates, auto-filled market data, and one-click entry/exit recording.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/a-clean-trade-journaling-entry-form-with-1773198499682-88c668e9.png?_wi=2", imageAlt: "Quick Entry Form"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Emotional Analysis", description: "Track emotional state during trades, identify patterns affecting your decisions, and build psychological awareness.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/an-ai-powered-insights-panel-showing-tra-1773198498049-6de928a2.png?_wi=2", imageAlt: "Emotional Tracking"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "Strategy Tags", description: "Categorize trades by strategy, market condition, and setup type for comprehensive performance analysis by strategy.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/uploaded-1773198840662-6yiahxf8.png", imageAlt: "Strategy Organization"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "Trade History", description: "Access your complete trading history with advanced filtering, search capabilities, and bulk export options.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/uploaded-1773198840662-ffdgm9pm.png", imageAlt: "Trade History View"
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="analytics" data-section="analytics">
|
||||||
|
<FeatureCardEight
|
||||||
|
title="Advanced Analytics Charts"
|
||||||
|
description="Visualize your trading performance with interactive charts, real-time metrics, and deep performance insights."
|
||||||
|
tag="Analytics Dashboard"
|
||||||
|
textboxLayout="default"
|
||||||
|
useInvertedBackground={false}
|
||||||
|
features={[
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Win/Loss Distribution", description: "Beautiful pie and bar charts showing your win rate, average profit per trade, and distribution across strategies.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/uploaded-1773198840662-q2exabeo.png", imageAlt: "Win Loss Charts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Equity Curve", description: "Track your account equity over time with cumulative profit/loss visualization and drawdown analysis.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/a-detailed-analytics-dashboard-showing-t-1773198498451-eec93cbe.png?_wi=1", imageAlt: "Equity Curve Chart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "Monthly Performance", description: "Compare performance across months with heatmaps, trend lines, and year-to-date summaries.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/uploaded-1773198840662-hlp4mklz.png", imageAlt: "Monthly Performance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "Risk Metrics", description: "Analyze risk-adjusted returns, maximum drawdown, Sharpe ratio, and other key performance indicators.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/uploaded-1773198840662-57d41v2x.png", imageAlt: "Risk Analysis"
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="performance" data-section="performance">
|
||||||
|
<MetricCardSeven
|
||||||
|
title="Performance Metrics"
|
||||||
|
description="Key statistics and insights about your trading performance, profitability, and consistency."
|
||||||
|
tag="Key Metrics"
|
||||||
|
textboxLayout="default"
|
||||||
|
animationType="slide-up"
|
||||||
|
useInvertedBackground={false}
|
||||||
|
metrics={[
|
||||||
|
{
|
||||||
|
id: "1", value: "62%", title: "Win Rate", items: ["15 wins from 24 trades", "Above market average", "Consistent performance"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2", value: "$12,450", title: "Total Profit", items: ["This month YTD", "From 24 trades", "$520 average per trade"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3", value: "2.8:1", title: "Profit Factor", items: ["Risk vs reward ratio", "Strong performance", "Trading discipline evident"]
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="history" data-section="history">
|
||||||
|
<TestimonialCardSixteen
|
||||||
|
title="Recent Trade Activity"
|
||||||
|
description="Overview of your recent trades showing key details, outcomes, and performance insights."
|
||||||
|
tag="Trade History"
|
||||||
|
textboxLayout="default"
|
||||||
|
animationType="slide-up"
|
||||||
|
useInvertedBackground={false}
|
||||||
|
testimonials={[
|
||||||
|
{
|
||||||
|
id: "1", name: "SPY Call Option", role: "Buy to Open", company: "Profit: +$245", rating: 5,
|
||||||
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-confident-fem-1773198497731-8eebcb72.png?_wi=2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2", name: "QQQ Short", role: "Swing Trade", company: "Profit: +$180", rating: 5,
|
||||||
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-male-trader-i-1773198497678-26a2816b.png?_wi=2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3", name: "EUR/USD Scalp", role: "Day Trade", company: "Loss: -$95", rating: 3,
|
||||||
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-young-male-tr-1773198497913-9713df41.png?_wi=2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4", name: "Tech Stock Long", role: "Position Trade", company: "Profit: +$520", rating: 5,
|
||||||
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-female-trader-1773198497808-f8d431b2.png?_wi=2"
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
kpiItems={[
|
||||||
|
{ value: "24", label: "Total Trades This Month" },
|
||||||
|
{ value: "$12.5K", label: "Total Profit" },
|
||||||
|
{ value: "3.2h", label: "Avg. Hold Time" }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" data-section="footer">
|
||||||
|
<FooterBase
|
||||||
|
logoText="TradeLogs"
|
||||||
|
copyrightText="© 2025 TradeLogs. All rights reserved."
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: "Product", items: [
|
||||||
|
{ label: "Dashboard", href: "/dashboard" },
|
||||||
|
{ label: "Features", href: "/#features" },
|
||||||
|
{ label: "Pricing", href: "/#pricing" },
|
||||||
|
{ label: "API Docs", href: "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Resources", items: [
|
||||||
|
{ label: "Documentation", href: "#" },
|
||||||
|
{ label: "Trading Guides", href: "#" },
|
||||||
|
{ label: "Community", href: "#" },
|
||||||
|
{ label: "Support", href: "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Legal", items: [
|
||||||
|
{ label: "Privacy Policy", href: "#" },
|
||||||
|
{ label: "Terms of Service", href: "#" },
|
||||||
|
{ label: "Disclaimer", href: "#" },
|
||||||
|
{ label: "Contact", href: "/" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
189
src/app/login/page.tsx
Normal file
189
src/app/login/page.tsx
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
|
||||||
|
import FooterBase from '@/components/sections/footer/FooterBase';
|
||||||
|
import Input from '@/components/form/Input';
|
||||||
|
import { Mail, Lock } from 'lucide-react';
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [errors, setErrors] = useState<{ email?: string; password?: string }>({});
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
|
const validateForm = () => {
|
||||||
|
const newErrors: { email?: string; password?: string } = {};
|
||||||
|
|
||||||
|
if (!email) {
|
||||||
|
newErrors.email = "Email is required";
|
||||||
|
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||||
|
newErrors.email = "Please enter a valid email";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password) {
|
||||||
|
newErrors.password = "Password is required";
|
||||||
|
} else if (password.length < 6) {
|
||||||
|
newErrors.password = "Password must be at least 6 characters";
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrors(newErrors);
|
||||||
|
return Object.keys(newErrors).length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!validateForm()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsSubmitting(true);
|
||||||
|
try {
|
||||||
|
// Simulate API call
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
console.log("Login attempt with:", { email, password });
|
||||||
|
// Handle successful login
|
||||||
|
} finally {
|
||||||
|
setIsSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeProvider
|
||||||
|
defaultButtonVariant="directional-hover"
|
||||||
|
defaultTextAnimation="background-highlight"
|
||||||
|
borderRadius="rounded"
|
||||||
|
contentWidth="medium"
|
||||||
|
sizing="largeSmallSizeMediumTitles"
|
||||||
|
background="floatingGradient"
|
||||||
|
cardStyle="gradient-mesh"
|
||||||
|
primaryButtonStyle="primary-glow"
|
||||||
|
secondaryButtonStyle="glass"
|
||||||
|
headingFontWeight="medium"
|
||||||
|
>
|
||||||
|
<div id="nav" data-section="nav">
|
||||||
|
<NavbarStyleCentered
|
||||||
|
navItems={[
|
||||||
|
{ name: "Features", id: "features" },
|
||||||
|
{ name: "Pricing", id: "pricing" },
|
||||||
|
{ name: "Testimonials", id: "testimonials" },
|
||||||
|
{ name: "FAQ", id: "faq" },
|
||||||
|
{ name: "Contact", id: "contact" }
|
||||||
|
]}
|
||||||
|
button={{ text: "Start Free Trial", href: "/contact" }}
|
||||||
|
brandName="TradeLogs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="min-h-screen flex items-center justify-center py-20 px-4">
|
||||||
|
<div className="w-full max-w-md">
|
||||||
|
<div className="text-center mb-8">
|
||||||
|
<h1 className="text-4xl font-bold mb-2">Welcome Back</h1>
|
||||||
|
<p className="text-foreground/60">Sign in to your TradeLogs account</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="email" className="block text-sm font-medium mb-2">
|
||||||
|
Email Address
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={email}
|
||||||
|
onChange={setEmail}
|
||||||
|
type="email"
|
||||||
|
placeholder="you@example.com"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.email && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.email}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="password" className="block text-sm font-medium mb-2">
|
||||||
|
Password
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
value={password}
|
||||||
|
onChange={setPassword}
|
||||||
|
type="password"
|
||||||
|
placeholder="Enter your password"
|
||||||
|
required
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
{errors.password && (
|
||||||
|
<p className="text-red-500 text-sm mt-1">{errors.password}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between text-sm">
|
||||||
|
<label className="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="w-4 h-4 rounded border-secondary-cta mr-2"
|
||||||
|
/>
|
||||||
|
<span>Remember me</span>
|
||||||
|
</label>
|
||||||
|
<a href="#" className="text-primary-cta hover:underline">
|
||||||
|
Forgot password?
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
className="w-full py-3 px-4 bg-primary-cta text-white rounded-lg font-medium hover:opacity-90 disabled:opacity-50 transition-opacity"
|
||||||
|
>
|
||||||
|
{isSubmitting ? "Signing in..." : "Sign In"}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className="mt-6 text-center text-sm">
|
||||||
|
<p className="text-foreground/60">
|
||||||
|
Don't have an account?{" "}
|
||||||
|
<a href="/create-account" className="text-primary-cta font-medium hover:underline">
|
||||||
|
Create one
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" data-section="footer">
|
||||||
|
<FooterBase
|
||||||
|
logoText="TradeLogs"
|
||||||
|
copyrightText="© 2025 TradeLogs. All rights reserved."
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: "Product", items: [
|
||||||
|
{ label: "Features", href: "/#features" },
|
||||||
|
{ label: "Pricing", href: "/#pricing" },
|
||||||
|
{ label: "Security", href: "#" },
|
||||||
|
{ label: "API Docs", href: "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Company", items: [
|
||||||
|
{ label: "About Us", href: "#" },
|
||||||
|
{ label: "Blog", href: "#" },
|
||||||
|
{ label: "Careers", href: "#" },
|
||||||
|
{ label: "Contact", href: "/#contact" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Legal", items: [
|
||||||
|
{ label: "Privacy Policy", href: "#" },
|
||||||
|
{ label: "Terms of Service", href: "#" },
|
||||||
|
{ label: "Disclaimer", href: "#" },
|
||||||
|
{ label: "Sitemap", href: "#" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ export default function LandingPage() {
|
|||||||
{ name: "Pricing", id: "pricing" },
|
{ name: "Pricing", id: "pricing" },
|
||||||
{ name: "Testimonials", id: "testimonials" },
|
{ name: "Testimonials", id: "testimonials" },
|
||||||
{ name: "FAQ", id: "faq" },
|
{ name: "FAQ", id: "faq" },
|
||||||
|
{ name: "Dashboard", id: "/dashboard" },
|
||||||
{ name: "Contact", id: "contact" }
|
{ name: "Contact", id: "contact" }
|
||||||
]}
|
]}
|
||||||
button={{ text: "Start Free Trial", href: "contact" }}
|
button={{ text: "Start Free Trial", href: "contact" }}
|
||||||
@@ -68,11 +69,11 @@ export default function LandingPage() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
title: "AI-Powered Insights", description: "Get intelligent trading recommendations and pattern recognition powered by advanced machine learning algorithms.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/an-ai-powered-insights-panel-showing-tra-1773198498049-6de928a2.png", imageAlt: "AI Insights Panel"
|
title: "AI-Powered Insights", description: "Get intelligent trading recommendations and pattern recognition powered by advanced machine learning algorithms.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/an-ai-powered-insights-panel-showing-tra-1773198498049-6de928a2.png?_wi=1", imageAlt: "AI Insights Panel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
title: "Trade Journaling", description: "Comprehensive trade logging with emotional state tracking, strategy classification, and detailed reflections for continuous improvement.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/a-clean-trade-journaling-entry-form-with-1773198499682-88c668e9.png", imageAlt: "Trade Journal"
|
title: "Trade Journaling", description: "Comprehensive trade logging with emotional state tracking, strategy classification, and detailed reflections for continuous improvement.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/a-clean-trade-journaling-entry-form-with-1773198499682-88c668e9.png?_wi=1", imageAlt: "Trade Journal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
@@ -140,19 +141,19 @@ export default function LandingPage() {
|
|||||||
testimonials={[
|
testimonials={[
|
||||||
{
|
{
|
||||||
id: "1", name: "Sarah Chen", role: "Day Trader", company: "Elite Trading Group", rating: 5,
|
id: "1", name: "Sarah Chen", role: "Day Trader", company: "Elite Trading Group", rating: 5,
|
||||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-confident-fem-1773198497731-8eebcb72.png"
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-confident-fem-1773198497731-8eebcb72.png?_wi=1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2", name: "Michael Rodriguez", role: "Options Trader", company: "Quantum Capital", rating: 5,
|
id: "2", name: "Michael Rodriguez", role: "Options Trader", company: "Quantum Capital", rating: 5,
|
||||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-male-trader-i-1773198497678-26a2816b.png"
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-male-trader-i-1773198497678-26a2816b.png?_wi=1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "3", name: "James Liu", role: "Swing Trader", company: "Independent", rating: 5,
|
id: "3", name: "James Liu", role: "Swing Trader", company: "Independent", rating: 5,
|
||||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-young-male-tr-1773198497913-9713df41.png"
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-young-male-tr-1773198497913-9713df41.png?_wi=1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "4", name: "Emma Thompson", role: "Forex Trader", company: "Global Markets Ltd", rating: 5,
|
id: "4", name: "Emma Thompson", role: "Forex Trader", company: "Global Markets Ltd", rating: 5,
|
||||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-female-trader-1773198497808-f8d431b2.png"
|
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AmW4xUc857ptqynek7kyF9pCSY/professional-headshot-of-a-female-trader-1773198497808-f8d431b2.png?_wi=1"
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
kpiItems={[
|
kpiItems={[
|
||||||
|
|||||||
Reference in New Issue
Block a user