4 Commits

Author SHA1 Message Date
72fd95c53c Add src/components/sections/payment/PaymentTerminal.tsx 2026-03-07 06:33:33 +00:00
ed774ff833 Update src/app/page.tsx 2026-03-07 06:33:33 +00:00
c856c61579 Update src/app/layout.tsx 2026-03-07 06:33:33 +00:00
29aa4645a6 Merge version_1 into main
Merge version_1 into main
2026-03-07 06:25:12 +00:00
3 changed files with 653 additions and 212 deletions

View File

@@ -7,49 +7,31 @@ import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag"; import Tag from "@/tag/Tag";
const halant = Halant({ const halant = Halant({
variable: "--font-halant", variable: "--font-halant", subsets: ["latin"],
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"], weight: ["300", "400", "500", "600", "700"],
}); });
const dmSans = DM_Sans({ const dmSans = DM_Sans({
variable: "--font-dm-sans", variable: "--font-dm-sans", subsets: ["latin"],
subsets: ["latin"],
}); });
const inter = Inter({ const inter = Inter({
variable: "--font-inter", variable: "--font-inter", subsets: ["latin"],
subsets: ["latin"],
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "DigitalPro - Premium Digital Products & Templates", title: "DigitalPro - Premium Digital Products & Templates", description: "Premium digital templates and tools designed to accelerate your success. Instant access, secure payments, 24/7 support.", keywords: "digital products, templates, Notion templates, AI tools, productivity, business templates, digital assets", metadataBase: new URL("https://digitalpro.com"),
description: "Premium digital templates and tools designed to accelerate your success. Instant access, secure payments, 24/7 support.",
keywords: "digital products, templates, Notion templates, AI tools, productivity, business templates, digital assets",
metadataBase: new URL("https://digitalpro.com"),
alternates: { alternates: {
canonical: "https://digitalpro.com", canonical: "https://digitalpro.com"},
},
openGraph: { openGraph: {
title: "DigitalPro - Premium Digital Products", title: "DigitalPro - Premium Digital Products", description: "Premium digital templates and tools to transform your business", url: "https://digitalpro.com", siteName: "DigitalPro", type: "website", images: [
description: "Premium digital templates and tools to transform your business",
url: "https://digitalpro.com",
siteName: "DigitalPro",
type: "website",
images: [
{ {
url: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png", url: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png", alt: "DigitalPro Premium Templates"},
alt: "DigitalPro Premium Templates",
},
], ],
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image", title: "DigitalPro - Premium Digital Products", description: "Premium templates and tools to accelerate your success", images: [
title: "DigitalPro - Premium Digital Products", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png"],
description: "Premium templates and tools to accelerate your success",
images: [
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png",
],
}, },
robots: { robots: {
index: true, index: true,
@@ -1441,4 +1423,4 @@ export default function RootLayout({
</ServiceWrapper> </ServiceWrapper>
</html> </html>
); );
} }

View File

@@ -21,6 +21,10 @@ import {
Sparkles, Sparkles,
Star, Star,
Crown, Crown,
Lock,
CheckCircle,
AlertCircle,
Eye,
} from "lucide-react"; } from "lucide-react";
const navItems = [ const navItems = [
@@ -33,8 +37,7 @@ const navItems = [
const footerColumns = [ const footerColumns = [
{ {
title: "Product", title: "Product", items: [
items: [
{ label: "Templates", href: "/products" }, { label: "Templates", href: "/products" },
{ label: "Pricing", href: "/pricing" }, { label: "Pricing", href: "/pricing" },
{ label: "Features", href: "#features" }, { label: "Features", href: "#features" },
@@ -42,8 +45,7 @@ const footerColumns = [
], ],
}, },
{ {
title: "Company", title: "Company", items: [
items: [
{ label: "About", href: "#" }, { label: "About", href: "#" },
{ label: "Blog", href: "#" }, { label: "Blog", href: "#" },
{ label: "Careers", href: "#" }, { label: "Careers", href: "#" },
@@ -51,8 +53,7 @@ const footerColumns = [
], ],
}, },
{ {
title: "Legal", title: "Legal", items: [
items: [
{ label: "Privacy", href: "#" }, { label: "Privacy", href: "#" },
{ label: "Terms", href: "#" }, { label: "Terms", href: "#" },
{ label: "Cookies", href: "#" }, { label: "Cookies", href: "#" },
@@ -62,6 +63,223 @@ const footerColumns = [
]; ];
export default function HomePage() { export default function HomePage() {
// Payment Verification and Tokenization Handler
const handlePaymentVerification = async (paymentData: any) => {
try {
// Tokenize sensitive payment data - never store raw card numbers
const tokenizedData = await tokenizePaymentData(paymentData);
// Verify tokenized payment
const verificationResult = await verifyPayment(tokenizedData);
if (verificationResult.success) {
// Process verified payment
await processVerifiedPayment(verificationResult);
return { status: "success", message: "Payment processed successfully" };
} else {
// Handle verification failure
return handlePaymentError(verificationResult.error);
}
} catch (error) {
// Comprehensive error handling
return handlePaymentException(error);
}
};
// Tokenization: Convert raw payment data to secure tokens
// PCI-DSS Compliance: Reduces PCI compliance burden by not handling raw card data
const tokenizePaymentData = async (paymentData: any) => {
const { cardNumber, cvv, expiryDate, holderName } = paymentData;
try {
// Call tokenization service (e.g., Stripe, Square, PayPal API)
const response = await fetch("/api/tokenize", {
method: "POST", headers: {
"Content-Type": "application/json", "Authorization": `Bearer ${process.env.NEXT_PUBLIC_PAYMENT_API_KEY}`,
},
body: JSON.stringify({
cardNumber: cardNumber.replace(/\s/g, ""), // Remove formatting
cvv: cvv, // CVV should be transmitted only once for tokenization
expiryDate: expiryDate,
holderName: holderName,
// Add timestamp to prevent replay attacks
timestamp: new Date().toISOString(),
// Include nonce for CSRF protection
nonce: generateNonce(),
}),
});
if (!response.ok) {
throw new Error(`Tokenization failed: ${response.statusText}`);
}
const tokenizedResult = await response.json();
// Ensure token is secure and time-limited
if (!tokenizedResult.token || !tokenizedResult.expiresAt) {
throw new Error("Invalid tokenization response");
}
return {
token: tokenizedResult.token,
expiresAt: tokenizedResult.expiresAt,
tokenType: "payment_token"};
} catch (error) {
throw new Error(`Tokenization error: ${error}`);
}
};
// Payment Verification: Validate tokenized payment against fraud checks
const verifyPayment = async (tokenizedData: any) => {
const { token, expiresAt } = tokenizedData;
try {
// Check token expiration
if (new Date(expiresAt) < new Date()) {
throw new Error("Payment token has expired");
}
// Call payment verification service
const response = await fetch("/api/verify-payment", {
method: "POST", headers: {
"Content-Type": "application/json", "Authorization": `Bearer ${process.env.NEXT_PUBLIC_PAYMENT_API_KEY}`,
},
body: JSON.stringify({
token: token,
amount: 0, // Amount should be validated separately
currency: "USD", // Include verification details for fraud prevention
verification: {
cvvCheck: true,
avsCheck: true,
threeDSecure: true,
},
// Metadata for audit trail
metadata: {
userId: "user_id_here", orderId: "order_id_here", timestamp: new Date().toISOString(),
},
}),
});
if (!response.ok) {
throw new Error(`Payment verification failed: ${response.statusText}`);
}
const verificationResult = await response.json();
// Validate verification response structure
if (!verificationResult.verified && !verificationResult.error) {
throw new Error("Invalid verification response structure");
}
return {
success: verificationResult.verified,
transactionId: verificationResult.transactionId || null,
error: verificationResult.error || null,
fraudScore: verificationResult.fraudScore || 0,
};
} catch (error) {
throw new Error(`Verification error: ${error}`);
}
};
// Process Verified Payment: Execute transaction with verified token
const processVerifiedPayment = async (verificationResult: any) => {
const { transactionId, fraudScore } = verificationResult;
try {
// Check fraud score threshold (0-100, higher = more suspicious)
if (fraudScore > 75) {
throw new Error("Payment flagged as high fraud risk");
}
// Process the verified payment
const response = await fetch("/api/process-payment", {
method: "POST", headers: {
"Content-Type": "application/json", "Authorization": `Bearer ${process.env.NEXT_PUBLIC_PAYMENT_API_KEY}`,
},
body: JSON.stringify({
transactionId: transactionId,
fraudScore: fraudScore,
// PCI-DSS: Include settlement strategy
settlement: {
method: "direct", schedule: "immediate"},
// Include receipt and audit information
receipt: {
sendTo: "customer_email", includeInvoice: true,
},
}),
});
if (!response.ok) {
throw new Error(`Payment processing failed: ${response.statusText}`);
}
const processResult = await response.json();
// Log transaction for audit and compliance
await logTransactionAudit({
transactionId: processResult.transactionId,
status: "completed", timestamp: new Date().toISOString(),
});
return processResult;
} catch (error) {
throw new Error(`Processing error: ${error}`);
}
};
// Error Handling: Specific error responses for different scenarios
const handlePaymentError = (error: any) => {
const errorMap: { [key: string]: string } = {
"insufficient_funds": "Your account has insufficient funds. Please check your balance.", "card_declined": "Your card was declined. Please verify your card details.", "expired_card": "Your card has expired. Please use a valid card.", "invalid_cvv": "The CVV provided is invalid. Please check and try again.", "fraud_detected": "This transaction was flagged for fraud prevention. Please contact support.", "duplicate_transaction": "A similar transaction was recently processed. Please try again later.", "network_error": "Network error occurred. Please try again."};
const errorMessage = errorMap[error] || "Payment verification failed. Please try again.";
return {
status: "error", message: errorMessage,
code: error,
// Include retry information
retry: {
allowed: !["card_declined", "expired_card", "insufficient_funds"].includes(error),
afterSeconds: 30,
},
};
};
// Exception Handling: Catch unexpected errors and provide user-friendly message
const handlePaymentException = (error: any) => {
console.error("Payment exception:", error);
return {
status: "error", message: "An unexpected error occurred during payment processing. Please try again or contact support.", code: "PAYMENT_EXCEPTION", debug: process.env.NODE_ENV === "development" ? error.message : undefined,
retry: {
allowed: true,
afterSeconds: 60,
},
};
};
// Generate nonce for CSRF protection
const generateNonce = (): string => {
return Math.random().toString(36).substr(2) + Date.now().toString(36);
};
// Audit logging for PCI-DSS compliance
const logTransactionAudit = async (auditData: any) => {
try {
await fetch("/api/audit-log", {
method: "POST", headers: {
"Content-Type": "application/json"},
body: JSON.stringify({
...auditData,
type: "payment_transaction", ipAddress: "ip_here", // Should be captured server-side
userAgent: typeof window !== "undefined" ? navigator.userAgent : ""}),
});
} catch (error) {
console.error("Audit logging failed:", error);
}
};
return ( return (
<ThemeProvider <ThemeProvider
defaultButtonVariant="icon-arrow" defaultButtonVariant="icon-arrow"
@@ -92,19 +310,13 @@ export default function HomePage() {
slides={[ slides={[
{ {
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/modern-digital-product-showcase-with-abs-1772864653378-8b3bdb2c.png", imageAlt: "Modern digital product showcase"},
imageAlt: "Modern digital product showcase",
},
{ {
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/digital-marketplace-dashboard-with-glowi-1772864653980-c6766c2a.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/digital-marketplace-dashboard-with-glowi-1772864653980-c6766c2a.png", imageAlt: "Digital marketplace dashboard"},
imageAlt: "Digital marketplace dashboard",
},
{ {
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/abstract-digital-transformation-concept--1772864653127-49ec1355.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/abstract-digital-transformation-concept--1772864653127-49ec1355.png", imageAlt: "Digital transformation concept"},
imageAlt: "Digital transformation concept",
},
]} ]}
autoplayDelay={5000} autoplayDelay={5000}
showDimOverlay={true} showDimOverlay={true}
@@ -120,40 +332,28 @@ export default function HomePage() {
features={[ features={[
{ {
icon: Zap, icon: Zap,
title: "Instant Access", title: "Instant Access", description:
description: "Get immediate access to all your purchased digital products and templates"},
"Get immediate access to all your purchased digital products and templates",
},
{ {
icon: Shield, icon: Shield,
title: "Secure & Safe", title: "Secure & Safe", description:
description: "Your payments and data are protected with industry-leading security standards"},
"Your payments and data are protected with industry-leading security standards",
},
{ {
icon: HeadphonesIcon, icon: HeadphonesIcon,
title: "24/7 Support", title: "24/7 Support", description:
description: "Our dedicated team is always ready to help with any questions or issues"},
"Our dedicated team is always ready to help with any questions or issues",
},
{ {
icon: Zap, icon: Zap,
title: "Regular Updates", title: "Regular Updates", description:
description: "Continuous improvements and new templates added to our collection"},
"Continuous improvements and new templates added to our collection",
},
{ {
icon: TrendingUp, icon: TrendingUp,
title: "Proven Results", title: "Proven Results", description:
description: "Thousands of users have transformed their business with our templates"},
"Thousands of users have transformed their business with our templates",
},
{ {
icon: Award, icon: Award,
title: "Premium Quality", title: "Premium Quality", description:
description: "All templates are crafted by industry experts with attention to detail"},
"All templates are crafted by industry experts with attention to detail",
},
]} ]}
animationType="slide-up" animationType="slide-up"
textboxLayout="default" textboxLayout="default"
@@ -169,60 +369,25 @@ export default function HomePage() {
tag="Popular" tag="Popular"
products={[ products={[
{ {
id: "1", id: "1", brand: "DigitalPro", name: "Project Management Master", price: "$49.99", rating: 5,
brand: "DigitalPro", reviewCount: "2.3k", imageSrc:
name: "Project Management Master", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-notion-template-dashboard-for-pr-1772864654183-63b422bf.png?_wi=1", imageAlt: "Project Management Notion Template"},
price: "$49.99",
rating: 5,
reviewCount: "2.3k",
imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-notion-template-dashboard-for-pr-1772864654183-63b422bf.png?_wi=1",
imageAlt: "Project Management Notion Template",
},
{ {
id: "2", id: "2", brand: "DigitalPro", name: "AI Content Suite Pro", price: "$79.99", rating: 5,
brand: "DigitalPro", reviewCount: "1.8k", imageSrc:
name: "AI Content Suite Pro", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-ai-content-creation-toolkit-inte-1772864653758-1b13a7eb.png?_wi=1", imageAlt: "AI Content Creation Toolkit"},
price: "$79.99",
rating: 5,
reviewCount: "1.8k",
imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-ai-content-creation-toolkit-inte-1772864653758-1b13a7eb.png?_wi=1",
imageAlt: "AI Content Creation Toolkit",
},
{ {
id: "3", id: "3", brand: "DigitalPro", name: "Financial Freedom Planner", price: "$39.99", rating: 4,
brand: "DigitalPro", reviewCount: "1.5k", imageSrc:
name: "Financial Freedom Planner", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-financial-planning-and-budgeting-1772864653112-bbdb3d99.png?_wi=1", imageAlt: "Financial Planning Template"},
price: "$39.99",
rating: 4,
reviewCount: "1.5k",
imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-financial-planning-and-budgeting-1772864653112-bbdb3d99.png?_wi=1",
imageAlt: "Financial Planning Template",
},
{ {
id: "4", id: "4", brand: "DigitalPro", name: "E-Commerce Store Builder", price: "$89.99", rating: 5,
brand: "DigitalPro", reviewCount: "2.1k", imageSrc:
name: "E-Commerce Store Builder", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-e-commerce-store-builder-templat-1772864653952-5be26115.png?_wi=1", imageAlt: "E-Commerce Store Template"},
price: "$89.99",
rating: 5,
reviewCount: "2.1k",
imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-e-commerce-store-builder-templat-1772864653952-5be26115.png?_wi=1",
imageAlt: "E-Commerce Store Template",
},
{ {
id: "5", id: "5", brand: "DigitalPro", name: "Social Media Manager Hub", price: "$59.99", rating: 4,
brand: "DigitalPro", reviewCount: "1.9k", imageSrc:
name: "Social Media Manager Hub", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-social-media-management-suite-wi-1772864656333-10d8a93b.png?_wi=1", imageAlt: "Social Media Management Suite"},
price: "$59.99",
rating: 4,
reviewCount: "1.9k",
imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/premium-social-media-management-suite-wi-1772864656333-10d8a93b.png?_wi=1",
imageAlt: "Social Media Management Suite",
},
]} ]}
gridVariant="uniform-all-items-equal" gridVariant="uniform-all-items-equal"
animationType="slide-up" animationType="slide-up"
@@ -240,48 +405,22 @@ export default function HomePage() {
tag="Pricing" tag="Pricing"
plans={[ plans={[
{ {
id: "1", id: "1", badge: "Starter", price: "$0", subtitle: "Perfect for beginners", badgeIcon: Sparkles,
badge: "Starter",
price: "$0",
subtitle: "Perfect for beginners",
badgeIcon: Sparkles,
buttons: [{ text: "Get Started", href: "/contact" }], buttons: [{ text: "Get Started", href: "/contact" }],
features: [ features: [
"5 Free Templates", "5 Free Templates", "Basic Support", "Community Access", "Monthly Updates"],
"Basic Support",
"Community Access",
"Monthly Updates",
],
}, },
{ {
id: "2", id: "2", badge: "Professional", price: "$29.99", subtitle: "Most popular choice", badgeIcon: Star,
badge: "Professional",
price: "$29.99",
subtitle: "Most popular choice",
badgeIcon: Star,
buttons: [{ text: "Subscribe Now", href: "/contact" }], buttons: [{ text: "Subscribe Now", href: "/contact" }],
features: [ features: [
"Unlimited Templates", "Unlimited Templates", "Priority Support", "Advanced Analytics", "Weekly Updates", "Commercial Rights"],
"Priority Support",
"Advanced Analytics",
"Weekly Updates",
"Commercial Rights",
],
}, },
{ {
id: "3", id: "3", badge: "Enterprise", price: "$99.99", subtitle: "For large teams", badgeIcon: Crown,
badge: "Enterprise",
price: "$99.99",
subtitle: "For large teams",
badgeIcon: Crown,
buttons: [{ text: "Contact Sales", href: "/contact" }], buttons: [{ text: "Contact Sales", href: "/contact" }],
features: [ features: [
"Everything in Pro", "Everything in Pro", "Dedicated Account Manager", "Custom Templates", "API Access", "White-label Options"],
"Dedicated Account Manager",
"Custom Templates",
"API Access",
"White-label Options",
],
}, },
]} ]}
animationType="slide-up" animationType="slide-up"
@@ -298,45 +437,21 @@ export default function HomePage() {
tag="Testimonials" tag="Testimonials"
testimonials={[ testimonials={[
{ {
id: "1", id: "1", name: "Sarah Johnson", role: "Founder", company: "TechStartup Co", rating: 5,
name: "Sarah Johnson",
role: "Founder",
company: "TechStartup Co",
rating: 5,
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-successful-en-1772864652282-f00d4c62.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-successful-en-1772864652282-f00d4c62.png", imageAlt: "Sarah Johnson"},
imageAlt: "Sarah Johnson",
},
{ {
id: "2", id: "2", name: "Michael Chen", role: "Product Manager", company: "InnovateLab", rating: 5,
name: "Michael Chen",
role: "Product Manager",
company: "InnovateLab",
rating: 5,
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-confident-fem-1772864652004-ed832249.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-confident-fem-1772864652004-ed832249.png", imageAlt: "Michael Chen"},
imageAlt: "Michael Chen",
},
{ {
id: "3", id: "3", name: "Emily Rodriguez", role: "Marketing Director", company: "GrowthCo", rating: 5,
name: "Emily Rodriguez",
role: "Marketing Director",
company: "GrowthCo",
rating: 5,
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-young-profess-1772864652184-6d0f80b0.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-young-profess-1772864652184-6d0f80b0.png", imageAlt: "Emily Rodriguez"},
imageAlt: "Emily Rodriguez",
},
{ {
id: "4", id: "4", name: "David Kim", role: "CEO", company: "StartupXYZ", rating: 4,
name: "David Kim",
role: "CEO",
company: "StartupXYZ",
rating: 4,
imageSrc: imageSrc:
"https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-business-exec-1772864651875-1760e8d0.png", "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/professional-headshot-of-a-business-exec-1772864651875-1760e8d0.png", imageAlt: "David Kim"},
imageAlt: "David Kim",
},
]} ]}
kpiItems={[ kpiItems={[
{ value: "15k+", label: "Happy Customers" }, { value: "15k+", label: "Happy Customers" },
@@ -371,41 +486,23 @@ export default function HomePage() {
tag="Help" tag="Help"
faqs={[ faqs={[
{ {
id: "1", id: "1", title: "How do I get access to the templates after purchase?", content:
title: "How do I get access to the templates after purchase?", "After purchase, you'll receive instant access to download all files. No waiting, no delays. All templates are immediately available in your account dashboard."},
content:
"After purchase, you'll receive instant access to download all files. No waiting, no delays. All templates are immediately available in your account dashboard.",
},
{ {
id: "2", id: "2", title: "Can I use these templates for commercial purposes?", content:
title: "Can I use these templates for commercial purposes?", "Yes! All our templates include commercial rights. You can use them for client projects, resell modified versions, and use them for business purposes with no restrictions."},
content:
"Yes! All our templates include commercial rights. You can use them for client projects, resell modified versions, and use them for business purposes with no restrictions.",
},
{ {
id: "3", id: "3", title: "What if I'm not satisfied with a template?", content:
title: "What if I'm not satisfied with a template?", "We offer a 30-day money-back guarantee. If you're not completely satisfied, simply request a refund and we'll process it within 24 hours."},
content:
"We offer a 30-day money-back guarantee. If you're not completely satisfied, simply request a refund and we'll process it within 24 hours.",
},
{ {
id: "4", id: "4", title: "Do you provide updates and support?", content:
title: "Do you provide updates and support?", "Absolutely! All templates receive regular updates with new features and improvements. Our support team is available 24/7 to help you with any questions."},
content:
"Absolutely! All templates receive regular updates with new features and improvements. Our support team is available 24/7 to help you with any questions.",
},
{ {
id: "5", id: "5", title: "Are the templates compatible with the latest software versions?", content:
title: "Are the templates compatible with the latest software versions?", "Yes, all templates are regularly updated to ensure compatibility with the latest software versions and tools."},
content:
"Yes, all templates are regularly updated to ensure compatibility with the latest software versions and tools.",
},
{ {
id: "6", id: "6", title: "What payment methods do you accept?", content:
title: "What payment methods do you accept?", "We accept all major credit cards, PayPal, and various international payment methods. Your payment is processed securely and encrypted."},
content:
"We accept all major credit cards, PayPal, and various international payment methods. Your payment is processed securely and encrypted.",
},
]} ]}
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/friendly-minimalist-illustration-of-a-pe-1772864652653-3d5f063c.png?_wi=1" imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AaqWADaE26HPuu9McAi5WY1Ok3/friendly-minimalist-illustration-of-a-pe-1772864652653-3d5f063c.png?_wi=1"
imageAlt="Customer Support Illustration" imageAlt="Customer Support Illustration"
@@ -440,4 +537,4 @@ export default function HomePage() {
</div> </div>
</ThemeProvider> </ThemeProvider>
); );
} }

View File

@@ -0,0 +1,362 @@
"use client";
import { useState } from "react";
import { CreditCard, Lock, AlertCircle } from "lucide-react";
import Input from "@/components/form/Input";
interface PaymentFormData {
cardNumber: string;
cardholderName: string;
expiryMonth: string;
expiryYear: string;
cvv: string;
billingAddress: string;
billingCity: string;
billingState: string;
billingZip: string;
billingCountry: string;
}
export default function PaymentTerminal() {
const [formData, setFormData] = useState<PaymentFormData>({
cardNumber: "", cardholderName: "", expiryMonth: "", expiryYear: "", cvv: "", billingAddress: "", billingCity: "", billingState: "", billingZip: "", billingCountry: ""});
const [errors, setErrors] = useState<Record<string, string>>({});
const [isProcessing, setIsProcessing] = useState(false);
const [successMessage, setSuccessMessage] = useState("");
const handleInputChange = (field: keyof PaymentFormData, value: string) => {
setFormData((prev) => ({
...prev,
[field]: value,
}));
// Clear error for this field when user starts typing
if (errors[field]) {
setErrors((prev) => ({
...prev,
[field]: ""}));
}
};
const formatCardNumber = (value: string) => {
const cleaned = value.replace(/\D/g, "");
const formatted = cleaned
.slice(0, 16)
.replace(/\s/g, "")
.replace(/(\d{4})/g, "$1 ")
.trim();
return formatted;
};
const formatCVV = (value: string) => {
return value.replace(/\D/g, "").slice(0, 4);
};
const validateForm = (): boolean => {
const newErrors: Record<string, string> = {};
if (!formData.cardNumber || formData.cardNumber.replace(/\s/g, "").length !== 16) {
newErrors.cardNumber = "Valid card number required (16 digits)";
}
if (!formData.cardholderName.trim()) {
newErrors.cardholderName = "Cardholder name required";
}
if (!formData.expiryMonth || !formData.expiryYear) {
newErrors.expiry = "Expiry date required";
}
if (!formData.cvv || formData.cvv.length < 3) {
newErrors.cvv = "Valid CVV required (3-4 digits)";
}
if (!formData.billingAddress.trim()) {
newErrors.billingAddress = "Billing address required";
}
if (!formData.billingCity.trim()) {
newErrors.billingCity = "City required";
}
if (!formData.billingZip.trim()) {
newErrors.billingZip = "ZIP code required";
}
if (!formData.billingCountry.trim()) {
newErrors.billingCountry = "Country required";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) {
return;
}
setIsProcessing(true);
setSuccessMessage("");
// Simulate payment processing
try {
await new Promise((resolve) => setTimeout(resolve, 2000));
setSuccessMessage("Payment processed successfully! Your transaction is complete.");
// Reset form
setFormData({
cardNumber: "", cardholderName: "", expiryMonth: "", expiryYear: "", cvv: "", billingAddress: "", billingCity: "", billingState: "", billingZip: "", billingCountry: ""});
} catch (error) {
setErrors({ submit: "Payment failed. Please try again." });
} finally {
setIsProcessing(false);
}
};
return (
<section className="py-20 px-6">
<div className="max-w-2xl mx-auto">
{/* Header */}
<div className="text-center mb-12">
<div className="flex items-center justify-center mb-4">
<CreditCard className="w-8 h-8 text-accent" />
</div>
<h2 className="text-4xl md:text-5xl font-bold mb-4">Payment Terminal</h2>
<p className="text-foreground/70 text-lg">Securely enter your payment information below</p>
</div>
{/* Payment Form */}
<div className="bg-card rounded-lg p-8 border border-accent/10">
{/* Security Badge */}
<div className="flex items-center justify-center gap-2 mb-8 pb-8 border-b border-accent/10">
<Lock className="w-4 h-4 text-accent" />
<span className="text-sm text-foreground/60">Your payment information is secure and encrypted</span>
</div>
{successMessage && (
<div className="mb-6 p-4 bg-green-500/10 border border-green-500/20 rounded-lg flex items-start gap-3">
<div className="w-5 h-5 rounded-full bg-green-500 flex items-center justify-center flex-shrink-0 mt-0.5">
<span className="text-white text-sm"></span>
</div>
<p className="text-green-600 dark:text-green-400 text-sm">{successMessage}</p>
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
{/* Card Information */}
<div>
<h3 className="text-lg font-semibold mb-4">Card Information</h3>
<div className="space-y-4">
{/* Card Number */}
<div>
<label className="block text-sm font-medium mb-2">Card Number</label>
<Input
value={formData.cardNumber}
onChange={(value) => handleInputChange("cardNumber", formatCardNumber(value))}
placeholder="1234 5678 9012 3456"
type="text"
required
/>
{errors.cardNumber && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.cardNumber}
</p>
)}
</div>
{/* Cardholder Name */}
<div>
<label className="block text-sm font-medium mb-2">Cardholder Name</label>
<Input
value={formData.cardholderName}
onChange={(value) => handleInputChange("cardholderName", value)}
placeholder="John Doe"
type="text"
required
/>
{errors.cardholderName && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.cardholderName}
</p>
)}
</div>
{/* Expiry and CVV */}
<div className="grid grid-cols-3 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Month</label>
<Input
value={formData.expiryMonth}
onChange={(value) =>
handleInputChange(
"expiryMonth", value.replace(/\D/g, "").slice(0, 2)
)
}
placeholder="MM"
type="text"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Year</label>
<Input
value={formData.expiryYear}
onChange={(value) =>
handleInputChange(
"expiryYear", value.replace(/\D/g, "").slice(0, 2)
)
}
placeholder="YY"
type="text"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">CVV</label>
<Input
value={formData.cvv}
onChange={(value) => handleInputChange("cvv", formatCVV(value))}
placeholder="123"
type="password"
required
/>
</div>
</div>
{errors.expiry && (
<p className="text-red-500 text-xs flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.expiry}
</p>
)}
{errors.cvv && (
<p className="text-red-500 text-xs flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.cvv}
</p>
)}
</div>
</div>
{/* Billing Address */}
<div>
<h3 className="text-lg font-semibold mb-4">Billing Address</h3>
<div className="space-y-4">
{/* Address */}
<div>
<label className="block text-sm font-medium mb-2">Street Address</label>
<Input
value={formData.billingAddress}
onChange={(value) => handleInputChange("billingAddress", value)}
placeholder="123 Main Street"
type="text"
required
/>
{errors.billingAddress && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.billingAddress}
</p>
)}
</div>
{/* City, State, ZIP */}
<div className="grid grid-cols-3 gap-4">
<div>
<label className="block text-sm font-medium mb-2">City</label>
<Input
value={formData.billingCity}
onChange={(value) => handleInputChange("billingCity", value)}
placeholder="New York"
type="text"
required
/>
{errors.billingCity && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.billingCity}
</p>
)}
</div>
<div>
<label className="block text-sm font-medium mb-2">State</label>
<Input
value={formData.billingState}
onChange={(value) => handleInputChange("billingState", value)}
placeholder="NY"
type="text"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">ZIP Code</label>
<Input
value={formData.billingZip}
onChange={(value) => handleInputChange("billingZip", value)}
placeholder="10001"
type="text"
required
/>
{errors.billingZip && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.billingZip}
</p>
)}
</div>
</div>
{/* Country */}
<div>
<label className="block text-sm font-medium mb-2">Country</label>
<Input
value={formData.billingCountry}
onChange={(value) => handleInputChange("billingCountry", value)}
placeholder="United States"
type="text"
required
/>
{errors.billingCountry && (
<p className="text-red-500 text-xs mt-1 flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{errors.billingCountry}
</p>
)}
</div>
</div>
</div>
{/* Submit Error */}
{errors.submit && (
<div className="p-4 bg-red-500/10 border border-red-500/20 rounded-lg flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5" />
<p className="text-red-600 dark:text-red-400 text-sm">{errors.submit}</p>
</div>
)}
{/* Submit Button */}
<button
type="submit"
disabled={isProcessing}
className="w-full py-3 px-6 bg-primary-cta hover:bg-primary-cta/90 disabled:bg-primary-cta/50 text-white font-semibold rounded-lg transition-colors duration-200 flex items-center justify-center gap-2"
>
{isProcessing ? (
<>
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
Processing...
</>
) : (
<>
<Lock className="w-4 h-4" />
Process Payment
</>
)}
</button>
</form>
</div>
</div>
</section>
);
}