Compare commits

..

10 Commits

Author SHA1 Message Date
3bc52d60c3 upgraded dependencies 2025-12-17 15:19:58 +03:00
Mohammed Al-yaseen
5f050a7a60 enhance footer mobile style & implement footer in each page 2025-08-02 15:36:11 +03:00
Mohammed Al-yaseen
7bcbea35e1 enhance the home page UI 2025-08-02 15:15:37 +03:00
Mohammed Al-yaseen
e6a3bd1fd5 enhance loader design 2025-08-02 02:25:27 +03:00
Mohammed Al-yaseen
e627594be9 site enhancements and add missing parts 2025-08-02 02:01:29 +03:00
Mohammed Al-yaseen
01ed3a2b7f enhance ssr, add routes and enhance the header styles 2025-07-29 16:12:21 +03:00
Mohammed Al-yaseen
b803532cde add some projects urls 2025-07-28 11:32:31 +03:00
Mohammed Al-yaseen
e32ddaa2db enhance headers styles & update colors palette 2025-07-28 11:32:05 +03:00
Mohammed Al-yaseen
b2896c379f ProjectsShowcase: add details modal 2025-07-28 10:40:33 +03:00
Mohammed Al-yaseen
c9998ce4e0 fixes 2025-07-28 02:08:21 +03:00
39 changed files with 9412 additions and 2171 deletions

View File

@@ -1,16 +1,6 @@
import { dirname } from "path"; import coreWebVitals from "eslint-config-next/core-web-vitals";
import { fileURLToPath } from "url"; import typescript from "eslint-config-next/typescript";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url); const config = [...coreWebVitals, ...typescript];
const __dirname = dirname(__filename);
const compat = new FlatCompat({ export default config;
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
export default eslintConfig;

View File

@@ -1,7 +1,14 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ images: {
remotePatterns: [
{
protocol: "https",
hostname: "techmasters.space",
},
],
},
}; };
export default nextConfig; export default nextConfig;

View File

@@ -2,26 +2,27 @@
"name": "antd-demo", "name": "antd-demo",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"packageManager": "yarn@1.22.22",
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev --turbopack",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start -p 4000",
"lint": "next lint" "lint": "eslint ."
}, },
"dependencies": { "dependencies": {
"antd": "^5.24.6", "antd": "^6.1.1",
"framer-motion": "^12.6.3", "framer-motion": "^12.23.26",
"next": "15.2.4", "next": "16.0.10",
"react": "^19.0.0", "react": "^19.2.3",
"react-dom": "^19.0.0" "react-dom": "^19.2.3"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3", "@eslint/eslintrc": "^3.3.3",
"@types/node": "^20", "@types/node": "^20.19.27",
"@types/react": "^19", "@types/react": "^19.2.7",
"@types/react-dom": "^19", "@types/react-dom": "^19.2.3",
"eslint": "^9", "eslint": "^9.39.2",
"eslint-config-next": "15.2.4", "eslint-config-next": "16.0.10",
"typescript": "^5" "typescript": "5.8.3"
} }
} }

32
src/app/about/layout.tsx Normal file
View File

@@ -0,0 +1,32 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "About Us | Tech Master - Award-Winning IT Solutions Dubai",
description: "Learn about Tech Master, an award-winning Dubai-based technology agency specializing in digital transformation, web development, and innovative IT solutions since 2020.",
keywords: [
"about Tech Master",
"Dubai IT company",
"award-winning tech agency",
"digital transformation company",
"web development company Dubai",
"IT solutions provider",
"tech company Dubai",
"software development company"
],
openGraph: {
title: "About Us | Tech Master - Award-Winning IT Solutions Dubai",
description: "Learn about Tech Master, an award-winning Dubai-based technology agency specializing in digital transformation and innovative IT solutions.",
url: "https://tech-masters.guru/about",
},
alternates: {
canonical: "/about",
},
};
export default function AboutLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -0,0 +1,598 @@
/* About Page Styles */
.main {
padding-top: 80px;
background-color: #f9fafb;
}
/* Hero Section */
.heroSection {
position: relative;
padding: 128px 0;
background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
color: white;
overflow: hidden;
}
.backgroundPattern {
position: absolute;
inset: 0;
opacity: 0.1;
}
.floatingOrb1 {
position: absolute;
top: 0;
left: 0;
width: 288px;
height: 288px;
background-color: #8b5cf6;
border-radius: 50%;
mix-blend-mode: multiply;
filter: blur(24px);
animation: pulse 2s infinite;
}
.floatingOrb2 {
position: absolute;
top: 0;
right: 0;
width: 288px;
height: 288px;
background-color: #eab308;
border-radius: 50%;
mix-blend-mode: multiply;
filter: blur(24px);
animation: pulse 2s infinite;
animation-delay: 2s;
}
.floatingOrb3 {
position: absolute;
bottom: -32px;
left: 80px;
width: 288px;
height: 288px;
background-color: #ec4899;
border-radius: 50%;
mix-blend-mode: multiply;
filter: blur(24px);
animation: pulse 2s infinite;
animation-delay: 4s;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.heroContent {
position: relative;
max-width: 1152px;
margin: 0 auto;
padding: 0 16px;
}
.heroTitle {
font-size: 60px;
font-weight: 700;
margin-bottom: 32px;
line-height: 1.2;
color: white;
}
.gradientText {
background: linear-gradient(135deg, #a855f7 0%, #ec4899 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.heroSubtitle {
font-size: 20px;
color: #d1d5db;
max-width: 1024px;
margin: 0 auto;
line-height: 1.6;
}
.heroIcon {
width: 80px;
height: 80px;
margin: 0 auto 24px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.trustBadge {
display: inline-flex;
align-items: center;
gap: 8px;
background-color: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(8px);
border-radius: 9999px;
padding: 12px 24px;
margin-top: 32px;
}
.trustBadgeIcon {
color: #f87171;
}
.trustBadgeText {
color: #e5e7eb;
}
/* Stats Section */
.statsSection {
padding: 96px 0;
background-color: white;
position: relative;
}
.statsBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, #faf5ff 0%, #fdf2f8 100%);
}
.statsContainer {
position: relative;
max-width: 1152px;
margin: 0 auto;
padding: 0 16px;
}
.statsHeader {
text-align: center;
margin-bottom: 64px;
}
.statsTitle {
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
color: #1f2937;
}
.statsSubtitle {
font-size: 18px;
color: #6b7280;
max-width: 512px;
margin: 0 auto;
}
.statCard {
text-align: center;
transition: all 0.3s ease;
}
.statCard:hover {
transform: translateY(-4px);
}
.statIcon {
width: 80px;
height: 80px;
margin: 0 auto 24px;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.statCard:hover .statIcon {
transform: scale(1.1);
}
.statIconYellow {
background: linear-gradient(135deg, #fbbf24 0%, #f97316 100%);
}
.statIconBlue {
background: linear-gradient(135deg, #60a5fa 0%, #8b5cf6 100%);
}
.statIconGreen {
background: linear-gradient(135deg, #4ade80 0%, #14b8a6 100%);
}
.statIconPink {
background: linear-gradient(135deg, #f472b6 0%, #ef4444 100%);
}
.statNumber {
font-size: 36px;
font-weight: 700;
margin-bottom: 8px;
color: #1f2937;
transition: color 0.3s ease;
}
.statCard:hover .statNumber {
color: #8b5cf6;
}
.statLabel {
color: #6b7280;
font-weight: 500;
}
/* Story Section */
.storySection {
padding: 96px 0;
background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);
position: relative;
overflow: hidden;
}
.storyBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(236, 72, 153, 0.1) 100%);
}
.storyContainer {
position: relative;
max-width: 1152px;
margin: 0 auto;
padding: 0 16px;
}
.journeyBadge {
display: inline-flex;
align-items: center;
gap: 8px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
color: white;
padding: 8px 16px;
border-radius: 9999px;
font-size: 14px;
font-weight: 500;
margin-bottom: 24px;
}
.storyTitle {
font-size: 48px;
font-weight: 700;
margin-bottom: 32px;
line-height: 1.2;
color: #1f2937;
}
.storyText {
font-size: 18px;
color: #374151;
margin-bottom: 32px;
line-height: 1.6;
}
.timelineGrid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
margin-top: 32px;
}
.timelineCard {
text-align: center;
padding: 16px;
background-color: white;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #f3f4f6;
}
.timelineYear {
font-size: 24px;
font-weight: 700;
margin-bottom: 4px;
color: #8b5cf6;
}
.timelineLabel {
font-size: 14px;
color: #6b7280;
}
.storyVisual {
text-align: center;
position: relative;
}
.mainCircle {
width: 320px;
height: 320px;
margin: 0 auto;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 50%, #f97316 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
}
.mainIcon {
font-size: 96px;
color: white;
}
.floatingBadge1 {
position: absolute;
top: -16px;
right: -16px;
width: 96px;
height: 96px;
background: linear-gradient(135deg, #eab308 0%, #f97316 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
.floatingBadge2 {
position: absolute;
bottom: -16px;
left: -16px;
width: 80px;
height: 80px;
background: linear-gradient(135deg, #4ade80 0%, #14b8a6 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
.badgeIcon {
color: white;
}
/* Values Section */
.valuesSection {
padding: 96px 0;
background-color: white;
position: relative;
}
.valuesBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);
}
.valuesContainer {
position: relative;
max-width: 1152px;
margin: 0 auto;
padding: 0 16px;
}
.valuesHeader {
text-align: center;
margin-bottom: 64px;
}
.valuesTitle {
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
color: #1f2937;
}
.valuesSubtitle {
font-size: 18px;
color: #6b7280;
max-width: 512px;
margin: 0 auto;
}
.valueCard {
height: 100%;
text-align: center;
transition: all 0.3s ease;
border: none;
background-color: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
}
.valueCard:hover {
background-color: white;
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1);
}
.valueCardBody {
padding: 32px;
}
.valueIcon {
width: 64px;
height: 64px;
margin: 0 auto 24px;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.valueCard:hover .valueIcon {
transform: scale(1.1);
}
.valueIconBlue {
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
}
.valueIconYellow {
background: linear-gradient(135deg, #eab308 0%, #f97316 100%);
}
.valueIconGreen {
background: linear-gradient(135deg, #22c55e 0%, #14b8a6 100%);
}
.valueIconIndigo {
background: linear-gradient(135deg, #6366f1 0%, #3b82f6 100%);
}
.valueTitle {
margin-bottom: 16px;
color: #1f2937;
transition: color 0.3s ease;
}
.valueCard:hover .valueTitle {
color: #8b5cf6;
}
.valueDescription {
color: #6b7280;
line-height: 1.6;
}
/* Team Section */
.teamSection {
padding: 96px 0;
background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);
position: relative;
}
.teamBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(236, 72, 153, 0.1) 100%);
}
.teamContainer {
position: relative;
max-width: 1152px;
margin: 0 auto;
padding: 0 16px;
}
.teamHeader {
text-align: center;
margin-bottom: 64px;
}
.teamTitle {
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
color: #1f2937;
}
.teamSubtitle {
font-size: 18px;
color: #6b7280;
max-width: 512px;
margin: 0 auto;
}
.teamCard {
height: 100%;
text-align: center;
transition: all 0.3s ease;
border: none;
background-color: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
}
.teamCard:hover {
background-color: white;
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1);
}
.avatarContainer {
position: relative;
margin-bottom: 24px;
}
.teamAvatar {
margin: 0 auto;
border: 4px solid white;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
transition: transform 0.3s ease;
}
.teamCard:hover .teamAvatar {
transform: scale(1.05);
}
.verificationBadge {
position: absolute;
bottom: -8px;
right: -8px;
width: 32px;
height: 32px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.verificationIcon {
font-size: 14px;
color: white;
}
.teamMemberName {
margin-bottom: 8px;
color: #1f2937;
transition: color 0.3s ease;
}
.teamCard:hover .teamMemberName {
color: #8b5cf6;
}
.teamMemberRole {
color: #6b7280;
margin-bottom: 12px;
font-weight: 500;
}
.teamMemberDescription {
font-size: 14px;
color: #6b7280;
line-height: 1.6;
}
/* Responsive Design */
@media (max-width: 768px) {
.heroTitle {
font-size: 48px;
}
.mainCircle {
width: 240px;
height: 240px;
}
.mainIcon {
font-size: 72px;
}
.timelineGrid {
grid-template-columns: 1fr;
}
.floatingOrb1,
.floatingOrb2,
.floatingOrb3 {
width: 200px;
height: 200px;
}
}

399
src/app/about/page.tsx Normal file
View File

@@ -0,0 +1,399 @@
"use client";
import {
BulbOutlined,
CheckCircleOutlined,
GlobalOutlined,
HeartOutlined,
RocketOutlined,
StarOutlined,
TeamOutlined,
TrophyOutlined,
} from "@ant-design/icons";
import { Avatar, Card, Col, Row } from "antd";
import Paragraph from "antd/es/typography/Paragraph";
import Title from "antd/es/typography/Title";
import { motion } from "framer-motion";
import Footer from "../components/Footer/Footer";
import styles from "./page.module.css";
export default function AboutPage() {
const stats = [
{
icon: <TrophyOutlined />,
number: "50+",
label: "Projects Completed",
color: "from-yellow-400 to-orange-500",
},
{
icon: <GlobalOutlined />,
number: "25+",
label: "Happy Clients",
color: "from-blue-400 to-purple-500",
},
{
icon: <TeamOutlined />,
number: "15+",
label: "Expert Developers",
color: "from-green-400 to-teal-500",
},
{
icon: <RocketOutlined />,
number: "3+",
label: "Years Experience",
color: "from-pink-400 to-red-500",
},
];
const values = [
{
title: "Innovation First",
description:
"We stay ahead of technology trends to deliver cutting-edge solutions that give our clients a competitive advantage.",
icon: <RocketOutlined />,
color: "from-blue-500 to-purple-600",
},
{
title: "Quality Excellence",
description:
"Every project is crafted with attention to detail, ensuring the highest standards of quality and performance.",
icon: <StarOutlined />,
color: "from-yellow-500 to-orange-600",
},
{
title: "Client Success",
description:
"Your success is our success. We work closely with clients to understand their needs and deliver solutions that exceed expectations.",
icon: <CheckCircleOutlined />,
color: "from-green-500 to-teal-600",
},
{
title: "Transparency",
description:
"We believe in open communication and transparent processes, keeping you informed at every step of your project.",
icon: <GlobalOutlined />,
color: "from-indigo-500 to-blue-600",
},
];
const teamMembers = [
{
name: "Ahmed Hassan",
role: "CEO & Founder",
description: "Visionary leader with 10+ years in digital transformation",
avatar: "https://randomuser.me/api/portraits/men/32.jpg",
delay: 0,
},
{
name: "Sarah Johnson",
role: "CTO",
description: "Technical expert specializing in AI and cloud solutions",
avatar: "https://randomuser.me/api/portraits/women/44.jpg",
delay: 0.1,
},
{
name: "Raj Patel",
role: "Lead Developer",
description: "Full-stack developer with expertise in modern frameworks",
avatar: "https://randomuser.me/api/portraits/men/67.jpg",
delay: 0.2,
},
];
return (
<main className={styles.main}>
{/* Hero Section */}
<section className={styles.heroSection}>
{/* Background Pattern */}
<div className={styles.backgroundPattern}>
<div className={styles.floatingOrb1}></div>
<div className={styles.floatingOrb2}></div>
<div className={styles.floatingOrb3}></div>
</div>
<div className={styles.heroContent}>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className="text-center"
>
<motion.div
initial={{ scale: 0.8 }}
animate={{ scale: 1 }}
transition={{ duration: 0.6, delay: 0.2 }}
className="inline-block mb-6"
>
<div className={styles.heroIcon}>
<BulbOutlined style={{ fontSize: "32px", color: "white" }} />
</div>
</motion.div>
<Title level={1} className={styles.heroTitle}>
About <span className={styles.gradientText}>Tech Master</span>
</Title>
<Paragraph className={styles.heroSubtitle}>
From Dubai to the stars, we&apos;re an award-winning technology
agency dedicated to transforming businesses through innovative
digital solutions that drive growth and success.
</Paragraph>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.4 }}
className="mt-8"
>
<div className={styles.trustBadge}>
<HeartOutlined className={styles.trustBadgeIcon} />
<span className={styles.trustBadgeText}>
Trusted by 25+ companies worldwide
</span>
</div>
</motion.div>
</motion.div>
</div>
</section>
{/* Stats Section */}
<section className={styles.statsSection}>
<div className={styles.statsBackground}></div>
<div className={styles.statsContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className={styles.statsHeader}
>
<Title level={2} className={styles.statsTitle}>
Our <span className={styles.gradientText}>Achievements</span>
</Title>
<Paragraph className={styles.statsSubtitle}>
Numbers that speak for our commitment to excellence and innovation
</Paragraph>
</motion.div>
<Row gutter={[32, 32]} justify="center">
{stats.map((stat, index) => (
<Col xs={24} sm={12} md={6} key={index}>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: index * 0.1 }}
className={styles.statCard}
>
<div
className={`${styles.statIcon} ${
stat.color.includes("yellow")
? styles.statIconYellow
: stat.color.includes("blue")
? styles.statIconBlue
: stat.color.includes("green")
? styles.statIconGreen
: styles.statIconPink
}`}
>
<div style={{ fontSize: "24px", color: "white" }}>
{stat.icon}
</div>
</div>
<div className={styles.statNumber}>{stat.number}</div>
<div className={styles.statLabel}>{stat.label}</div>
</motion.div>
</Col>
))}
</Row>
</div>
</section>
{/* Story Section */}
<section className={styles.storySection}>
<div className={styles.storyBackground}></div>
<div className={styles.storyContainer}>
<Row gutter={[64, 64]} align="middle">
<Col xs={24} lg={12}>
<motion.div
initial={{ opacity: 0, x: -30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.8 }}
>
<div className={styles.journeyBadge}>
<RocketOutlined />
<span>Our Journey</span>
</div>
<Title level={2} className={styles.storyTitle}>
Our <span className={styles.gradientText}>Story</span>
</Title>
<Paragraph className={styles.storyText}>
Founded in 2020, Tech Master emerged from a vision to bridge
the gap between traditional business practices and
cutting-edge technology. Based in Dubai, we&apos;ve grown from
a small startup to an award-winning technology agency serving
clients across the UAE and beyond.
</Paragraph>
<Paragraph className={styles.storyText}>
Our journey has been marked by continuous innovation,
unwavering commitment to quality, and a deep understanding of
our clients&apos; needs. We believe that technology should be
an enabler, not a barrier, and we work tirelessly to make
digital transformation accessible to businesses of all sizes.
</Paragraph>
<div className={styles.timelineGrid}>
<div className={styles.timelineCard}>
<div className={styles.timelineYear}>2020</div>
<div className={styles.timelineLabel}>Founded</div>
</div>
<div className={styles.timelineCard}>
<div className={styles.timelineYear}>2024</div>
<div className={styles.timelineLabel}>Award Winner</div>
</div>
</div>
</motion.div>
</Col>
<Col xs={24} lg={12}>
<motion.div
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.8 }}
className={styles.storyVisual}
>
<div className="relative">
<div className={styles.mainCircle}>
<GlobalOutlined className={styles.mainIcon} />
</div>
<div className={styles.floatingBadge1}>
<TrophyOutlined className={styles.badgeIcon} />
</div>
<div className={styles.floatingBadge2}>
<StarOutlined className={styles.badgeIcon} />
</div>
</div>
</motion.div>
</Col>
</Row>
</div>
</section>
{/* Values Section */}
<section className={styles.valuesSection}>
<div className={styles.valuesBackground}></div>
<div className={styles.valuesContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className={styles.valuesHeader}
>
<Title level={2} className={styles.valuesTitle}>
Our <span className={styles.gradientText}>Values</span>
</Title>
<Paragraph className={styles.valuesSubtitle}>
These core values guide everything we do and shape the way we
approach every project and client relationship.
</Paragraph>
</motion.div>
<Row gutter={[32, 32]}>
{values.map((value, index) => (
<Col xs={24} sm={12} lg={6} key={index}>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: index * 0.1 }}
className="h-full"
>
<Card
className={styles.valueCard}
bodyStyle={{ padding: "2rem" }}
>
<div
className={`${styles.valueIcon} ${
value.color.includes("blue")
? styles.valueIconBlue
: value.color.includes("yellow")
? styles.valueIconYellow
: value.color.includes("green")
? styles.valueIconGreen
: styles.valueIconIndigo
}`}
>
<div style={{ fontSize: "24px", color: "white" }}>
{value.icon}
</div>
</div>
<Title level={4} className={styles.valueTitle}>
{value.title}
</Title>
<Paragraph className={styles.valueDescription}>
{value.description}
</Paragraph>
</Card>
</motion.div>
</Col>
))}
</Row>
</div>
</section>
{/* Team Section */}
<section className={styles.teamSection}>
<div className={styles.teamBackground}></div>
<div className={styles.teamContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className={styles.teamHeader}
>
<Title level={2} className={styles.teamTitle}>
Meet Our <span className={styles.gradientText}>Team</span>
</Title>
<Paragraph className={styles.teamSubtitle}>
Meet the passionate professionals behind Tech Master&apos;s
success. Our diverse team brings together expertise from various
domains to deliver exceptional results.
</Paragraph>
</motion.div>
<Row gutter={[32, 32]} justify="center">
{teamMembers.map((member, index) => (
<Col xs={24} sm={12} md={8} key={index}>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: member.delay }}
className="text-center group"
>
<Card className={styles.teamCard}>
<div className={styles.avatarContainer}>
<Avatar
size={140}
src={member.avatar}
className={styles.teamAvatar}
/>
<div className={styles.verificationBadge}>
<StarOutlined className={styles.verificationIcon} />
</div>
</div>
<Title level={4} className={styles.teamMemberName}>
{member.name}
</Title>
<Paragraph className={styles.teamMemberRole}>
{member.role}
</Paragraph>
<Paragraph className={styles.teamMemberDescription}>
{member.description}
</Paragraph>
</Card>
</motion.div>
</Col>
))}
</Row>
</div>
</section>
<Footer />
</main>
);
}

View File

@@ -1,242 +0,0 @@
// File: src/components/home/ContactSection.tsx
import {
EnvironmentOutlined,
MailOutlined,
PhoneOutlined,
SendOutlined,
} from "@ant-design/icons";
import { Button, Col, Form, Input, message, Row, Typography } from "antd";
import { motion } from "framer-motion";
import Image from "next/image";
import React, { useState } from "react";
import styles from "./ContactSection.module.css";
const { Title, Paragraph, Text } = Typography;
const { TextArea } = Input;
const ContactSection: React.FC = () => {
const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false);
const handleSubmit = async () => {
setSubmitting(true);
// Simulate API call
setTimeout(() => {
message.success("Your message has been sent successfully!");
form.resetFields();
setSubmitting(false);
}, 1500);
};
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
},
},
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 },
},
};
return (
<section className={styles.contactSection}>
<div className={styles.backgroundElements}>
<div className={styles.glowOrbTop}></div>
<div className={styles.glowOrbBottom}></div>
</div>
<div className={styles.container}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className={styles.sectionHeader}
>
<Title level={2} className={styles.sectionTitle}>
Get In Touch
</Title>
<Paragraph className={styles.sectionSubtitle}>
Ready to transform your ideas into reality? Contact us today.
</Paragraph>
</motion.div>
<Row gutter={[48, 48]} className={styles.contactContent}>
<Col xs={24} lg={10}>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.contactInfo}
>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div className={styles.iconWrapper}>
<MailOutlined className={styles.contactIcon} />
</div>
<div>
<Text strong className={styles.contactLabel}>
Email
</Text>
<Text className={styles.contactValue}>
info@techmaster.com
</Text>
</div>
</motion.div>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div className={styles.iconWrapper}>
<PhoneOutlined className={styles.contactIcon} />
</div>
<div>
<Text strong className={styles.contactLabel}>
Phone
</Text>
<Text className={styles.contactValue}>+1 (555) 123-4567</Text>
</div>
</motion.div>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div className={styles.iconWrapper}>
<EnvironmentOutlined className={styles.contactIcon} />
</div>
<div>
<Text strong className={styles.contactLabel}>
Address
</Text>
<Text className={styles.contactValue}>
1234 Tech Boulevard, Innovation District
<br />
San Francisco, CA 94105
</Text>
</div>
</motion.div>
<motion.div
variants={itemVariants}
className={styles.mapContainer}
>
<Image
src="/api/placeholder/400/200"
alt="Office Location Map"
className={styles.mapImage}
width={400}
height={400}
/>
</motion.div>
</motion.div>
</Col>
<Col xs={24} lg={14}>
<motion.div
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
viewport={{ once: true }}
className={styles.contactForm}
>
<Title level={4} className={styles.formTitle}>
Send Us a Message
</Title>
<Form
form={form}
layout="vertical"
onFinish={handleSubmit}
className={styles.form}
>
<Row gutter={16}>
<Col xs={24} sm={12}>
<Form.Item
name="name"
label="Name"
rules={[
{ required: true, message: "Please enter your name" },
]}
>
<Input size="large" placeholder="Your name" />
</Form.Item>
</Col>
<Col xs={24} sm={12}>
<Form.Item
name="email"
label="Email"
rules={[
{ required: true, message: "Please enter your email" },
{
type: "email",
message: "Please enter a valid email",
},
]}
>
<Input size="large" placeholder="Your email" />
</Form.Item>
</Col>
</Row>
<Form.Item
name="subject"
label="Subject"
rules={[
{ required: true, message: "Please enter a subject" },
]}
>
<Input size="large" placeholder="How can we help you?" />
</Form.Item>
<Form.Item
name="message"
label="Message"
rules={[
{ required: true, message: "Please enter your message" },
]}
>
<TextArea
rows={5}
placeholder="Tell us about your project..."
className={styles.messageInput}
/>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
size="large"
icon={<SendOutlined />}
loading={submitting}
className={styles.submitButton}
>
Send Message
</Button>
</Form.Item>
</Form>
</motion.div>
</Col>
</Row>
</div>
</section>
);
};
export default ContactSection;

View File

@@ -1,190 +0,0 @@
/* File: src/components/home/ContactSection.module.css */
.contactSection {
padding: 100px 0;
background-color: #f8f9fa;
position: relative;
overflow: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
position: relative;
z-index: 2;
}
.backgroundElements {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 1;
}
.glowOrbTop {
position: absolute;
width: 400px;
height: 400px;
border-radius: 50%;
background: var(--primary-glow);
top: -200px;
left: -150px;
filter: blur(50px);
}
.glowOrbBottom {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(64, 169, 255, 0.15) 0%,
rgba(64, 169, 255, 0.05) 50%,
rgba(0, 0, 0, 0) 70%
);
bottom: -250px;
right: -200px;
filter: blur(60px);
}
.sectionHeader {
text-align: center;
margin-bottom: 60px;
}
.sectionTitle {
font-size: 2.5rem !important;
font-weight: 700 !important;
margin-bottom: 16px !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.sectionSubtitle {
font-size: 1.1rem;
color: #666;
max-width: 600px;
margin: 0 auto;
}
.contactContent {
background: rgba(255, 255, 255, 0.8);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.05);
backdrop-filter: blur(8px);
padding: 40px;
}
.contactInfo {
display: flex;
flex-direction: column;
gap: 24px;
}
.contactInfoItem {
display: flex;
align-items: center;
gap: 16px;
}
.iconWrapper {
width: 48px;
height: 48px;
border-radius: 50%;
background: var(--primary);
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 4px 8px rgba(152, 71, 232, 0.2);
}
.contactIcon {
font-size: 20px;
color: #fff;
}
.contactLabel {
display: block;
margin-bottom: 4px;
font-size: 16px;
}
.contactValue {
color: #666;
font-size: 15px;
}
.mapContainer {
margin-top: 16px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.mapImage {
width: 100%;
height: auto;
display: block;
}
.contactForm {
background: white;
border-radius: 12px;
padding: 32px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
}
.formTitle {
margin-bottom: 24px !important;
color: #1890ff;
}
.messageInput {
resize: none;
}
.submitButton {
height: 48px;
padding: 0 32px;
border-radius: 24px;
font-weight: 500;
border: none;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
transition: all 0.3s ease;
}
.submitButton:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(24, 144, 255, 0.2);
}
@media (max-width: 992px) {
.contactContent {
padding: 24px;
}
.contactForm {
padding: 24px;
margin-top: 24px;
}
}
@media (max-width: 768px) {
.contactSection {
padding: 60px 0;
}
.sectionTitle {
font-size: 2rem !important;
}
.mapContainer {
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,494 @@
/* Footer Component Styles */
.footer {
position: relative;
background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
color: white;
overflow: hidden;
padding: 80px 0 40px;
}
.footerBackground {
position: absolute;
inset: 0;
opacity: 0.1;
}
.footerOrb1 {
position: absolute;
top: -100px;
left: -100px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 8s ease-in-out infinite;
}
.footerOrb2 {
position: absolute;
bottom: -150px;
right: -100px;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(35px);
animation: float 10s ease-in-out infinite reverse;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
.footerContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
position: relative;
z-index: 2;
}
.footerContent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 40px;
margin-bottom: 50px;
}
.footerColumn {
text-align: left;
}
.footerColumnTitle {
font-size: 1.1rem;
font-weight: 600;
color: white;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
transition: all 0.3s ease;
padding: 8px 0;
}
.footerColumnTitle:hover {
color: #a855f7;
}
.footerColumnIcon {
color: #a855f7;
font-size: 1.2rem;
transition: transform 0.3s ease;
}
.footerColumnTitle:hover .footerColumnIcon {
transform: scale(1.1);
}
.footerLinks {
list-style: none;
padding: 0;
margin: 0;
transition: all 0.3s ease;
}
.footerLink {
margin-bottom: 12px;
}
.footerLink a {
color: #cbd5e1;
text-decoration: none;
font-size: 0.9rem;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 0;
min-height: 44px; /* Better touch target */
border-radius: 6px;
padding-left: 8px;
padding-right: 8px;
}
.footerLink a:hover {
color: #a855f7;
transform: translateX(6px);
background: rgba(168, 85, 247, 0.1);
}
.footerLinkIcon {
font-size: 0.8rem;
transition: all 0.3s ease;
}
.footerBottom {
text-align: center;
padding-top: 40px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.footerBottomText {
color: #94a3b8;
font-size: 1rem;
margin-bottom: 30px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
line-height: 1.6;
}
.socialLinks {
display: flex;
justify-content: center;
gap: 20px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.socialLink {
width: 45px;
height: 45px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
color: white;
text-decoration: none;
transition: all 0.3s ease;
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.1);
min-width: 45px; /* Ensure minimum touch target */
min-height: 45px;
}
.socialLink:hover {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
transform: translateY(-3px);
color: white;
box-shadow: 0 8px 25px rgba(139, 92, 246, 0.3);
}
.socialLink:active {
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(139, 92, 246, 0.4);
}
.copyright {
color: #64748b;
font-size: 0.85rem;
line-height: 1.6;
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
}
.copyright a {
color: #94a3b8;
text-decoration: none;
transition: color 0.3s ease;
padding: 4px 8px;
border-radius: 4px;
min-height: 32px;
display: inline-flex;
align-items: center;
}
.copyright a:hover {
color: #a855f7;
background: rgba(168, 85, 247, 0.1);
}
/* Mobile-specific enhancements */
.mobileFooterColumn {
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 20px;
margin-bottom: 20px;
}
.mobileFooterColumn:last-child {
border-bottom: none;
margin-bottom: 0;
}
.mobileFooterTitle {
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
padding: 12px 0;
user-select: none;
}
.mobileFooterTitle::after {
content: '+';
font-size: 1.2rem;
color: #a855f7;
transition: transform 0.3s ease;
}
.mobileFooterTitle.expanded::after {
transform: rotate(45deg);
}
.mobileFooterLinks {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.mobileFooterLinks.expanded {
max-height: 300px;
}
/* Responsive Design */
@media (max-width: 1024px) {
.footerContent {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 30px;
}
}
@media (max-width: 768px) {
.footer {
padding: 60px 0 30px;
}
.footerContainer {
padding: 0 16px;
}
.footerContent {
grid-template-columns: 1fr;
gap: 0;
margin-bottom: 40px;
}
.footerColumn {
text-align: left;
margin-bottom: 0;
}
.footerColumnTitle {
justify-content: space-between;
font-size: 1.05rem;
padding: 16px 0;
margin-bottom: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.footerColumnTitle::after {
content: '+';
font-size: 1.3rem;
color: #a855f7;
transition: transform 0.3s ease;
}
.footerColumnTitle.expanded::after {
transform: rotate(45deg);
}
.footerLinks {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
padding-top: 0;
}
.footerLinks.expanded {
max-height: 300px;
padding-top: 16px;
}
.footerLink {
margin-bottom: 8px;
}
.footerLink a {
justify-content: flex-start;
font-size: 0.95rem;
padding: 12px 0;
min-height: 48px;
border-radius: 8px;
padding-left: 12px;
padding-right: 12px;
}
.footerLink a:hover {
transform: translateX(4px);
}
.socialLinks {
gap: 16px;
margin-bottom: 25px;
}
.socialLink {
width: 48px;
height: 48px;
min-width: 48px;
min-height: 48px;
}
.footerBottomText {
font-size: 0.95rem;
margin-bottom: 25px;
padding: 0 16px;
}
.copyright {
font-size: 0.8rem;
flex-direction: column;
gap: 12px;
padding: 0 16px;
}
.copyright a {
padding: 8px 12px;
min-height: 36px;
border-radius: 6px;
}
}
@media (max-width: 480px) {
.footer {
padding: 50px 0 25px;
}
.footerContainer {
padding: 0 12px;
}
.footerContent {
gap: 0;
margin-bottom: 30px;
}
.footerColumnTitle {
font-size: 1rem;
padding: 14px 0;
}
.footerColumnTitle::after {
font-size: 1.2rem;
}
.footerLinks.expanded {
padding-top: 12px;
}
.footerLink a {
font-size: 0.9rem;
padding: 10px 0;
min-height: 44px;
padding-left: 10px;
padding-right: 10px;
}
.socialLinks {
gap: 12px;
margin-bottom: 20px;
}
.socialLink {
width: 44px;
height: 44px;
min-width: 44px;
min-height: 44px;
}
.footerBottomText {
font-size: 0.9rem;
margin-bottom: 20px;
padding: 0 12px;
}
.copyright {
font-size: 0.75rem;
gap: 10px;
padding: 0 12px;
}
.copyright a {
padding: 6px 10px;
min-height: 32px;
font-size: 0.75rem;
}
}
@media (max-width: 360px) {
.footer {
padding: 40px 0 20px;
}
.footerContainer {
padding: 0 8px;
}
.footerColumnTitle {
font-size: 0.95rem;
padding: 12px 0;
}
.footerLink a {
font-size: 0.85rem;
padding: 8px 0;
min-height: 40px;
padding-left: 8px;
padding-right: 8px;
}
.socialLinks {
gap: 10px;
}
.socialLink {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
}
.footerBottomText {
font-size: 0.85rem;
padding: 0 8px;
}
.copyright {
font-size: 0.7rem;
padding: 0 8px;
}
}
/* Touch device optimizations */
@media (hover: none) and (pointer: coarse) {
.footerLink a:hover {
transform: none;
background: rgba(168, 85, 247, 0.1);
}
.socialLink:hover {
transform: none;
}
.socialLink:active {
transform: scale(0.95);
}
.footerColumnTitle:hover {
color: white;
}
.footerColumnTitle:hover .footerColumnIcon {
transform: none;
}
}

View File

@@ -0,0 +1,240 @@
"use client";
import {
ArrowRightOutlined,
BulbOutlined,
EnvironmentOutlined,
FacebookOutlined,
InstagramOutlined,
LinkedinOutlined,
MailOutlined,
PhoneOutlined,
TeamOutlined,
TrophyOutlined,
TwitterOutlined
} from '@ant-design/icons';
import { Typography } from 'antd';
import { motion } from 'framer-motion';
import React, { useEffect, useState } from 'react';
import styles from './Footer.module.css';
const { Paragraph } = Typography;
const Footer: React.FC = () => {
const [expandedSections, setExpandedSections] = useState<{ [key: string]: boolean }>({});
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth <= 768);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 }
}
};
const toggleSection = (sectionKey: string) => {
if (isMobile) {
setExpandedSections(prev => ({
...prev,
[sectionKey]: !prev[sectionKey]
}));
}
};
const footerSections = [
{
key: 'company',
title: 'Company',
icon: <TeamOutlined className={styles.footerColumnIcon} />,
links: [
{ href: '/about', text: 'About Us' },
{ href: '/services', text: 'Our Services' },
{ href: '/projects', text: 'Portfolio' },
{ href: '/contact', text: 'Contact Us' }
]
},
{
key: 'services',
title: 'Services',
icon: <BulbOutlined className={styles.footerColumnIcon} />,
links: [
{ href: '/services#webdev', text: 'Web Development' },
{ href: '/services#mobile', text: 'Mobile Apps' },
{ href: '/services#ai', text: 'AI Solutions' },
{ href: '/services#cloud', text: 'Cloud Services' }
]
},
{
key: 'resources',
title: 'Resources',
icon: <TrophyOutlined className={styles.footerColumnIcon} />,
links: [
{ href: '/blog', text: 'Blog & Insights' },
{ href: '/case-studies', text: 'Case Studies' },
{ href: '/whitepapers', text: 'Whitepapers' },
{ href: '/webinars', text: 'Webinars' }
]
},
{
key: 'contact',
title: 'Contact Info',
icon: <MailOutlined className={styles.footerColumnIcon} />,
links: [
{ href: 'mailto:info@techmaster.com', text: 'info@techmaster.com' },
{ href: 'tel:+15551234567', text: '+1 (555) 123-4567' },
{ href: '#', text: 'San Francisco, CA' },
{ href: '/support', text: '24/7 Support' }
]
}
];
const getLinkIcon = (href: string) => {
if (href.startsWith('mailto:')) return <MailOutlined className={styles.footerLinkIcon} />;
if (href.startsWith('tel:')) return <PhoneOutlined className={styles.footerLinkIcon} />;
if (href.includes('support')) return <ArrowRightOutlined className={styles.footerLinkIcon} />;
if (href.includes('San Francisco')) return <EnvironmentOutlined className={styles.footerLinkIcon} />;
return <ArrowRightOutlined className={styles.footerLinkIcon} />;
};
return (
<footer className={styles.footer}>
<div className={styles.footerBackground}>
<div className={styles.footerOrb1}></div>
<div className={styles.footerOrb2}></div>
</div>
<div className={styles.footerContainer}>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.footerContent}
>
{footerSections.map((section) => (
<motion.div
key={section.key}
variants={itemVariants}
className={`${styles.footerColumn} ${isMobile ? styles.mobileFooterColumn : ''}`}
>
<div
className={`${styles.footerColumnTitle} ${isMobile && expandedSections[section.key] ? styles.expanded : ''}`}
onClick={() => toggleSection(section.key)}
role={isMobile ? 'button' : undefined}
tabIndex={isMobile ? 0 : undefined}
onKeyDown={(e) => {
if (isMobile && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault();
toggleSection(section.key);
}
}}
>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
{section.icon}
{section.title}
</div>
</div>
<ul className={`${styles.footerLinks} ${isMobile && expandedSections[section.key] ? styles.expanded : ''}`}>
{section.links.map((link, index) => (
<li key={index} className={styles.footerLink}>
<a
href={link.href}
onClick={(e) => {
// Prevent navigation if it's a placeholder link
if (link.href === '#') {
e.preventDefault();
}
}}
>
{getLinkIcon(link.href)}
{link.text}
</a>
</li>
))}
</ul>
</motion.div>
))}
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.3 }}
viewport={{ once: true }}
className={styles.footerBottom}
>
<Paragraph className={styles.footerBottomText}>
Ready to transform your business? Let&apos;s discuss your next project.
</Paragraph>
<div className={styles.socialLinks}>
<a
href="#"
className={styles.socialLink}
onClick={(e) => e.preventDefault()}
aria-label="Facebook"
>
<FacebookOutlined />
</a>
<a
href="#"
className={styles.socialLink}
onClick={(e) => e.preventDefault()}
aria-label="Twitter"
>
<TwitterOutlined />
</a>
<a
href="#"
className={styles.socialLink}
onClick={(e) => e.preventDefault()}
aria-label="LinkedIn"
>
<LinkedinOutlined />
</a>
<a
href="#"
className={styles.socialLink}
onClick={(e) => e.preventDefault()}
aria-label="Instagram"
>
<InstagramOutlined />
</a>
</div>
<div className={styles.copyright}>
<span>© 2024 Tech Master. All rights reserved.</span>
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', justifyContent: 'center' }}>
<a href="/privacy" onClick={(e) => e.preventDefault()}>Privacy Policy</a>
<a href="/terms" onClick={(e) => e.preventDefault()}>Terms of Service</a>
</div>
</div>
</motion.div>
</div>
</footer>
);
};
export default Footer;

View File

@@ -5,37 +5,97 @@
right: 0; right: 0;
z-index: 1000; z-index: 1000;
background: rgba(255, 255, 255, 0.95); background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px); backdrop-filter: blur(20px);
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(116, 0, 184, 0.1);
padding: 15px 0; padding: 0;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.headerContainer { .headerContainer {
max-width: 1200px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
padding: 0 20px; padding: 0 32px;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 40px;
height: 80px;
}
/* Logo Section */
.logoSection {
display: flex;
align-items: center;
}
.logoLink {
text-decoration: none;
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
} }
.logoContainer { .logoContainer {
/* background: var(--primary) !important; */
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px;
}
.logoIcon {
display: flex;
gap: 4px;
padding: 8px;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
border-radius: 12px;
box-shadow: 0 4px 12px rgba(116, 0, 184, 0.3);
}
.logoDot {
width: 6px;
height: 6px;
background: white;
border-radius: 50%;
animation: pulse 2s infinite;
}
.logoDot:nth-child(2) {
animation-delay: 0.3s;
}
.logoDot:nth-child(3) {
animation-delay: 0.6s;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
} }
.logoText { .logoText {
color: #6e48aa !important; background: linear-gradient(135deg, #7400b8 0%, #5e60ce 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin: 0 !important; margin: 0 !important;
font-weight: 700 !important; font-weight: 800 !important;
font-size: 1.5rem !important; font-size: 1.6rem !important;
letter-spacing: -0.5px;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.logoHighlight { .logoText:hover {
margin-left: 8px; transform: scale(1.02);
}
/* Navigation Section */
.navSection {
display: flex;
justify-content: center;
align-items: center;
} }
.navContainer { .navContainer {
@@ -46,31 +106,229 @@
.menu { .menu {
border-bottom: none !important; border-bottom: none !important;
background: transparent !important; background: transparent !important;
font-weight: 500; font-weight: 500 !important;
font-size: 0.95rem !important;
} }
.menu li { .menu :global(.ant-menu-item) {
padding: 0 15px !important; padding: 12px 20px !important;
margin: 0 4px !important;
border-radius: 12px !important;
transition: all 0.3s ease !important;
color: #666 !important;
font-weight: 500 !important;
position: relative;
overflow: hidden;
} }
.ctaContainer { .menu :global(.ant-menu-item::before) {
margin-left: 30px; content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
opacity: 0;
transition: opacity 0.3s ease;
z-index: -1;
}
/* .menu :global(.ant-menu-item:hover) {
color: #7400b8 !important;
transform: translateY(-2px) !important;
box-shadow: 0 8px 25px rgba(116, 0, 184, 0.15) !important;
} */
.menu :global(.ant-menu-item:hover::before) {
/* opacity: 0.1; */
}
.menu :global(.ant-menu-item-selected) {
color: #7400b8 !important;
/* background: rgba(116, 0, 184, 0.1) !important; */
font-weight: 600 !important;
/* box-shadow: 0 4px 15px rgba(116, 0, 184, 0.2) !important; */
}
.menu :global(.ant-menu-item::after) {
display: none !important;
}
/* Actions Section */
.actionsSection {
display: flex;
align-items: center;
}
.actionButtons {
display: flex;
align-items: center;
gap: 12px;
}
.actionButton {
width: 40px;
height: 40px;
border-radius: 12px !important;
border: 1px solid rgba(116, 0, 184, 0.1) !important;
background: rgba(255, 255, 255, 0.8) !important;
color: #666 !important;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05) !important;
}
.actionButton:hover {
background: rgba(116, 0, 184, 0.1) !important;
color: #7400b8 !important;
transform: translateY(-2px) !important;
box-shadow: 0 8px 20px rgba(116, 0, 184, 0.2) !important;
border-color: rgba(116, 0, 184, 0.2) !important;
} }
.ctaButton { .ctaButton {
/* background: var(--primary) !important; */ background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%) !important;
border: none !important; border: none !important;
font-weight: 500 !important; font-weight: 600 !important;
padding: 0 25px !important; padding: 0 24px !important;
height: 40px !important; height: 40px !important;
border-radius: 12px !important;
box-shadow: 0 4px 15px rgba(116, 0, 184, 0.3) !important;
transition: all 0.3s ease !important;
font-size: 0.9rem !important;
color: white !important;
}
.ctaButton:hover {
transform: translateY(-2px) !important;
box-shadow: 0 8px 25px rgba(116, 0, 184, 0.4) !important;
/* background: linear-gradient(135deg, #6930c3 0%, #5e60ce 100%) !important; */
}
.ctaButton:active {
transform: translateY(0) !important;
}
.userAvatar {
width: 40px !important;
height: 40px !important;
border-radius: 12px !important;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%) !important;
border: 2px solid rgba(255, 255, 255, 0.8) !important;
box-shadow: 0 4px 12px rgba(116, 0, 184, 0.3) !important;
transition: all 0.3s ease !important;
cursor: pointer;
}
.userAvatar:hover {
transform: scale(1.05) !important;
box-shadow: 0 8px 20px rgba(116, 0, 184, 0.4) !important;
}
/* Responsive Design */
@media (max-width: 1200px) {
.headerContainer {
padding: 0 24px;
gap: 30px;
}
.menu :global(.ant-menu-item) {
padding: 10px 16px !important;
}
.actionButtons {
gap: 8px;
}
} }
@media (max-width: 992px) { @media (max-width: 992px) {
.navContainer { .headerContainer {
grid-template-columns: auto auto;
gap: 20px;
}
.navSection {
display: none; display: none;
} }
.headerContainer { .actionsSection {
justify-content: center; justify-self: end;
}
.logoText {
font-size: 1.4rem !important;
}
}
@media (max-width: 768px) {
.header {
padding: 0;
}
.headerContainer {
padding: 0 16px;
height: 70px;
}
.logoText {
font-size: 1.3rem !important;
}
.actionButtons {
gap: 6px;
}
.actionButton {
width: 36px;
height: 36px;
}
.ctaButton {
padding: 0 20px !important;
height: 36px !important;
font-size: 0.85rem !important;
}
.userAvatar {
width: 36px !important;
height: 36px !important;
}
}
@media (max-width: 480px) {
.headerContainer {
padding: 0 12px;
}
.logoText {
font-size: 1.2rem !important;
}
.logoIcon {
padding: 6px;
}
.logoDot {
width: 5px;
height: 5px;
}
.actionButton {
width: 32px;
height: 32px;
}
.ctaButton {
padding: 0 16px !important;
height: 32px !important;
font-size: 0.8rem !important;
}
.userAvatar {
width: 32px !important;
height: 32px !important;
} }
} }

View File

@@ -1,6 +1,7 @@
"use client"; "use client";
import { Menu, MenuProps, Typography } from "antd"; import { BellOutlined, UserOutlined } from "@ant-design/icons";
import { Avatar, Button, Menu, MenuProps, Typography } from "antd";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Link from "next/link"; import Link from "next/link";
import styles from "./Header.module.css"; import styles from "./Header.module.css";
@@ -34,37 +35,74 @@ const Header = () => {
return ( return (
<header className={styles.header}> <header className={styles.header}>
<div className={styles.headerContainer}> <div className={styles.headerContainer}>
{/* Logo Section */}
<motion.div <motion.div
initial={{ opacity: 0, y: -20 }} initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5 }} transition={{ duration: 0.6 }}
className={styles.logoContainer} className={styles.logoSection}
> >
<Link href="/"> <Link href="/" className={styles.logoLink}>
<Title level={3} className={styles.logoText}> <div className={styles.logoContainer}>
Tech Master <div className={styles.logoIcon}>
</Title> <div className={styles.logoDot}></div>
<div className={styles.logoDot}></div>
<div className={styles.logoDot}></div>
</div>
<Title level={3} className={styles.logoText}>
Tech Masters
</Title>
</div>
</Link> </Link>
</motion.div> </motion.div>
<nav className={styles.navContainer}> {/* Navigation Section */}
<Menu <nav className={styles.navSection}>
mode="horizontal" <motion.div
items={items} initial={{ opacity: 0, y: -10 }}
className={styles.menu} animate={{ opacity: 1, y: 0 }}
/> transition={{ duration: 0.6, delay: 0.2 }}
className={styles.navContainer}
>
<Menu
mode="horizontal"
items={items}
className={styles.menu}
selectedKeys={['home']}
/>
</motion.div>
</nav>
{/* <Space className={styles.ctaContainer}> {/* Actions Section */}
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: 0.4 }}
className={styles.actionsSection}
>
<div className={styles.actionButtons}>
{/* <Button
type="text"
icon={<SearchOutlined />}
className={styles.actionButton}
/> */}
<Button <Button
type="text"
icon={<BellOutlined />}
className={styles.actionButton}
/>
{/* <Button
type="primary" type="primary"
shape="round"
size="large"
className={styles.ctaButton} className={styles.ctaButton}
> >
Get Started Get Started
</Button> </Button> */}
</Space> */} <Avatar
</nav> icon={<UserOutlined />}
className={styles.userAvatar}
/>
</div>
</motion.div>
</div> </div>
</header> </header>
); );

View File

@@ -4,6 +4,7 @@ import { useEffect } from "react";
declare global { declare global {
interface Window { interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
particlesJS: any; particlesJS: any;
} }
} }

View File

@@ -25,11 +25,6 @@ const preferenceOptions: PreferenceOption[] = [
label: "E-commerce Solutions", label: "E-commerce Solutions",
description: "Online stores, payment gateways, inventory management", description: "Online stores, payment gateways, inventory management",
}, },
{
id: "seo",
label: "SEO & Digital Marketing",
description: "Search optimization, content strategy, analytics",
},
// { // {
// id: "mobile", // id: "mobile",
// label: "Mobile Development", // label: "Mobile Development",

View File

@@ -1,14 +1,8 @@
// File: src/components/home/ProjectsShowcase.tsx import Paragraph from "antd/es/typography/Paragraph";
import Title from "antd/es/typography/Title";
import { EyeOutlined, LeftOutlined, RightOutlined } from "@ant-design/icons"; import ProjectsShowcaseClient from "./ProjectsShowcaseClient";
import { Badge, Button, Card, Col, Row, Tag, Typography } from "antd";
import { motion, useAnimation } from "framer-motion";
import Image from "next/image";
import React, { useEffect, useState } from "react";
import styles from "./ProjectsShowcaseSelector.module.css"; import styles from "./ProjectsShowcaseSelector.module.css";
const { Title, Paragraph, Text } = Typography;
interface Project { interface Project {
id: string; id: string;
title: string; title: string;
@@ -17,246 +11,258 @@ interface Project {
category: string; category: string;
technologies: string[]; technologies: string[];
featured: boolean; featured: boolean;
detailedDescription: string;
images: string[];
liveUrl?: string;
githubUrl?: string;
features: string[];
duration: string;
teamSize: string;
} }
// Sample project data // Sample project data
const projectsData: Project[] = [ const projectsData: Project[] = [
{ {
id: "p1", id: "p1",
title: "FinTech Dashboard", title: "BPro ERP System",
description: description:
"An AI-powered financial analytics platform with real-time data visualization and predictive insights.", "Comprehensive enterprise resource planning system with advanced business process management and real-time analytics.",
imageUrl: "/api/placeholder/600/400", imageUrl: "https://tech-masters.guru/photos/projects/bpro-erp.jpg",
category: "Web Application", category: "Enterprise Software",
technologies: ["React", "Node.js", "TensorFlow", "AWS"], technologies: ["React", "Node.js", "PostgreSQL", "Redis"],
featured: true, featured: true,
detailedDescription:
"A comprehensive ERP system designed for modern businesses, featuring advanced business process management, real-time analytics, and seamless integration with existing enterprise systems. The platform streamlines operations across all departments.",
images: [
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
],
liveUrl: "https://bpro-erp.com",
githubUrl: "https://github.com/company/bpro-erp",
features: [
"Advanced business process management",
"Real-time analytics and reporting",
"Multi-department integration",
"Custom workflow automation",
"Comprehensive audit trails",
],
duration: "8 months",
teamSize: "12 developers",
}, },
{ {
id: "p2", id: "p2",
title: "Healthcare Management System", title: "Law Office Management",
description: description:
"Comprehensive solution for managing patient records, appointments, and medical data with advanced security features.", "Complete legal practice management solution with case tracking, document management, and client portal.",
imageUrl: "/api/placeholder/600/400", imageUrl: "https://tech-masters.guru/photos/projects/law-office-home.png",
category: "Enterprise Software", category: "Legal Software",
technologies: ["Angular", ".NET Core", "SQL Server", "Azure"], technologies: ["Angular", ".NET Core", "SQL Server", "Azure"],
featured: true, featured: true,
detailedDescription:
"A comprehensive legal practice management system designed to streamline law office operations, manage cases, track billable hours, and provide secure client communication portals.",
images: [
"https://tech-masters.guru/photos/projects/law-office-home.png",
"https://tech-masters.guru/photos/projects/law-office-login.png",
"https://tech-masters.guru/photos/projects/law-office-home.png",
],
liveUrl: "https://law-office-demo.com",
githubUrl: "https://github.com/company/law-office-system",
features: [
"Case management and tracking",
"Document management system",
"Client portal and communication",
"Time tracking and billing",
"Calendar and appointment management",
],
duration: "6 months",
teamSize: "8 developers",
}, },
{ {
id: "p3", id: "p3",
title: "E-commerce Marketplace", title: "MoneyOut Payment Platform",
description: description:
"Feature-rich online marketplace connecting vendors and customers with integrated payment processing and inventory management.", "Secure digital payment processing platform with multi-currency support and advanced fraud detection.",
imageUrl: "/api/placeholder/600/400", imageUrl: "https://tech-masters.guru/photos/projects/moneyout.png",
category: "E-commerce", category: "FinTech",
technologies: ["Next.js", "Stripe", "MongoDB", "GraphQL"], technologies: ["Next.js", "Stripe", "MongoDB", "GraphQL"],
featured: true, featured: true,
detailedDescription:
"A modern payment processing platform that enables secure digital transactions with multi-currency support, advanced fraud detection, and comprehensive merchant tools.",
images: [
"https://tech-masters.guru/photos/projects/moneyout.png",
"https://tech-masters.guru/photos/projects/moneyout.png",
"https://tech-masters.guru/photos/projects/moneyout.png",
],
liveUrl: "https://moneyout-demo.com",
githubUrl: "https://github.com/company/moneyout-platform",
features: [
"Multi-currency payment processing",
"Advanced fraud detection",
"Merchant dashboard and analytics",
"Secure API integration",
"Real-time transaction monitoring",
],
duration: "7 months",
teamSize: "10 developers",
}, },
{ {
id: "p4", id: "p4",
title: "Smart City IoT Platform", title: "Cloths E-commerce Platform",
description: description:
"IoT ecosystem for urban monitoring and management, featuring real-time data collection and analytics.", "Modern fashion e-commerce platform with advanced product catalog, virtual try-on, and personalized recommendations.",
imageUrl: "/api/placeholder/600/400", imageUrl: "https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
category: "IoT", category: "E-commerce",
technologies: ["Python", "MQTT", "Kubernetes", "TensorFlow"], technologies: ["React", "Node.js", "MongoDB", "AWS"],
featured: false, featured: false,
detailedDescription:
"A cutting-edge fashion e-commerce platform featuring virtual try-on technology, personalized recommendations, and seamless mobile shopping experience.",
images: [
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
],
liveUrl: "https://cloths-ecommerce.com",
githubUrl: "https://github.com/company/cloths-ecommerce",
features: [
"Virtual try-on technology",
"Personalized recommendations",
"Advanced product catalog",
"Mobile-first design",
"Social commerce integration",
],
duration: "5 months",
teamSize: "6 developers",
}, },
{ {
id: "p5", id: "p5",
title: "Logistics Tracking System", title: "Nanas Dashboard",
description: description:
"Real-time fleet management and package tracking solution with route optimization algorithms.", "Comprehensive business intelligence dashboard with real-time data visualization and predictive analytics.",
imageUrl: "/api/placeholder/600/400", imageUrl:
category: "Mobile & Web", "https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
technologies: ["React Native", "Node.js", "PostgreSQL", "Google Maps API"], category: "Business Intelligence",
technologies: ["Vue.js", "Python", "PostgreSQL", "Docker"],
featured: false, featured: false,
detailedDescription:
"A powerful business intelligence dashboard that provides real-time data visualization, predictive analytics, and comprehensive reporting for data-driven decision making.",
images: [
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
],
liveUrl: "https://nanas-dashboard.com",
githubUrl: "https://github.com/company/nanas-dashboard",
features: [
"Real-time data visualization",
"Predictive analytics",
"Custom reporting tools",
"Interactive dashboards",
"Data export capabilities",
],
duration: "4 months",
teamSize: "5 developers",
}, },
{ {
id: "p6", id: "p6",
title: "Virtual Learning Environment", title: "Easy Pay Login System",
description: description:
"Interactive educational platform with personalized learning paths, video conferencing, and progress tracking.", "Secure authentication system with multi-factor authentication and advanced security features for financial applications.",
imageUrl: "/api/placeholder/600/400", imageUrl: "https://tech-masters.guru/photos/projects/easy-pay-login.png",
category: "Education", category: "Security",
technologies: ["Vue.js", "Django", "WebRTC", "Docker"], technologies: ["React", "Node.js", "JWT", "Redis"],
featured: false, featured: false,
detailedDescription:
"A robust authentication system designed for financial applications, featuring multi-factor authentication, advanced security protocols, and seamless user experience.",
images: [
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
],
liveUrl: "https://easy-pay-login.com",
githubUrl: "https://github.com/company/easy-pay-login",
features: [
"Multi-factor authentication",
"Advanced security protocols",
"Session management",
"Audit logging",
"Password recovery system",
],
duration: "3 months",
teamSize: "4 developers",
},
{
id: "p7",
title: "Majsin Dashboard",
description:
"Advanced analytics dashboard with machine learning insights and customizable reporting for enterprise clients.",
imageUrl: "https://tech-masters.guru/photos/projects/majsin-dashborad.png",
category: "Analytics",
technologies: ["Angular", "Python", "TensorFlow", "AWS"],
featured: false,
detailedDescription:
"An advanced analytics dashboard powered by machine learning, providing deep insights and customizable reporting for enterprise-level decision making.",
images: [
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
],
liveUrl: "https://majsin-dashboard.com",
githubUrl: "https://github.com/company/majsin-dashboard",
features: [
"Machine learning insights",
"Customizable reporting",
"Real-time data processing",
"Advanced visualizations",
"API integration capabilities",
],
duration: "6 months",
teamSize: "7 developers",
},
{
id: "p8",
title: "SVU Hardware Management",
description:
"Comprehensive hardware inventory and management system for educational institutions with asset tracking.",
imageUrl: "https://tech-masters.guru/photos/projects/svu-hw.png",
category: "Education",
technologies: ["React", "Node.js", "MySQL", "Docker"],
featured: false,
detailedDescription:
"A comprehensive hardware management system designed for educational institutions, featuring asset tracking, maintenance scheduling, and detailed reporting capabilities.",
images: [
"https://tech-masters.guru/photos/projects/svu-hw.png",
"https://tech-masters.guru/photos/projects/svu-hw.png",
"https://tech-masters.guru/photos/projects/svu-hw.png",
],
liveUrl: "https://svu-hardware.com",
githubUrl: "https://github.com/company/svu-hardware",
features: [
"Asset tracking and management",
"Maintenance scheduling",
"Inventory control",
"Detailed reporting",
"User access management",
],
duration: "5 months",
teamSize: "6 developers",
}, },
]; ];
const ProjectsShowcase: React.FC = () => { const ProjectsShowcase: React.FC = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [visibleProjects, setVisibleProjects] = useState<Project[]>([]);
const controls = useAnimation();
// Determine number of projects to show based on screen width
const [projectsPerView, setProjectsPerView] = useState(3);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 768) {
setProjectsPerView(1);
} else if (window.innerWidth < 992) {
setProjectsPerView(2);
} else {
setProjectsPerView(3);
}
};
// Set initial state
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
// Update visible projects whenever currentIndex or projectsPerView changes
setVisibleProjects(
projectsData.slice(currentIndex, currentIndex + projectsPerView)
);
}, [currentIndex, projectsPerView]);
const handleNext = async () => {
if (currentIndex + projectsPerView < projectsData.length) {
await controls.start({
x: "-100%",
opacity: 0,
transition: { duration: 0.3 },
});
setCurrentIndex((prev) => prev + 1);
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.3 },
});
}
};
const handlePrev = async () => {
if (currentIndex > 0) {
await controls.start({
x: "100%",
opacity: 0,
transition: { duration: 0.3 },
});
setCurrentIndex((prev) => prev - 1);
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.3 },
});
}
};
return ( return (
<section className={styles.projectsSection}> <section className={styles.projectsSection}>
<div className={styles.container}> <div className={styles.container}>
<motion.div <div className={styles.sectionHeader}>
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className={styles.sectionHeader}
>
<Title level={2} className={styles.sectionTitle}> <Title level={2} className={styles.sectionTitle}>
Our Work Our Work
</Title> </Title>
<Paragraph className={styles.sectionSubtitle}> <Paragraph className={styles.sectionSubtitle}>
Transforming ideas into powerful digital solutions Transforming ideas into powerful digital solutions
</Paragraph> </Paragraph>
</motion.div>
<div className={styles.showcaseContainer}>
<motion.div
className={styles.projectsGrid}
animate={controls}
initial={{ opacity: 1, x: 0 }}
>
<Row gutter={[24, 24]}>
{visibleProjects.map((project) => (
<Col xs={24} md={24 / projectsPerView} key={project.id}>
<motion.div
whileHover={{ y: -10 }}
transition={{ type: "spring", stiffness: 300 }}
>
<Card
hoverable
cover={
<div className={styles.projectImageContainer}>
<Image
alt={project.title}
src={project.imageUrl}
className={styles.projectImage}
width={400}
height={400}
/>
<div className={styles.projectOverlay}>
<Button
type="primary"
shape="circle"
icon={<EyeOutlined />}
className={styles.viewButton}
/>
</div>
{project.featured && (
<Badge.Ribbon
text="Featured"
className={styles.featuredBadge}
/>
)}
</div>
}
className={styles.projectCard}
>
<div className={styles.categoryTag}>
<Tag color="blue">{project.category}</Tag>
</div>
<Card.Meta
title={project.title}
description={project.description}
/>
<div className={styles.technologiesList}>
{project.technologies.map((tech) => (
<Tag key={tech} className={styles.techTag}>
{tech}
</Tag>
))}
</div>
</Card>
</motion.div>
</Col>
))}
</Row>
</motion.div>
<div className={styles.navigationControls}>
<Button
shape="circle"
icon={<LeftOutlined />}
onClick={handlePrev}
disabled={currentIndex === 0}
className={styles.navButton}
/>
<Text className={styles.pageIndicator}>
{currentIndex + 1}-
{Math.min(currentIndex + projectsPerView, projectsData.length)} of{" "}
{projectsData.length}
</Text>
<Button
shape="circle"
icon={<RightOutlined />}
onClick={handleNext}
disabled={currentIndex + projectsPerView >= projectsData.length}
className={styles.navButton}
/>
</div>
</div> </div>
<div className={styles.viewAllContainer}> <ProjectsShowcaseClient projects={projectsData} />
<Button type="primary" size="large" className={styles.viewAllButton}>
View All Projects
</Button>
</div>
</div> </div>
</section> </section>
); );

View File

@@ -0,0 +1,364 @@
"use client";
import {
CloseOutlined,
EyeOutlined,
LeftOutlined,
LinkOutlined,
RightOutlined
} from "@ant-design/icons";
import {
Badge,
Button,
Card,
Carousel,
Col,
Modal,
Row,
Tag,
Typography,
} from "antd";
import { AnimatePresence, motion, useAnimation } from "framer-motion";
import Image from "next/image";
import React, { useEffect, useState } from "react";
import styles from "./ProjectsShowcaseSelector.module.css";
const { Title, Paragraph, Text } = Typography;
interface Project {
id: string;
title: string;
description: string;
imageUrl: string;
category: string;
technologies: string[];
featured: boolean;
detailedDescription: string;
images: string[];
liveUrl?: string;
githubUrl?: string;
features: string[];
duration: string;
teamSize: string;
}
interface ProjectsShowcaseClientProps {
projects: Project[];
}
const ProjectsShowcaseClient: React.FC<ProjectsShowcaseClientProps> = ({
projects,
}) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [visibleProjects, setVisibleProjects] = useState<Project[]>([]);
const [selectedProject, setSelectedProject] = useState<Project | null>(null);
const [isModalVisible, setIsModalVisible] = useState(false);
const controls = useAnimation();
// Determine number of projects to show based on screen width
const [projectsPerView, setProjectsPerView] = useState(3);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 768) {
setProjectsPerView(1);
} else if (window.innerWidth < 992) {
setProjectsPerView(2);
} else {
setProjectsPerView(3);
}
};
// Set initial state
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
// Update visible projects whenever currentIndex or projectsPerView changes
setVisibleProjects(
projects.slice(currentIndex, currentIndex + projectsPerView)
);
}, [currentIndex, projectsPerView, projects]);
const handleNext = async () => {
if (currentIndex + projectsPerView < projects.length) {
await controls.start({
x: "-100%",
opacity: 0,
transition: { duration: 0.3 },
});
setCurrentIndex((prev) => prev + 1);
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.3 },
});
}
};
const handlePrev = async () => {
if (currentIndex > 0) {
await controls.start({
x: "100%",
opacity: 0,
transition: { duration: 0.3 },
});
setCurrentIndex((prev) => prev - 1);
controls.start({
x: 0,
opacity: 1,
transition: { duration: 0.3 },
});
}
};
const handleProjectClick = (project: Project) => {
setSelectedProject(project);
setIsModalVisible(true);
};
const handleModalClose = () => {
setIsModalVisible(false);
setTimeout(() => {
setSelectedProject(null);
}, 300);
};
return (
<>
<div className={styles.showcaseContainer}>
<motion.div
className={styles.projectsGrid}
animate={controls}
initial={{ opacity: 1, x: 0 }}
>
<Row gutter={[24, 24]}>
{visibleProjects.map((project) => (
<Col xs={24} md={24 / projectsPerView} key={project.id}>
<motion.div
whileHover={{ y: -10 }}
transition={{ type: "spring", stiffness: 300 }}
>
<Card
hoverable
onClick={() => handleProjectClick(project)}
cover={
<div className={styles.projectImageContainer}>
<Image
alt={project.title}
src={project.imageUrl}
className={styles.projectImage}
width={400}
height={400}
/>
<div className={styles.projectOverlay}>
<Button
type="primary"
shape="circle"
icon={<EyeOutlined />}
className={styles.viewButton}
/>
</div>
{project.featured && (
<Badge.Ribbon
text="Featured"
className={styles.featuredBadge}
/>
)}
</div>
}
className={styles.projectCard}
>
<div className={styles.categoryTag}>
<Tag color="blue">{project.category}</Tag>
</div>
<Card.Meta
title={project.title}
description={project.description}
/>
<div className={styles.technologiesList}>
{project.technologies.map((tech) => (
<Tag key={tech} className={styles.techTag}>
{tech}
</Tag>
))}
</div>
</Card>
</motion.div>
</Col>
))}
</Row>
</motion.div>
<div className={styles.navigationControls}>
<Button
shape="circle"
icon={<LeftOutlined />}
onClick={handlePrev}
disabled={currentIndex === 0}
className={styles.navButton}
/>
<Text className={styles.pageIndicator}>
{currentIndex + 1}-
{Math.min(currentIndex + projectsPerView, projects.length)} of{" "}
{projects.length}
</Text>
<Button
shape="circle"
icon={<RightOutlined />}
onClick={handleNext}
disabled={currentIndex + projectsPerView >= projects.length}
className={styles.navButton}
/>
</div>
</div>
<div className={styles.viewAllContainer}>
<Button type="primary" size="large" className={styles.viewAllButton}>
View All Projects
</Button>
</div>
{/* Project Details Modal */}
<AnimatePresence>
{isModalVisible && selectedProject && (
<Modal
open={isModalVisible}
onCancel={handleModalClose}
footer={null}
width={1000}
className={styles.projectModal}
closeIcon={<CloseOutlined className={styles.closeIcon} />}
>
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.3 }}
className={styles.modalContent}
>
<div className={styles.modalHeader}>
<div className={styles.modalTitleSection}>
<Title level={2} className={styles.modalTitle}>
{selectedProject.title}
</Title>
<Tag color="blue" className={styles.modalCategory}>
{selectedProject.category}
</Tag>
</div>
<div className={styles.modalActions}>
{selectedProject.liveUrl && (
<Button
type="primary"
icon={<LinkOutlined />}
href={selectedProject.liveUrl}
target="_blank"
className={styles.actionButton}
>
Live Demo
</Button>
)}
{/* {selectedProject.githubUrl && (
<Button
icon={<GithubOutlined />}
href={selectedProject.githubUrl}
target="_blank"
className={styles.actionButton}
>
View Code
</Button>
)} */}
</div>
</div>
<div className={styles.modalBody}>
<div className={styles.projectImages}>
<Carousel
autoplay
dots={{ className: styles.carouselDots }}
className={styles.imageCarousel}
>
{selectedProject.images.map((image, index) => (
<div key={index} className={styles.carouselItem}>
<Image
src={image}
alt={`${selectedProject.title} - Image ${index + 1}`}
width={800}
height={500}
className={styles.modalImage}
/>
</div>
))}
</Carousel>
</div>
<div className={styles.projectDetails}>
<div className={styles.detailSection}>
<Title level={4} className={styles.sectionTitle}>
Project Overview
</Title>
<Paragraph className={styles.projectDescription}>
{selectedProject.detailedDescription}
</Paragraph>
</div>
<div className={styles.detailGrid}>
<div className={styles.detailSection}>
<Title level={4} className={styles.sectionTitle}>
Key Features
</Title>
<ul className={styles.featuresList}>
{selectedProject.features.map((feature, index) => (
<motion.li
key={index}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
className={styles.featureItem}
>
{feature}
</motion.li>
))}
</ul>
</div>
<div className={styles.detailSection}>
<Title level={4} className={styles.sectionTitle}>
Project Details
</Title>
<div className={styles.projectInfo}>
<div className={styles.infoItem}>
<Text strong>Duration:</Text>
<Text>{selectedProject.duration}</Text>
</div>
<div className={styles.infoItem}>
<Text strong>Team Size:</Text>
<Text>{selectedProject.teamSize}</Text>
</div>
<div className={styles.infoItem}>
<Text strong>Technologies:</Text>
<div className={styles.modalTechnologies}>
{selectedProject.technologies.map((tech) => (
<Tag key={tech} className={styles.modalTechTag}>
{tech}
</Tag>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</motion.div>
</Modal>
)}
</AnimatePresence>
</>
);
};
export default ProjectsShowcaseClient;

View File

@@ -1,43 +1,73 @@
/* File: src/components/home/ProjectsShowcase.module.css */ /* File: src/components/home/ProjectsShowcase.module.css */
.projectsSection { .projectsSection {
padding: 100px 0; padding: 120px 0;
background-color: #fff; background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.projectsSection::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="hexagons" width="50" height="43.4" patternUnits="userSpaceOnUse"><polygon points="25,2 47,13.4 47,36.6 25,48 3,36.6 3,13.4" fill="none" stroke="%23f1f5f9" stroke-width="1"/></pattern></defs><rect width="100" height="100" fill="url(%23hexagons)"/></svg>');
opacity: 0.4;
}
.container { .container {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
padding: 0 16px; padding: 0 16px;
position: relative; position: relative;
z-index: 1;
} }
.sectionHeader { .sectionHeader {
text-align: center; text-align: center;
margin-bottom: 60px; margin-bottom: 80px;
} }
.sectionTitle { .sectionTitle {
font-size: 2.5rem !important; font-size: 3rem !important;
font-weight: 700 !important; font-weight: 800 !important;
margin-bottom: 16px !important; margin-bottom: 20px !important;
background: linear-gradient(135deg, #7400b8 0%, #5e60ce 50%, #4ea8de 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
letter-spacing: -0.02em;
}
.sectionTitle::after {
content: "";
position: absolute;
bottom: -12px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 5px;
background: linear-gradient(90deg, #7400b8, #6930c3);
border-radius: 3px;
box-shadow: 0 2px 8px rgba(116, 0, 184, 0.3);
} }
.sectionSubtitle { .sectionSubtitle {
font-size: 1.1rem; font-size: 1.2rem;
color: #666; color: #64748b;
max-width: 600px; max-width: 700px;
margin: 0 auto; margin: 0 auto;
line-height: 1.7;
font-weight: 400;
} }
.showcaseContainer { .showcaseContainer {
position: relative; position: relative;
padding: 20px 0; padding: 40px 0;
} }
.projectsGrid { .projectsGrid {
@@ -46,12 +76,37 @@
} }
.projectCard { .projectCard {
height: 100%; height: fit-content;
border-radius: 12px; border-radius: 20px;
overflow: hidden; overflow: hidden;
transition: all 0.3s ease; transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
border: none; border: none;
cursor: pointer;
background: white;
position: relative;
}
.projectCard::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(116, 0, 184, 0.05) 0%, rgba(94, 96, 206, 0.05) 100%);
opacity: 0;
transition: opacity 0.3s ease;
z-index: 1;
}
.projectCard:hover::before {
opacity: 1;
}
.projectCard:hover {
transform: translateY(-12px) scale(1.02);
box-shadow: 0 24px 48px rgba(116, 0, 184, 0.15);
} }
.projectImageContainer { .projectImageContainer {
@@ -64,11 +119,11 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
transition: transform 0.5s ease; transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
} }
.projectCard:hover .projectImage { .projectCard:hover .projectImage {
transform: scale(1.05); transform: scale(1.08);
} }
.projectOverlay { .projectOverlay {
@@ -77,12 +132,13 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgba(0, 0, 0, 0.4);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease; transition: all 0.4s ease;
background: rgba(116, 0, 184, 0.9);
backdrop-filter: blur(4px);
} }
.projectCard:hover .projectOverlay { .projectCard:hover .projectOverlay {
@@ -91,89 +147,507 @@
.viewButton { .viewButton {
background: #fff; background: #fff;
color: #6e48aa; color: #7400b8;
border: none; border: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
border-radius: 12px;
padding: 12px 24px;
font-weight: 600;
transition: all 0.3s ease;
} }
.viewButton:hover { .viewButton:hover {
background: #6e48aa; background: #7400b8;
color: #fff; color: #fff;
transform: scale(1.05);
box-shadow: 0 6px 20px rgba(116, 0, 184, 0.3);
} }
.categoryTag { .categoryTag {
margin-bottom: 12px; margin-bottom: 16px;
border-radius: 20px;
font-weight: 600;
padding: 6px 16px;
font-size: 0.85rem;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
color: white;
border: none;
box-shadow: 0 2px 8px rgba(116, 0, 184, 0.2);
} }
.technologiesList { .technologiesList {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 6px;
margin-top: 16px; margin-top: 16px;
} }
.techTag { .techTag {
margin: 0; margin: 0;
color: #6e48aa; background: #f8fafc;
color: #475569;
border: 1px solid #e2e8f0;
font-size: 0.8rem;
padding: 4px 10px;
border-radius: 12px;
font-weight: 500;
transition: all 0.3s ease;
}
.techTag:hover {
background: #7400b8;
color: white;
border-color: #7400b8;
transform: translateY(-1px);
} }
.featuredBadge { .featuredBadge {
z-index: 2; z-index: 2;
position: absolute;
top: 16px;
right: 16px;
background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
color: white;
border: none;
border-radius: 20px;
padding: 6px 12px;
font-size: 0.75rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(251, 191, 36, 0.3);
} }
.navigationControls { .navigationControls {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 16px; gap: 20px;
margin-top: 40px; margin-top: 60px;
} }
.navButton { .navButton {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); width: 48px;
height: 48px;
border-radius: 50%;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
background: white;
border: 1px solid #e2e8f0;
}
.navButton:hover {
transform: scale(1.1);
box-shadow: 0 6px 20px rgba(116, 0, 184, 0.2);
border-color: #7400b8;
color: #7400b8;
} }
.pageIndicator { .pageIndicator {
font-size: 0.9rem; font-size: 1rem;
color: #666; color: #64748b;
font-weight: 500;
padding: 8px 16px;
background: #f8fafc;
border-radius: 20px;
border: 1px solid #e2e8f0;
} }
.viewAllContainer { .viewAllContainer {
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-top: 48px; margin-top: 60px;
} }
.viewAllButton { .viewAllButton {
height: 48px; height: 56px;
padding: 0 32px; padding: 0 40px;
border-radius: 24px; border-radius: 28px;
font-weight: 500; font-weight: 600;
font-size: 1.1rem;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
border: none; border: none;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15); box-shadow: 0 8px 24px rgba(116, 0, 184, 0.2);
transition: all 0.3s ease; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.viewAllButton::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.6s ease;
}
.viewAllButton:hover::before {
left: 100%;
} }
.viewAllButton:hover { .viewAllButton:hover {
transform: translateY(-2px); transform: translateY(-3px);
box-shadow: 0 6px 16px rgba(24, 144, 255, 0.2); box-shadow: 0 12px 32px rgba(116, 0, 184, 0.3);
} }
/* Modal Styles */
.projectModal {
border-radius: 20px;
overflow: hidden;
}
.projectModal :global(.ant-modal-content) {
border-radius: 20px;
overflow: hidden;
box-shadow: 0 32px 64px rgba(0, 0, 0, 0.3);
}
.projectModal :global(.ant-modal-header) {
display: none;
}
.projectModal :global(.ant-modal-body) {
padding: 0;
}
.closeIcon {
font-size: 20px;
color: #64748b;
transition: all 0.3s ease;
}
.closeIcon:hover {
color: #7400b8;
transform: scale(1.1);
}
.modalContent {
background: #fff;
border-radius: 20px;
overflow: hidden;
}
.modalHeader {
padding: 40px 40px 30px;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
color: white;
position: relative;
}
.modalHeader::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="50" cy="50" r="1" fill="white" opacity="0.1"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
opacity: 0.4;
}
.modalTitleSection {
position: relative;
z-index: 1;
}
.modalTitle {
color: white !important;
font-size: 2.5rem !important;
font-weight: 800 !important;
margin-bottom: 16px !important;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
letter-spacing: -0.02em;
}
.modalCategory {
background: rgba(255, 255, 255, 0.2) !important;
border: 1px solid rgba(255, 255, 255, 0.3) !important;
color: white !important;
font-weight: 600;
padding: 6px 16px;
border-radius: 20px;
backdrop-filter: blur(10px);
}
.modalActions {
position: absolute;
top: 40px;
right: 40px;
display: flex;
gap: 16px;
z-index: 1;
}
.actionButton {
height: 44px;
border-radius: 22px;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
padding: 0 24px;
}
.actionButton:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.modalBody {
padding: 0;
}
.projectImages {
position: relative;
background: #f8f9fa;
}
.imageCarousel {
border-radius: 0;
}
.carouselItem {
position: relative;
height: 450px;
overflow: hidden;
}
.modalImage {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.4s ease;
}
.carouselItem:hover .modalImage {
transform: scale(1.03);
}
.carouselDots {
bottom: 24px;
}
.carouselDots :global(.ant-carousel .slick-dots li button) {
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
width: 10px;
height: 10px;
transition: all 0.3s ease;
}
.carouselDots :global(.ant-carousel .slick-dots li.slick-active button) {
background: #7400b8;
transform: scale(1.2);
}
.projectDetails {
padding: 40px;
background: white;
}
.detailSection {
margin-bottom: 40px;
}
.detailSection:last-child {
margin-bottom: 0;
}
.sectionTitle {
font-size: 1.6rem !important;
font-weight: 700 !important;
margin-bottom: 20px !important;
color: #1e293b;
position: relative;
}
.sectionTitle::after {
content: "";
position: absolute;
bottom: -6px;
left: 0;
width: 50px;
height: 4px;
background: linear-gradient(90deg, #7400b8, #6930c3);
border-radius: 2px;
}
.projectDescription {
font-size: 1.15rem;
line-height: 1.8;
color: #475569;
margin-bottom: 0;
font-weight: 400;
}
.detailGrid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
margin-top: 40px;
}
.featuresList {
list-style: none;
padding: 0;
margin: 0;
}
.featureItem {
position: relative;
padding: 16px 0 16px 32px;
font-size: 1.05rem;
color: #475569;
line-height: 1.6;
border-bottom: 1px solid #f1f5f9;
font-weight: 500;
}
.featureItem:last-child {
border-bottom: none;
}
.featureItem::before {
content: "✓";
position: absolute;
left: 0;
top: 16px;
color: #7400b8;
font-weight: bold;
font-size: 16px;
background: rgba(116, 0, 184, 0.1);
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.projectInfo {
display: flex;
flex-direction: column;
gap: 20px;
}
.infoItem {
display: flex;
align-items: flex-start;
gap: 16px;
padding: 20px;
background: #f8fafc;
border-radius: 12px;
border-left: 4px solid #7400b8;
transition: all 0.3s ease;
}
.infoItem:hover {
background: #f1f5f9;
transform: translateX(4px);
}
.infoItem:last-child {
flex-direction: column;
gap: 12px;
}
.modalTechnologies {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 12px;
}
.modalTechTag {
background: rgba(116, 0, 184, 0.1);
border: 1px solid rgba(116, 0, 184, 0.2);
color: #7400b8;
font-weight: 600;
border-radius: 20px;
padding: 6px 14px;
font-size: 0.9rem;
transition: all 0.3s ease;
}
.modalTechTag:hover {
background: #7400b8;
color: white;
transform: translateY(-1px);
}
/* Responsive Design */
@media (max-width: 768px) { @media (max-width: 768px) {
.projectsSection { .projectsSection {
padding: 60px 0; padding: 80px 0;
} }
.sectionTitle { .sectionTitle {
font-size: 2rem !important; font-size: 2.5rem !important;
} }
.projectImageContainer { .projectImageContainer {
height: 180px; height: 180px;
} }
.projectModal {
margin: 16px;
max-width: calc(100vw - 32px);
}
.modalHeader {
padding: 30px 24px 24px;
}
.modalTitle {
font-size: 2rem !important;
}
.modalActions {
position: static;
margin-top: 20px;
justify-content: flex-start;
}
.projectDetails {
padding: 30px 24px;
}
.detailGrid {
grid-template-columns: 1fr;
gap: 30px;
}
.carouselItem {
height: 300px;
}
.actionButton {
height: 40px;
font-size: 0.95rem;
}
}
@media (max-width: 480px) {
.modalHeader {
padding: 24px 20px 20px;
}
.modalTitle {
font-size: 1.8rem !important;
}
.projectDetails {
padding: 24px 20px;
}
.carouselItem {
height: 250px;
}
.sectionTitle {
font-size: 2rem !important;
}
} }

View File

@@ -1,185 +0,0 @@
// File: src/components/home/ServicesSection.tsx
"use client";
import {
CloudOutlined,
CodeOutlined,
GlobalOutlined,
LineChartOutlined,
MobileOutlined,
RobotOutlined,
RocketOutlined,
ShoppingOutlined,
} from '@ant-design/icons';
import { Button, Card, Col, Row, Typography } from 'antd';
import { motion } from 'framer-motion';
import React, { useEffect, useState } from 'react';
import styles from './ServicesSelector.module.css';
const { Title, Paragraph } = Typography;
interface ServicesSectionProps {
userPreferences: string[];
}
interface Service {
id: string;
title: string;
description: string;
icon: React.ReactNode;
preferenceMatches: string[];
}
const allServices: Service[] = [
{
id: 'webdev',
title: 'Web Development',
description: 'Custom web applications with cutting-edge technologies and responsive design.',
icon: <CodeOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ecommerce', 'cloud', 'seo']
},
{
id: 'branding',
title: 'Branding & Identity',
description: 'Complete brand identity packages including logos, guidelines, and visual systems.',
icon: <RocketOutlined className={styles.serviceIcon} />,
preferenceMatches: ['branding', 'seo']
},
{
id: 'ecom',
title: 'E-commerce Solutions',
description: 'Full-stack e-commerce platforms with secure payment integration and inventory management.',
icon: <ShoppingOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ecommerce', 'branding']
},
{
id: 'seo',
title: 'SEO & Marketing',
description: 'Data-driven digital marketing strategies to improve visibility and drive conversions.',
icon: <LineChartOutlined className={styles.serviceIcon} />,
preferenceMatches: ['seo', 'branding']
},
{
id: 'mobile',
title: 'Mobile Development',
description: 'Native and cross-platform mobile applications for iOS and Android.',
icon: <MobileOutlined className={styles.serviceIcon} />,
preferenceMatches: ['mobile', 'ai']
},
{
id: 'cloud',
title: 'Cloud Solutions',
description: 'Scalable cloud infrastructures, migrations, and DevOps automation.',
icon: <CloudOutlined className={styles.serviceIcon} />,
preferenceMatches: ['cloud', 'ai']
},
{
id: 'ai',
title: 'AI & Machine Learning',
description: 'Custom AI solutions for automation, prediction, and data analysis.',
icon: <RobotOutlined className={styles.serviceIcon} />,
preferenceMatches: ['ai', 'cloud']
},
{
id: 'global',
title: 'Global IT Consulting',
description: 'Strategic technology consulting to drive digital transformation and innovation.',
icon: <GlobalOutlined className={styles.serviceIcon} />,
preferenceMatches: ['cloud', 'branding', 'seo']
},
];
const ServicesSection: React.FC<ServicesSectionProps> = ({ userPreferences }) => {
const [services, setServices] = useState<Service[]>([]);
useEffect(() => {
// Sort services based on user preferences
if (userPreferences.length > 0) {
const sortedServices = [...allServices].sort((a, b) => {
const aMatches = a.preferenceMatches.filter(pref => userPreferences.includes(pref)).length;
const bMatches = b.preferenceMatches.filter(pref => userPreferences.includes(pref)).length;
return bMatches - aMatches;
});
setServices(sortedServices);
} else {
// If no preferences, show all services in default order
setServices(allServices);
}
}, [userPreferences]);
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { y: 50, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 }
}
};
return (
<section className={styles.servicesSection}>
<div className={styles.sectionBackground}>
<div className={styles.glowOrb}></div>
</div>
<div className={styles.container}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className={styles.sectionHeader}
>
<Title level={2} className={styles.sectionTitle}>Our Services</Title>
<Paragraph className={styles.sectionSubtitle}>
Innovative technology solutions customized for your business needs
</Paragraph>
</motion.div>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<Row gutter={[24, 24]}>
{services.map((service) => (
<Col xs={24} sm={12} lg={8} xl={6} key={service.id}>
<motion.div variants={itemVariants}>
<Card
hoverable
className={styles.serviceCard}
cover={
<div className={styles.serviceIconWrapper}>
{service.icon}
</div>
}
>
<Card.Meta
title={service.title}
description={service.description}
/>
<Button type="link" className={styles.learnMoreBtn}>
Learn more
</Button>
</Card>
</motion.div>
</Col>
))}
</Row>
</motion.div>
</div>
</section>
);
};
export default ServicesSection;

View File

@@ -1,102 +0,0 @@
/* File: src/components/home/ServicesSection.module.css */
.servicesSection {
position: relative;
padding: 100px 0;
overflow: hidden;
background-color: #f8f9fa;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
position: relative;
z-index: 2;
}
.sectionBackground {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 1;
}
.glowOrb {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
background: var(--primary-glow);
top: -150px;
right: -100px;
filter: blur(50px);
}
.sectionHeader {
text-align: center;
margin-bottom: 60px;
}
.sectionTitle {
font-size: 2.5rem !important;
font-weight: 700 !important;
margin-bottom: 16px !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.sectionSubtitle {
font-size: 1.1rem;
color: #666;
max-width: 600px;
margin: 0 auto;
}
.serviceCard {
height: 100%;
border-radius: 12px;
overflow: hidden;
transition: all 0.3s ease;
border: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.serviceCard:hover {
transform: translateY(-8px);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}
.serviceIconWrapper {
display: flex;
justify-content: center;
align-items: center;
height: 120px;
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
}
.serviceIcon {
font-size: 3rem;
color: #6e48aa;
}
.learnMoreBtn {
display: block;
margin-top: 16px;
padding: 0;
font-weight: 500;
}
@media (max-width: 768px) {
.servicesSection {
padding: 60px 0;
}
.sectionTitle {
font-size: 2rem !important;
}
}

View File

@@ -1,42 +1,72 @@
/* File: src/components/TestimonialsSection/TestimonialsSection.module.css */ /* File: src/components/TestimonialsSection/TestimonialsSection.module.css */
.testimonialsSection { .testimonialsSection {
padding: 100px 0; padding: 120px 0;
background-color: #fff; background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.testimonialsSection::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="circles" width="30" height="30" patternUnits="userSpaceOnUse"><circle cx="15" cy="15" r="2" fill="%23e2e8f0" opacity="0.6"/></pattern></defs><rect width="100" height="100" fill="url(%23circles)"/></svg>');
opacity: 0.4;
}
.container { .container {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
padding: 0 16px; padding: 0 16px;
position: relative; position: relative;
z-index: 1;
} }
.sectionHeader { .sectionHeader {
text-align: center; text-align: center;
margin-bottom: 60px; margin-bottom: 80px;
} }
.sectionTitle { .sectionTitle {
font-size: 2.5rem !important; font-size: 3rem !important;
font-weight: 700 !important; font-weight: 800 !important;
margin-bottom: 16px !important; margin-bottom: 20px !important;
background: linear-gradient(135deg, #7400b8 0%, #5e60ce 50%, #4ea8de 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
letter-spacing: -0.02em;
}
.sectionTitle::after {
content: "";
position: absolute;
bottom: -12px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 5px;
background: linear-gradient(90deg, #7400b8, #6930c3);
border-radius: 3px;
box-shadow: 0 2px 8px rgba(116, 0, 184, 0.3);
} }
.sectionSubtitle { .sectionSubtitle {
font-size: 1.1rem; font-size: 1.2rem;
color: #666; color: #64748b;
max-width: 600px; max-width: 700px;
margin: 0 auto; margin: 0 auto;
line-height: 1.7;
font-weight: 400;
} }
.showcaseContainer { .showcaseContainer {
position: relative; position: relative;
padding: 20px 0; padding: 40px 0;
} }
.testimonialsCarousel { .testimonialsCarousel {
@@ -45,49 +75,94 @@
} }
.testimonialItem { .testimonialItem {
padding: 0 15px; padding: 0 20px;
} }
.testimonialCard { .testimonialCard {
height: 100%; height: 100%;
border-radius: 12px; border-radius: 20px;
overflow: hidden; overflow: hidden;
transition: all 0.3s ease; transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
border: none; border: none;
padding: 30px; padding: 40px 30px;
background: white;
position: relative;
} }
.clientName { .testimonialCard::before {
font-size: 1.2rem; content: "";
color: #333; position: absolute;
margin-bottom: 4px; top: 20px;
left: 30px;
font-size: 4rem;
color: rgba(116, 0, 184, 0.1);
font-family: serif;
line-height: 1;
} }
.clientTitle { .testimonialCard::after {
font-size: 0.9rem; content: "";
position: absolute;
bottom: 20px;
right: 30px;
font-size: 4rem;
color: rgba(116, 0, 184, 0.1);
font-family: serif;
line-height: 1;
transform: rotate(180deg);
}
.testimonialCard:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 20px 48px rgba(116, 0, 184, 0.15);
} }
.testimonialContent { .testimonialContent {
font-size: 1rem; font-size: 1.1rem;
color: #555; color: #475569;
line-height: 1.6; line-height: 1.8;
font-style: italic; font-style: italic;
margin-bottom: 24px;
position: relative;
z-index: 1;
font-weight: 400;
}
.clientName {
font-size: 1.3rem;
color: #1e293b;
margin-bottom: 6px;
font-weight: 600;
position: relative;
z-index: 1;
}
.clientTitle {
font-size: 0.95rem;
color: #64748b;
font-weight: 500;
margin-bottom: 20px;
position: relative;
z-index: 1;
} }
.projectInfo { .projectInfo {
margin-top: 16px; margin-top: 24px;
padding-top: 16px; padding-top: 24px;
border-top: 1px solid #f0f0f0; border-top: 2px solid #f1f5f9;
position: relative;
z-index: 1;
} }
.projectLabel { .projectLabel {
background: var(--primary); background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
-webkit-background-clip: text; /* For Safari */ -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent !important; /* Hide original text color */ color: transparent !important;
font-weight: 600;
margin-right: 8px; margin-right: 8px;
font-size: 0.9rem;
} }
.technologiesList { .technologiesList {
@@ -99,57 +174,170 @@
.techTag { .techTag {
margin: 0; margin: 0;
background: #f5f5f5; background: #f8fafc;
border-color: #d9d9d9; border: 1px solid #e2e8f0;
color: #666; color: #475569;
font-size: 0.8rem;
padding: 4px 10px;
border-radius: 12px;
font-weight: 500;
transition: all 0.3s ease;
}
.techTag:hover {
background: #7400b8;
color: white;
border-color: #7400b8;
transform: translateY(-1px);
} }
.filledStar { .filledStar {
color: #faad14; color: #fbbf24;
font-size: 1.1rem;
} }
.emptyStar { .emptyStar {
color: #d9d9d9; color: #e2e8f0;
font-size: 1.1rem;
}
.carouselDots {
margin-top: 40px;
} }
.carouselDots li button { .carouselDots li button {
background: #d9d9d9 !important; background: #d1d5db !important;
width: 10px !important; width: 12px !important;
height: 10px !important; height: 12px !important;
border-radius: 50% !important; border-radius: 50% !important;
transition: all 0.3s ease !important;
} }
.carouselDots li.slick-active button { .carouselDots li.slick-active button {
background: #1890ff !important; background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%) !important;
transform: scale(1.2);
box-shadow: 0 2px 8px rgba(116, 0, 184, 0.3);
} }
.viewAllContainer { .viewAllContainer {
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-top: 48px; margin-top: 60px;
} }
.viewAllButton { .viewAllButton {
height: 48px; height: 56px;
padding: 0 32px; padding: 0 40px;
border-radius: 24px; border-radius: 28px;
font-weight: 500; font-weight: 600;
font-size: 1.1rem;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
color: white; color: white;
border: none; border: none;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15); box-shadow: 0 8px 24px rgba(116, 0, 184, 0.2);
transition: all 0.3s ease; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer; cursor: pointer;
font-size: 1rem; position: relative;
overflow: hidden;
}
.viewAllButton::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.6s ease;
}
.viewAllButton:hover::before {
left: 100%;
} }
.viewAllButton:hover { .viewAllButton:hover {
transform: translateY(-2px); transform: translateY(-3px);
box-shadow: 0 6px 16px rgba(24, 144, 255, 0.2); box-shadow: 0 12px 32px rgba(116, 0, 184, 0.3);
} }
/* Enhanced Animation for Testimonial Cards */
.testimonialCard {
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Staggered animation for multiple cards */
.testimonialItem:nth-child(1) .testimonialCard {
animation-delay: 0.1s;
}
.testimonialItem:nth-child(2) .testimonialCard {
animation-delay: 0.2s;
}
.testimonialItem:nth-child(3) .testimonialCard {
animation-delay: 0.3s;
}
/* Enhanced hover effects */
.testimonialCard:hover::before,
.testimonialCard:hover::after {
color: rgba(116, 0, 184, 0.2);
transform: scale(1.1);
transition: all 0.3s ease;
}
.testimonialCard:hover .clientName {
color: #7400b8;
transition: color 0.3s ease;
}
/* Responsive Design */
@media (max-width: 768px) { @media (max-width: 768px) {
.testimonialsSection {
padding: 80px 0;
}
.sectionTitle {
font-size: 2.5rem !important;
}
.testimonialCard {
padding: 30px 24px;
}
.testimonialCard::before,
.testimonialCard::after {
font-size: 3rem;
}
.testimonialContent {
font-size: 1rem;
}
.clientName {
font-size: 1.2rem;
}
.viewAllButton {
height: 48px;
padding: 0 32px;
font-size: 1rem;
}
}
@media (max-width: 480px) {
.testimonialsSection { .testimonialsSection {
padding: 60px 0; padding: 60px 0;
} }
@@ -158,7 +346,42 @@
font-size: 2rem !important; font-size: 2rem !important;
} }
.sectionSubtitle {
font-size: 1rem;
}
.testimonialCard { .testimonialCard {
padding: 20px; padding: 24px 20px;
}
.testimonialCard::before,
.testimonialCard::after {
font-size: 2.5rem;
top: 15px;
left: 20px;
}
.testimonialCard::after {
bottom: 15px;
right: 20px;
}
.testimonialContent {
font-size: 0.95rem;
line-height: 1.7;
}
.clientName {
font-size: 1.1rem;
}
.clientTitle {
font-size: 0.9rem;
}
.viewAllButton {
height: 44px;
padding: 0 28px;
font-size: 0.95rem;
} }
} }

View File

@@ -0,0 +1,32 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Contact Us | Tech Master - Get In Touch for IT Solutions",
description: "Contact Tech Master in Dubai for innovative IT solutions, digital transformation, web development, and mobile app development. Start your project today.",
keywords: [
"contact Tech Master",
"Dubai IT company contact",
"web development Dubai contact",
"digital transformation consultation",
"IT solutions contact",
"mobile app development Dubai",
"enterprise software consultation",
"tech agency Dubai contact"
],
openGraph: {
title: "Contact Us | Tech Master - Get In Touch for IT Solutions",
description: "Contact Tech Master in Dubai for innovative IT solutions, digital transformation, and mobile app development.",
url: "https://tech-masters.guru/contact",
},
alternates: {
canonical: "/contact",
},
};
export default function ContactLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -0,0 +1,518 @@
/* Contact Page Enhanced Styles */
.main {
padding-top: 80px;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
min-height: 100vh;
}
/* Hero Section */
.heroSection {
position: relative;
padding: 80px 0 60px;
background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
color: white;
overflow: hidden;
}
.heroBackground {
position: absolute;
inset: 0;
opacity: 0.1;
}
.heroOrb1 {
position: absolute;
top: -100px;
left: -100px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 6s ease-in-out infinite;
}
.heroOrb2 {
position: absolute;
top: 50px;
right: -150px;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(35px);
animation: float 8s ease-in-out infinite reverse;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
.heroContent {
position: relative;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
text-align: center;
}
.heroTitle {
font-size: 3.5rem;
font-weight: 700;
margin-bottom: 20px;
line-height: 1.2;
color: white;
}
.gradientText {
background: linear-gradient(135deg, #a855f7 0%, #ec4899 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.heroSubtitle {
font-size: 1.25rem;
color: #cbd5e1;
max-width: 600px;
margin: 0 auto 30px;
line-height: 1.6;
}
.contactStats {
display: flex;
justify-content: center;
gap: 40px;
margin-top: 40px;
}
.statItem {
text-align: center;
}
.statNumber {
font-size: 2rem;
font-weight: 700;
color: #a855f7;
display: block;
}
.statLabel {
font-size: 0.9rem;
color: #94a3b8;
margin-top: 4px;
}
/* Contact Section */
.contactSection {
padding: 80px 0;
position: relative;
}
.contactBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.05) 0%, rgba(236, 72, 153, 0.05) 100%);
}
.contactContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
position: relative;
}
.contactGrid {
display: grid;
grid-template-columns: 1fr 1.5fr;
gap: 60px;
align-items: start;
}
/* Contact Info */
.contactInfo {
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
.contactInfo::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
}
.contactInfoHeader {
margin-bottom: 40px;
}
.contactInfoTitle {
font-size: 1.75rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 12px;
}
.contactInfoSubtitle {
color: #64748b;
line-height: 1.6;
}
.contactInfoList {
display: flex;
flex-direction: column;
gap: 24px;
}
.contactInfoItem {
display: flex;
align-items: flex-start;
gap: 16px;
padding: 20px;
background: #f8fafc;
border-radius: 12px;
transition: all 0.3s ease;
}
.contactInfoItem:hover {
background: #f1f5f9;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.iconWrapper {
width: 50px;
height: 50px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all 0.3s ease;
}
.iconWrapperEmail {
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
}
.iconWrapperPhone {
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
.iconWrapperLocation {
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
}
.contactIcon {
font-size: 20px;
color: white;
}
.contactDetails {
flex: 1;
}
.contactLabel {
display: block;
font-weight: 600;
color: #1e293b;
margin-bottom: 4px;
font-size: 0.95rem;
}
.contactValue {
color: #64748b;
line-height: 1.5;
font-size: 0.9rem;
}
/* Map Section */
.mapSection {
margin-top: 30px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.mapContainer {
position: relative;
height: 200px;
background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);
display: flex;
align-items: center;
justify-content: center;
}
.mapPlaceholder {
text-align: center;
color: #64748b;
}
.mapIcon {
font-size: 3rem;
margin-bottom: 10px;
color: #8b5cf6;
}
/* Contact Form */
.contactForm {
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
.contactForm::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
}
.formHeader {
margin-bottom: 30px;
}
.formTitle {
font-size: 1.75rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 12px;
}
.formSubtitle {
color: #64748b;
line-height: 1.6;
}
.form {
display: flex;
flex-direction: column;
gap: 20px;
}
.formRow {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.formField {
margin-bottom: 0;
}
.formField :global(.ant-form-item-label) {
padding-bottom: 8px;
}
.formField :global(.ant-form-item-label > label) {
font-weight: 600;
color: #374151;
font-size: 0.9rem;
}
.formField :global(.ant-input),
.formField :global(.ant-input-affix-wrapper) {
border-radius: 12px;
border: 2px solid #e5e7eb;
padding: 12px 16px;
font-size: 0.95rem;
transition: all 0.3s ease;
}
.formField :global(.ant-input:focus),
.formField :global(.ant-input-affix-wrapper:focus),
.formField :global(.ant-input-affix-wrapper-focused) {
border-color: #8b5cf6;
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
}
.formField :global(.ant-input:hover),
.formField :global(.ant-input-affix-wrapper:hover) {
border-color: #a855f7;
}
.messageField {
margin-bottom: 0;
}
.messageField :global(.ant-input) {
resize: none;
min-height: 120px;
}
.submitButton {
height: 50px;
border-radius: 25px;
font-weight: 600;
font-size: 1rem;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none;
box-shadow: 0 8px 25px rgba(139, 92, 246, 0.3);
transition: all 0.3s ease;
margin-top: 10px;
}
.submitButton:hover {
transform: translateY(-2px);
box-shadow: 0 12px 35px rgba(139, 92, 246, 0.4);
background: linear-gradient(135deg, #7c3aed 0%, #db2777 100%);
}
.submitButton:active {
transform: translateY(0);
}
/* Additional Features */
.featuresSection {
padding: 60px 0;
background: white;
}
.featuresContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.featuresGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-top: 40px;
}
.featureCard {
text-align: center;
padding: 30px;
background: #f8fafc;
border-radius: 16px;
transition: all 0.3s ease;
}
.featureCard:hover {
background: white;
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
.featureIcon {
width: 60px;
height: 60px;
margin: 0 auto 20px;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
}
.featureIconSupport {
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
}
.featureIconResponse {
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
.featureIconSecurity {
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
}
.featureTitle {
font-size: 1.25rem;
font-weight: 600;
color: #1e293b;
margin-bottom: 12px;
}
.featureDescription {
color: #64748b;
line-height: 1.6;
}
/* Responsive Design */
@media (max-width: 1024px) {
.contactGrid {
grid-template-columns: 1fr;
gap: 40px;
}
.heroTitle {
font-size: 3rem;
}
}
@media (max-width: 768px) {
.main {
padding-top: 60px;
}
.heroSection {
padding: 60px 0 40px;
}
.heroTitle {
font-size: 2.5rem;
}
.heroSubtitle {
font-size: 1.1rem;
}
.contactStats {
flex-direction: column;
gap: 20px;
}
.contactSection {
padding: 60px 0;
}
.contactInfo,
.contactForm {
padding: 30px 20px;
}
.formRow {
grid-template-columns: 1fr;
gap: 15px;
}
.featuresGrid {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
.heroTitle {
font-size: 2rem;
}
.contactInfo,
.contactForm {
padding: 25px 15px;
}
.contactInfoItem {
padding: 15px;
}
}

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

@@ -0,0 +1,413 @@
"use client";
import {
BulbOutlined,
ClockCircleOutlined,
EnvironmentOutlined,
IeOutlined,
MailOutlined,
PhoneOutlined,
SendOutlined,
UserOutlined,
} from "@ant-design/icons";
import { Button, Form, Input, message, Typography } from "antd";
import { motion } from "framer-motion";
import { useState } from "react";
import Footer from "../components/Footer/Footer";
import styles from "./page.module.css";
const { Title, Paragraph, Text } = Typography;
const { TextArea } = Input;
export default function ContactPage() {
const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false);
const handleSubmit = async () => {
setSubmitting(true);
// Simulate API call
setTimeout(() => {
message.success("Your message has been sent successfully!");
form.resetFields();
setSubmitting(false);
}, 1500);
};
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
},
},
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 },
},
};
return (
<main className={styles.main}>
{/* Hero Section */}
<section className={styles.heroSection}>
<div className={styles.heroBackground}>
<div className={styles.heroOrb1}></div>
<div className={styles.heroOrb2}></div>
</div>
<div className={styles.heroContent}>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<Title level={1} className={styles.heroTitle}>
Get In <span className={styles.gradientText}>Touch</span>
</Title>
<Paragraph className={styles.heroSubtitle}>
Ready to transform your ideas into reality? Let&apos;s start a
conversation about your next project and how we can help bring
your vision to life.
</Paragraph>
<div className={styles.contactStats}>
<div className={styles.statItem}>
<span className={styles.statNumber}>24/7</span>
<span className={styles.statLabel}>Support</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>2hr</span>
<span className={styles.statLabel}>Response Time</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>100%</span>
<span className={styles.statLabel}>Secure</span>
</div>
</div>
</motion.div>
</div>
</section>
{/* Contact Section */}
<section className={styles.contactSection}>
<div className={styles.contactBackground}></div>
<div className={styles.contactContainer}>
<div className={styles.contactGrid}>
{/* Contact Info */}
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.contactInfo}
>
<div className={styles.contactInfoHeader}>
<Title level={3} className={styles.contactInfoTitle}>
Contact Information
</Title>
<Paragraph className={styles.contactInfoSubtitle}>
Reach out to us through any of these channels. We&apos;re here
to help you succeed with your next project.
</Paragraph>
</div>
<div className={styles.contactInfoList}>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div
className={`${styles.iconWrapper} ${styles.iconWrapperEmail}`}
>
<MailOutlined className={styles.contactIcon} />
</div>
<div className={styles.contactDetails}>
<Text strong className={styles.contactLabel}>
Email
</Text>
<Text className={styles.contactValue}>
info@techmaster.com
</Text>
</div>
</motion.div>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div
className={`${styles.iconWrapper} ${styles.iconWrapperPhone}`}
>
<PhoneOutlined className={styles.contactIcon} />
</div>
<div className={styles.contactDetails}>
<Text strong className={styles.contactLabel}>
Phone
</Text>
<Text className={styles.contactValue}>
+1 (555) 123-4567
</Text>
</div>
</motion.div>
<motion.div
variants={itemVariants}
className={styles.contactInfoItem}
>
<div
className={`${styles.iconWrapper} ${styles.iconWrapperLocation}`}
>
<EnvironmentOutlined className={styles.contactIcon} />
</div>
<div className={styles.contactDetails}>
<Text strong className={styles.contactLabel}>
Address
</Text>
<Text className={styles.contactValue}>
1234 Tech Boulevard, Innovation District
<br />
San Francisco, CA 94105
</Text>
</div>
</motion.div>
</div>
<motion.div variants={itemVariants} className={styles.mapSection}>
<div className={styles.mapContainer}>
<div className={styles.mapPlaceholder}>
<EnvironmentOutlined className={styles.mapIcon} />
<div>Interactive Map Coming Soon</div>
</div>
</div>
</motion.div>
</motion.div>
{/* Contact Form */}
<motion.div
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
viewport={{ once: true }}
className={styles.contactForm}
>
<div className={styles.formHeader}>
<Title level={3} className={styles.formTitle}>
Send Us a Message
</Title>
<Paragraph className={styles.formSubtitle}>
Tell us about your project and we&apos;ll get back to you
within 2 hours.
</Paragraph>
</div>
<Form
form={form}
layout="vertical"
onFinish={handleSubmit}
className={styles.form}
>
<div className={styles.formRow}>
<Form.Item
name="name"
label="Full Name"
rules={[
{ required: true, message: "Please enter your name" },
]}
className={styles.formField}
>
<Input
size="large"
placeholder="Your full name"
prefix={<UserOutlined />}
/>
</Form.Item>
<Form.Item
name="email"
label="Email Address"
rules={[
{ required: true, message: "Please enter your email" },
{
type: "email",
message: "Please enter a valid email",
},
]}
className={styles.formField}
>
<Input
size="large"
placeholder="your.email@example.com"
prefix={<MailOutlined />}
/>
</Form.Item>
</div>
<Form.Item
name="subject"
label="Subject"
rules={[
{ required: true, message: "Please enter a subject" },
]}
className={styles.formField}
>
<Input
size="large"
placeholder="How can we help you?"
prefix={<BulbOutlined />}
/>
</Form.Item>
<Form.Item
name="message"
label="Message"
rules={[
{ required: true, message: "Please enter your message" },
]}
className={`${styles.formField} ${styles.messageField}`}
>
<TextArea
rows={5}
placeholder="Tell us about your project, goals, and any specific requirements..."
/>
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
size="large"
icon={<SendOutlined />}
loading={submitting}
className={styles.submitButton}
>
Send Message
</Button>
</Form.Item>
</Form>
</motion.div>
</div>
</div>
</section>
{/* Features Section */}
<section className={styles.featuresSection}>
<div className={styles.featuresContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
style={{ textAlign: "center", marginBottom: "40px" }}
>
<Title
level={2}
style={{
fontSize: "2.5rem",
fontWeight: 700,
color: "#1e293b",
marginBottom: "16px",
}}
>
Why Choose{" "}
<span
style={{
background:
"linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
backgroundClip: "text",
}}
>
Us
</span>
</Title>
<Paragraph
style={{
fontSize: "1.1rem",
color: "#64748b",
maxWidth: "600px",
margin: "0 auto",
}}
>
We&apos;re committed to providing exceptional service and support
throughout your journey with us.
</Paragraph>
</motion.div>
<div className={styles.featuresGrid}>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.1 }}
viewport={{ once: true }}
className={styles.featureCard}
>
<div
className={`${styles.featureIcon} ${styles.featureIconSupport}`}
>
<UserOutlined />
</div>
<Title level={4} className={styles.featureTitle}>
24/7 Support
</Title>
<Paragraph className={styles.featureDescription}>
Our dedicated team is available around the clock to assist you
with any questions or concerns.
</Paragraph>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
viewport={{ once: true }}
className={styles.featureCard}
>
<div
className={`${styles.featureIcon} ${styles.featureIconResponse}`}
>
<ClockCircleOutlined />
</div>
<Title level={4} className={styles.featureTitle}>
Fast Response
</Title>
<Paragraph className={styles.featureDescription}>
We guarantee a response within 2 hours during business hours,
ensuring your project moves forward quickly.
</Paragraph>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.3 }}
viewport={{ once: true }}
className={styles.featureCard}
>
<div
className={`${styles.featureIcon} ${styles.featureIconSecurity}`}
>
<IeOutlined />
</div>
<Title level={4} className={styles.featureTitle}>
Secure & Confidential
</Title>
<Paragraph className={styles.featureDescription}>
Your information is protected with enterprise-grade security and
strict confidentiality protocols.
</Paragraph>
</motion.div>
</div>
</div>
</section>
<Footer />
</main>
);
}

View File

@@ -1,35 +1,21 @@
:root { :root {
--background: #ffffff; /* Color Palette */
--foreground: #171717; --french-violet: #7400b8;
--primary: linear-gradient(135deg, #6e48aa 0%, #9d50bb 100%); --grape: #6930c3;
--secondary: linear-gradient(135deg, #00c1d4 0%, #ff5f6d 100%); --slate-blue: #5e60ce;
--primary-glow: radial-gradient( --sky-blue: #56cfe1;
circle, --aquamarine: #80ffdb;
rgba(152, 71, 232, 0.2) 0%,
rgba(71, 1, 90, 0.1) 50%,
rgba(0, 0, 0, 0) 70%
);
}
@media (prefers-color-scheme: dark) { /* Gradients */
:root { --primary-gradient: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
--background: #0a0a0a; --secondary-gradient: linear-gradient(135deg, #6930c3 0%, #5e60ce 100%);
--foreground: #ededed; --accent-gradient: linear-gradient(135deg, #56cfe1 0%, #80ffdb 100%);
} --text-gradient: linear-gradient(135deg, #7400b8 0%, #5e60ce 100%);
}
html, /* Shadows */
body { --primary-shadow: 0 4px 12px rgba(116, 0, 184, 0.15);
max-width: 100vw; --primary-shadow-hover: 0 8px 25px rgba(116, 0, 184, 0.25);
overflow-x: hidden; --secondary-shadow: 0 2px 8px rgba(94, 96, 206, 0.1);
}
body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} }
* { * {
@@ -38,56 +24,343 @@ body {
margin: 0; margin: 0;
} }
html,
body {
max-width: 100vw;
overflow-x: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a { a {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
@media (prefers-color-scheme: dark) { /* Custom scrollbar */
html { ::-webkit-scrollbar {
color-scheme: dark; width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: var(--primary-gradient);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--secondary-gradient);
}
/* Selection styles */
::selection {
background: rgba(116, 0, 184, 0.2);
color: #7400b8;
}
/* Focus styles */
*:focus {
outline: 2px solid #7400b8;
outline-offset: 2px;
}
/* Button hover effects */
.btn-primary {
background: var(--primary-gradient);
border: none;
color: white;
padding: 12px 24px;
border-radius: 8px;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: var(--primary-shadow);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: var(--primary-shadow-hover);
}
/* Text gradients */
.text-gradient {
background: var(--text-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Card styles */
.card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px rgba(116, 0, 184, 0.1);
}
/* Animation classes */
.fade-in {
animation: fadeIn 0.6s ease-in-out;
}
.slide-up {
animation: slideUp 0.6s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
} }
} }
canvas { @keyframes slideUp {
display: block; from {
vertical-align: bottom; opacity: 0;
} /* ---- particles.js container ---- */ transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Utility classes */
.gradient-bg {
background: var(--primary-gradient);
}
.gradient-text {
background: var(--text-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.shadow-primary {
box-shadow: var(--primary-shadow);
}
.shadow-primary-hover:hover {
box-shadow: var(--primary-shadow-hover);
}
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
/* Color Palette */
--french-violet: #7400b8;
--grape: #6930c3;
--slate-blue: #5e60ce;
--sky-blue: #56cfe1;
--aquamarine: #80ffdb;
/* Gradients */
--primary-gradient: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
--secondary-gradient: linear-gradient(135deg, #6930c3 0%, #5e60ce 100%);
--accent-gradient: linear-gradient(135deg, #56cfe1 0%, #80ffdb 100%);
--text-gradient: linear-gradient(135deg, #7400b8 0%, #5e60ce 100%);
/* Shadows */
--primary-shadow: 0 4px 12px rgba(116, 0, 184, 0.15);
--primary-shadow-hover: 0 8px 25px rgba(116, 0, 184, 0.25);
--secondary-shadow: 0 2px 8px rgba(94, 96, 206, 0.1);
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a {
color: inherit;
text-decoration: none;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: var(--primary-gradient);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--secondary-gradient);
}
/* Particles.js Styles */
#particles-js { #particles-js {
position: absolute; position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: linear-gradient(135deg, #6e48aa 0%, #9d50bb 100%); z-index: 1;
background: transparent;
} }
.count-particles { .count-particles {
background: #000022;
position: absolute; position: absolute;
top: 48px; top: 0;
left: 0; left: 0;
width: 80px; width: 100%;
color: #13e8e9; height: 100%;
font-size: 0.8em;
text-align: left;
text-indent: 4px;
line-height: 14px;
padding-bottom: 2px;
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
}
.js-count-particles {
font-size: 1.1em;
}
#stats,
.count-particles {
-webkit-user-select: none;
margin-top: 5px;
margin-left: 5px;
}
#stats {
border-radius: 3px 3px 0 0;
overflow: hidden; overflow: hidden;
z-index: 0;
opacity: 0;
pointer-events: none;
} }
.count-particles {
border-radius: 0 0 3px 3px; /* Selection styles */
::selection {
background: rgba(116, 0, 184, 0.2);
color: #7400b8;
}
/* Focus styles */
*:focus {
outline: 2px solid #7400b8;
outline-offset: 2px;
}
/* Button hover effects */
.btn-primary {
background: var(--primary-gradient);
border: none;
color: white;
padding: 12px 24px;
border-radius: 8px;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: var(--primary-shadow);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: var(--primary-shadow-hover);
}
/* Text gradients */
.text-gradient {
background: var(--text-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Card styles */
.card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px rgba(116, 0, 184, 0.1);
}
/* Animation classes */
.fade-in {
animation: fadeIn 0.6s ease-in-out;
}
.slide-up {
animation: slideUp 0.6s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Utility classes */
.gradient-bg {
background: var(--primary-gradient);
}
.gradient-text {
background: var(--text-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.shadow-primary {
box-shadow: var(--primary-shadow);
}
.shadow-primary-hover:hover {
box-shadow: var(--primary-shadow-hover);
} }

View File

@@ -7,15 +7,91 @@ import "./globals.css";
import { themeConfig } from "./theme/themeConfig"; import { themeConfig } from "./theme/themeConfig";
// Modern font (Inter + Orbitron backup) // Modern font (Inter + Orbitron backup)
const inter = Inter({ subsets: ["latin"] }); const inter = Inter({
const orbitron = { subsets: ["latin"],
className: "font-orbitron", display: "swap",
style: fallback: ["system-ui", "arial"],
"@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');", adjustFontFallback: true,
}; preload: true,
variable: "--font-inter",
});
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Tech Master | Dubai To Stars", title: "Tech Master | Dubai To Stars - Award-Winning IT Solutions",
description:
"Tech Master is an award-winning Dubai-based technology agency specializing in digital transformation, web development, mobile apps, AI solutions, and enterprise software. From zero to hero, we create cutting-edge digital experiences for ambitious businesses.",
keywords: [
"Dubai IT solutions",
"digital transformation",
"web development Dubai",
"mobile app development",
"AI solutions",
"enterprise software",
"ERP systems",
"e-commerce development",
"financial solutions",
"legal software",
"business intelligence",
"cloud migration",
"cybersecurity",
"blockchain development",
"IoT solutions",
"tech agency Dubai",
"software development UAE",
],
authors: [{ name: "Tech Master" }],
creator: "Tech Master",
publisher: "Tech Master",
formatDetection: {
email: false,
address: false,
telephone: false,
},
metadataBase: new URL("https://tech-masters.guru"),
alternates: {
canonical: "/",
},
openGraph: {
title: "Tech Master | Dubai To Stars - Award-Winning IT Solutions",
description:
"Award-winning Dubai-based technology agency specializing in digital transformation, web development, mobile apps, AI solutions, and enterprise software.",
url: "https://tech-masters.guru",
siteName: "Tech Master",
images: [
{
url: "https://tech-masters.guru/og-image.jpg",
width: 1200,
height: 630,
alt: "Tech Master - Dubai To Stars",
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Tech Master | Dubai To Stars - Award-Winning IT Solutions",
description:
"Award-winning Dubai-based technology agency specializing in digital transformation and innovative IT solutions.",
images: ["https://tech-masters.guru/twitter-image.jpg"],
creator: "@techmasterdubai",
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
verification: {
google: "your-google-verification-code",
yandex: "your-yandex-verification-code",
yahoo: "your-yahoo-verification-code",
},
}; };
export default function RootLayout({ export default function RootLayout({
@@ -24,19 +100,48 @@ export default function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
return ( return (
<html lang="en"> <html lang="en" className={`${inter.variable} font-sans`}>
<head> <head>
{/* ThreeJS CDN */} {/* ThreeJS CDN */}
<script <script
src="http://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js" src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"
async async
></script> ></script>
<script <script
src="http://threejs.org/examples/js/libs/stats.min.js" src="https://threejs.org/examples/js/libs/stats.min.js"
async async
></script> ></script>
{/* Orbitron Font */}
<style>{orbitron.style}</style> {/* Structured Data */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "Organization",
name: "Tech Master",
url: "https://tech-masters.guru",
logo: "https://tech-masters.guru/logo.png",
description:
"Award-winning Dubai-based technology agency specializing in digital transformation and innovative IT solutions.",
address: {
"@type": "PostalAddress",
addressLocality: "Dubai",
addressCountry: "UAE",
},
contactPoint: {
"@type": "ContactPoint",
telephone: "+971-XX-XXX-XXXX",
contactType: "customer service",
},
sameAs: [
"https://linkedin.com/company/tech-master",
"https://twitter.com/techmasterdubai",
"https://facebook.com/techmasterdubai",
],
}),
}}
/>
</head> </head>
<body <body
className={`${inter.className} bg-gradient-to-br from-[#0F0525] to-[#2A0B45]`} className={`${inter.className} bg-gradient-to-br from-[#0F0525] to-[#2A0B45]`}

View File

@@ -6,27 +6,470 @@
background-color: #fafafa; background-color: #fafafa;
} }
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
position: relative;
}
.sectionHeader {
text-align: center;
margin-bottom: 60px;
}
.sectionTitle {
font-size: 2.5rem !important;
font-weight: 700 !important;
margin-bottom: 16px !important;
background: linear-gradient(135deg, #7400b8 0%, #5e60ce 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
}
.sectionTitle::after {
content: "";
position: absolute;
bottom: -8px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 4px;
background: linear-gradient(90deg, #7400b8, #6930c3);
border-radius: 2px;
}
.sectionSubtitle {
font-size: 1.1rem !important;
color: #666 !important;
max-width: 600px;
margin: 0 auto !important;
line-height: 1.6 !important;
}
/* Services Section */
.servicesSection {
padding: 100px 0;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
position: relative;
overflow: hidden;
}
.servicesSection::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M 20 0 L 0 0 0 20" fill="none" stroke="%23e2e8f0" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
}
.servicesGrid {
position: relative;
z-index: 1;
}
.serviceCard {
height: 100%;
border-radius: 16px !important;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
border: none !important;
background: white;
position: relative;
}
.serviceCard::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #7400b8, #6930c3);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.serviceCard:hover::before {
transform: scaleX(1);
}
.serviceCard:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(116, 0, 184, 0.15);
}
.serviceIcon {
width: 60px;
height: 60px;
border-radius: 16px;
background: linear-gradient(135deg, #7400b8 0%, #6930c3 100%);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
font-size: 24px;
color: white;
transition: all 0.3s ease;
}
.serviceCard:hover .serviceIcon {
transform: scale(1.1) rotate(5deg);
box-shadow: 0 8px 20px rgba(116, 0, 184, 0.3);
}
.serviceTitle {
font-size: 1.4rem !important;
font-weight: 600 !important;
margin-bottom: 12px !important;
color: #333 !important;
}
.serviceDescription {
color: #666 !important;
line-height: 1.6 !important;
margin-bottom: 20px !important;
}
.serviceFeatures {
list-style: none;
padding: 0;
margin: 0;
}
.serviceFeatures li {
position: relative;
padding: 8px 0 8px 20px;
color: #555;
font-size: 0.95rem;
}
.serviceFeatures li::before {
content: "✓";
position: absolute;
left: 0;
top: 8px;
color: #7400b8;
font-weight: bold;
font-size: 12px;
}
/* Statistics Section */
.statisticsSection {
padding: 100px 0;
background: linear-gradient(135deg, #7400b8 0%, #5e60ce 100%);
position: relative;
overflow: hidden;
color: white;
}
.statisticsSection::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="white" opacity="0.1"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
opacity: 0.3;
}
.statisticsSection .sectionTitle {
color: white !important;
-webkit-text-fill-color: white !important;
background: none !important;
}
.statisticsSection .sectionSubtitle {
color: rgba(255, 255, 255, 0.8) !important;
}
.statsGrid {
position: relative;
z-index: 1;
}
.statCard {
text-align: center;
padding: 30px 20px;
border-radius: 16px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
transition: all 0.3s ease;
}
.statCard:hover {
transform: translateY(-5px);
background: rgba(255, 255, 255, 0.15);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.statIcon {
width: 50px;
height: 50px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16px;
font-size: 20px;
color: white;
transition: all 0.3s ease;
}
.statCard:hover .statIcon {
transform: scale(1.1);
background: rgba(255, 255, 255, 0.3);
}
.statistic {
color: white !important;
}
.statistic :global(.ant-statistic-title) {
color: rgba(255, 255, 255, 0.8) !important;
font-size: 0.9rem !important;
margin-bottom: 8px !important;
}
.statistic :global(.ant-statistic-content) {
color: white !important;
}
.statistic :global(.ant-statistic-content-value) {
color: white !important;
font-size: 2.5rem !important;
font-weight: 700 !important;
}
.statistic :global(.ant-statistic-content-suffix) {
color: rgba(255, 255, 255, 0.8) !important;
font-size: 1.5rem !important;
}
.loaderContainer { .loaderContainer {
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
display: flex; display: flex;
flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: linear-gradient(135deg, #42475C 0%, #20222F 100%); background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
position: relative;
overflow: hidden;
}
.loaderBackground {
position: absolute;
inset: 0;
overflow: hidden;
}
.loaderOrb1 {
position: absolute;
top: -200px;
left: -200px;
width: 400px;
height: 400px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(60px);
animation: float 8s ease-in-out infinite;
opacity: 0.3;
}
.loaderOrb2 {
position: absolute;
top: 50%;
right: -150px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(50px);
animation: float 6s ease-in-out infinite reverse;
opacity: 0.2;
}
.loaderOrb3 {
position: absolute;
bottom: -100px;
left: 50%;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #ec4899 0%, #f97316 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 10s ease-in-out infinite;
opacity: 0.25;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-30px) rotate(180deg);
}
}
.loaderContent {
position: relative;
z-index: 10;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
}
.logoContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.logoIcon {
width: 80px;
height: 80px;
border-radius: 20px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
display: flex;
align-items: center;
justify-content: center;
position: relative;
animation: logoPulse 2s ease-in-out infinite;
}
.logoInner {
width: 40px;
height: 40px;
border-radius: 10px;
background: white;
animation: logoRotate 3s linear infinite;
}
@keyframes logoPulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 30px rgba(139, 92, 246, 0.5);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 50px rgba(139, 92, 246, 0.8);
}
}
@keyframes logoRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.logoText {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.logoTitle {
font-size: 2rem;
font-weight: 700;
color: white;
letter-spacing: 2px;
}
.logoSubtitle {
font-size: 1.2rem;
font-weight: 500;
color: #a855f7;
letter-spacing: 1px;
}
.loaderAnimation {
display: flex;
justify-content: center;
align-items: center;
}
.loaderDots {
display: flex;
gap: 8px;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
animation: dotBounce 1.4s ease-in-out infinite both;
}
.dot:nth-child(1) {
animation-delay: -0.32s;
}
.dot:nth-child(2) {
animation-delay: -0.16s;
}
.dot:nth-child(3) {
animation-delay: 0s;
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: scale(0.8);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
} }
.loaderText { .loaderText {
margin-top: 20px; display: flex;
color: white; flex-direction: column;
opacity: 0.8; align-items: center;
animation: pulse 2s infinite; gap: 8px;
} }
@keyframes pulse { .loaderTitle {
0% { opacity: 0.6; } color: white !important;
50% { opacity: 1; } font-size: 1.5rem !important;
100% { opacity: 0.6; } font-weight: 600 !important;
margin: 0 !important;
animation: textFade 2s ease-in-out infinite;
}
.loaderSubtitle {
color: #cbd5e1;
font-size: 0.95rem;
margin: 0;
opacity: 0.8;
animation: textFade 2s ease-in-out infinite 0.5s;
}
@keyframes textFade {
0%, 100% {
opacity: 0.7;
}
50% {
opacity: 1;
}
} }
.section { .section {
@@ -35,8 +478,140 @@
overflow: hidden; overflow: hidden;
} }
/* Enhanced Responsive Design */
@media (max-width: 768px) { @media (max-width: 768px) {
.section { .section {
padding: 60px 16px; padding: 60px 16px;
} }
.servicesSection,
.statisticsSection {
padding: 60px 0;
}
.sectionTitle {
font-size: 2rem !important;
}
.serviceCard {
margin-bottom: 20px;
}
.statCard {
padding: 20px 15px;
margin-bottom: 20px;
}
.statistic :global(.ant-statistic-content-value) {
font-size: 2rem !important;
}
.loaderContent {
gap: 30px;
}
.logoIcon {
width: 70px;
height: 70px;
}
.logoInner {
width: 35px;
height: 35px;
}
.logoTitle {
font-size: 1.8rem;
}
.logoSubtitle {
font-size: 1.1rem;
}
.loaderTitle {
font-size: 1.3rem !important;
}
.loaderSubtitle {
font-size: 0.9rem;
}
.dot {
width: 10px;
height: 10px;
}
}
@media (max-width: 480px) {
.servicesSection,
.statisticsSection {
padding: 40px 0;
}
.sectionTitle {
font-size: 1.8rem !important;
}
.sectionSubtitle {
font-size: 1rem !important;
}
.serviceIcon {
width: 50px;
height: 50px;
font-size: 20px;
}
.serviceTitle {
font-size: 1.2rem !important;
}
.statCard {
padding: 15px 10px;
}
.statIcon {
width: 40px;
height: 40px;
font-size: 16px;
}
.statistic :global(.ant-statistic-content-value) {
font-size: 1.5rem !important;
}
.loaderContent {
gap: 25px;
}
.logoIcon {
width: 60px;
height: 60px;
}
.logoInner {
width: 30px;
height: 30px;
}
.logoTitle {
font-size: 1.6rem;
}
.logoSubtitle {
font-size: 1rem;
}
.loaderTitle {
font-size: 1.2rem !important;
}
.loaderSubtitle {
font-size: 0.85rem;
}
.dot {
width: 8px;
height: 8px;
}
} }

View File

@@ -1,32 +1,42 @@
// File: src/pages/index.tsx // File: src/pages/index.tsx
"use client"; "use client";
import { Spin, Typography } from "antd"; import {
BulbOutlined,
ClockCircleOutlined,
CodeOutlined,
ProjectOutlined,
RocketOutlined,
StarOutlined,
TeamOutlined
} from "@ant-design/icons";
import { Card, Col, Row, Statistic, Typography } from "antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import ContactSection from "./components/Contact/Contact"; import Footer from "./components/Footer/Footer";
import HeroSection from "./components/Hero/HeroSection"; import HeroSection from "./components/Hero/HeroSection";
import PreferencesSelector from "./components/Preferences/Preferences"; import PreferencesSelector from "./components/Preferences/Preferences";
import ProjectsShowcase from "./components/ProjectsShowcase/ProjectsShowcase"; import ProjectsShowcase from "./components/ProjectsShowcase/ProjectsShowcase";
import ServicesSection from "./components/Services/Services";
import TestimonialsSection from "./components/Testimonials/Testimonials"; import TestimonialsSection from "./components/Testimonials/Testimonials";
import styles from "./page.module.css"; import styles from "./page.module.css";
const { Title } = Typography; const { Title, Paragraph } = Typography;
export default function Home() { export default function Home() {
const [showPreferences, setShowPreferences] = useState(true); const [userPreferences, setUserPreferences] = useState<string[]>(() => {
try {
const storedPreferences = localStorage.getItem("userPreferences");
return storedPreferences ? JSON.parse(storedPreferences) : [];
} catch {
return [];
}
});
const [showPreferences, setShowPreferences] = useState(
() => userPreferences.length === 0,
);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [userPreferences, setUserPreferences] = useState<string[]>([]);
useEffect(() => { useEffect(() => {
// Check if preferences already exist in localStorage
const storedPreferences = localStorage.getItem("userPreferences");
if (storedPreferences) {
setUserPreferences(JSON.parse(storedPreferences));
setShowPreferences(false);
}
// Simulate loading of resources // Simulate loading of resources
const timer = setTimeout(() => { const timer = setTimeout(() => {
setLoading(false); setLoading(false);
@@ -46,10 +56,40 @@ export default function Home() {
if (loading) { if (loading) {
return ( return (
<div className={styles.loaderContainer}> <div className={styles.loaderContainer}>
<Spin size="large" /> <div className={styles.loaderBackground}>
<Title level={4} className={styles.loaderText}> <div className={styles.loaderOrb1}></div>
Preparing Tech Master Experience... <div className={styles.loaderOrb2}></div>
</Title> <div className={styles.loaderOrb3}></div>
</div>
<div className={styles.loaderContent}>
<div className={styles.logoContainer}>
<div className={styles.logoIcon}>
<div className={styles.logoInner}></div>
</div>
<div className={styles.logoText}>
<span className={styles.logoTitle}>Tech</span>
<span className={styles.logoSubtitle}>Masters</span>
</div>
</div>
<div className={styles.loaderAnimation}>
<div className={styles.loaderDots}>
<div className={styles.dot}></div>
<div className={styles.dot}></div>
<div className={styles.dot}></div>
</div>
</div>
<div className={styles.loaderText}>
<Title level={4} className={styles.loaderTitle}>
Preparing Your Experience
</Title>
<p className={styles.loaderSubtitle}>
Loading innovative solutions and cutting-edge technology
</p>
</div>
</div>
</div> </div>
); );
} }
@@ -61,12 +101,169 @@ export default function Home() {
)} )}
<main className={styles.main}> <main className={styles.main}>
<HeroSection /> <section id="home">
<ServicesSection userPreferences={userPreferences} /> <HeroSection />
<ProjectsShowcase /> </section>
<TestimonialsSection />
<ContactSection /> {/* Services Section */}
<section id="services" className={styles.servicesSection}>
<div className={styles.container}>
<div className={styles.sectionHeader}>
<Title level={2} className={styles.sectionTitle}>
Our Services
</Title>
<Paragraph className={styles.sectionSubtitle}>
We offer comprehensive solutions to transform your digital presence and drive business growth
</Paragraph>
</div>
<Row gutter={[32, 32]} className={styles.servicesGrid}>
<Col xs={24} sm={12} lg={8}>
<Card className={styles.serviceCard} hoverable>
<div className={styles.serviceIcon}>
<CodeOutlined />
</div>
<Title level={4} className={styles.serviceTitle}>
Web Development
</Title>
<Paragraph className={styles.serviceDescription}>
Custom web applications built with modern technologies and best practices for optimal performance and user experience.
</Paragraph>
<ul className={styles.serviceFeatures}>
<li>Responsive Design</li>
<li>SEO Optimization</li>
<li>Performance Tuning</li>
<li>Security Implementation</li>
</ul>
</Card>
</Col>
<Col xs={24} sm={12} lg={8}>
<Card className={styles.serviceCard} hoverable>
<div className={styles.serviceIcon}>
<RocketOutlined />
</div>
<Title level={4} className={styles.serviceTitle}>
Mobile Development
</Title>
<Paragraph className={styles.serviceDescription}>
Native and cross-platform mobile applications that deliver exceptional user experiences across all devices.
</Paragraph>
<ul className={styles.serviceFeatures}>
<li>iOS & Android Apps</li>
<li>Cross-platform Solutions</li>
<li>App Store Optimization</li>
<li>Push Notifications</li>
</ul>
</Card>
</Col>
<Col xs={24} sm={12} lg={8}>
<Card className={styles.serviceCard} hoverable>
<div className={styles.serviceIcon}>
<BulbOutlined />
</div>
<Title level={4} className={styles.serviceTitle}>
UI/UX Design
</Title>
<Paragraph className={styles.serviceDescription}>
User-centered design solutions that create intuitive, engaging, and conversion-focused digital experiences.
</Paragraph>
<ul className={styles.serviceFeatures}>
<li>User Research</li>
<li>Wireframing & Prototyping</li>
<li>Visual Design</li>
<li>Usability Testing</li>
</ul>
</Card>
</Col>
</Row>
</div>
</section>
{/* Statistics Section */}
<section id="statistics" className={styles.statisticsSection}>
<div className={styles.container}>
<div className={styles.sectionHeader}>
<Title level={2} className={styles.sectionTitle}>
Our Impact
</Title>
<Paragraph className={styles.sectionSubtitle}>
Numbers that speak for themselves - our commitment to excellence in every project
</Paragraph>
</div>
<Row gutter={[48, 32]} className={styles.statsGrid}>
<Col xs={12} sm={6}>
<div className={styles.statCard}>
<div className={styles.statIcon}>
<ProjectOutlined />
</div>
<Statistic
title="Projects Completed"
value={150}
suffix="+"
className={styles.statistic}
/>
</div>
</Col>
<Col xs={12} sm={6}>
<div className={styles.statCard}>
<div className={styles.statIcon}>
<TeamOutlined />
</div>
<Statistic
title="Happy Clients"
value={80}
suffix="+"
className={styles.statistic}
/>
</div>
</Col>
<Col xs={12} sm={6}>
<div className={styles.statCard}>
<div className={styles.statIcon}>
<StarOutlined />
</div>
<Statistic
title="Average Rating"
value={4.9}
suffix="/5"
precision={1}
className={styles.statistic}
/>
</div>
</Col>
<Col xs={12} sm={6}>
<div className={styles.statCard}>
<div className={styles.statIcon}>
<ClockCircleOutlined />
</div>
<Statistic
title="Years Experience"
value={8}
suffix="+"
className={styles.statistic}
/>
</div>
</Col>
</Row>
</div>
</section>
<section id="projects">
<ProjectsShowcase />
</section>
<section id="testimonials">
<TestimonialsSection />
</section>
</main> </main>
<Footer />
</> </>
); );
} }

View File

@@ -0,0 +1,34 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Our Projects | Tech Master - Portfolio of Digital Solutions",
description: "Explore our portfolio of successful projects including ERP systems, e-commerce platforms, payment solutions, legal software, and business intelligence dashboards developed in Dubai.",
keywords: [
"portfolio projects",
"ERP systems Dubai",
"e-commerce development",
"payment platforms",
"legal software",
"business intelligence",
"web applications",
"mobile apps",
"enterprise software",
"fintech solutions"
],
openGraph: {
title: "Our Projects | Tech Master - Portfolio of Digital Solutions",
description: "Portfolio of successful projects including ERP systems, e-commerce platforms, payment solutions, and business intelligence dashboards.",
url: "https://tech-masters.guru/projects",
},
alternates: {
canonical: "/projects",
},
};
export default function ProjectsLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -0,0 +1,408 @@
/* Projects Page Styles */
.main {
padding-top: 80px;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
min-height: 100vh;
}
/* Hero Section */
.heroSection {
position: relative;
padding: 80px 0 60px;
background: linear-gradient(135deg, #0F0525 0%, #1a0b3a 50%, #2A0B45 100%);
color: white;
overflow: hidden;
}
.heroBackground {
position: absolute;
inset: 0;
opacity: 0.1;
}
.heroOrb1 {
position: absolute;
top: -100px;
left: -100px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 6s ease-in-out infinite;
}
.heroOrb2 {
position: absolute;
top: 50px;
right: -150px;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(35px);
animation: float 8s ease-in-out infinite reverse;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
.heroContent {
position: relative;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
text-align: center;
}
.heroTitle {
font-size: 3.5rem;
font-weight: 700;
margin-bottom: 20px;
line-height: 1.2;
color: white;
}
.gradientText {
background: linear-gradient(135deg, #a855f7 0%, #ec4899 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.heroSubtitle {
font-size: 1.25rem;
color: #cbd5e1;
max-width: 600px;
margin: 0 auto 30px;
line-height: 1.6;
}
.projectStats {
display: flex;
justify-content: center;
gap: 40px;
margin-top: 40px;
}
.statItem {
text-align: center;
}
.statNumber {
font-size: 2rem;
font-weight: 700;
color: #a855f7;
display: block;
}
.statLabel {
font-size: 0.9rem;
color: #94a3b8;
margin-top: 4px;
}
/* Projects Section */
.projectsSection {
padding: 80px 0;
position: relative;
}
.projectsBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.05) 0%, rgba(236, 72, 153, 0.05) 100%);
}
.projectsContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
position: relative;
}
.projectsHeader {
text-align: center;
margin-bottom: 60px;
}
.projectsTitle {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 16px;
color: #1e293b;
}
.projectsSubtitle {
font-size: 1.1rem;
color: #64748b;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
/* Filter Section */
.filterSection {
margin-bottom: 40px;
text-align: center;
}
.filterButtons {
display: flex;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.filterButton {
padding: 8px 20px;
border-radius: 25px;
border: 2px solid #e5e7eb;
background: white;
color: #64748b;
font-weight: 500;
transition: all 0.3s ease;
cursor: pointer;
}
.filterButton:hover {
border-color: #8b5cf6;
color: #8b5cf6;
}
.filterButton.active {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-color: transparent;
color: white;
}
/* Projects Grid */
.projectsGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 24px;
margin-bottom: 60px;
}
.projectCard {
background: white;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
cursor: pointer;
border: none;
height: fit-content;
}
.projectCard:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.projectImageContainer {
position: relative;
height: 200px;
overflow: hidden;
}
.projectImage {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.projectCard:hover .projectImage {
transform: scale(1.05);
}
.projectOverlay {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.projectCard:hover .projectOverlay {
opacity: 1;
}
.viewButton {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none;
width: 50px;
height: 50px;
font-size: 18px;
}
.featuredBadge {
position: absolute;
top: 16px;
right: 16px;
z-index: 2;
}
.projectContent {
padding: 20px;
}
.categoryTag {
margin-bottom: 12px;
}
.projectTitle {
font-size: 1.1rem;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
line-height: 1.3;
}
.projectDescription {
color: #64748b;
line-height: 1.5;
margin-bottom: 12px;
font-size: 0.85rem;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.technologiesList {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 12px;
}
.techTag {
background: #f8fafc;
color: #475569;
border: 1px solid #e2e8f0;
font-size: 0.75rem;
padding: 2px 6px;
border-radius: 8px;
}
.projectMeta {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 12px;
border-top: 1px solid #f1f5f9;
font-size: 0.8rem;
}
.projectDuration {
font-size: 0.75rem;
color: #64748b;
}
.projectTeam {
font-size: 0.75rem;
color: #64748b;
}
/* Load More Section */
.loadMoreSection {
text-align: center;
margin-top: 40px;
}
.loadMoreButton {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none;
color: white;
padding: 12px 32px;
border-radius: 25px;
font-weight: 600;
font-size: 1rem;
transition: all 0.3s ease;
}
.loadMoreButton:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(139, 92, 246, 0.3);
background: linear-gradient(135deg, #7c3aed 0%, #db2777 100%);
color: white;
}
/* Responsive Design */
@media (max-width: 1024px) {
.projectsGrid {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.heroTitle {
font-size: 3rem;
}
}
@media (max-width: 768px) {
.main {
padding-top: 60px;
}
.heroSection {
padding: 60px 0 40px;
}
.heroTitle {
font-size: 2.5rem;
}
.heroSubtitle {
font-size: 1.1rem;
}
.projectStats {
flex-direction: column;
gap: 20px;
}
.projectsSection {
padding: 60px 0;
}
.projectsGrid {
grid-template-columns: 1fr;
gap: 16px;
}
.filterButtons {
gap: 8px;
}
.filterButton {
padding: 6px 16px;
font-size: 0.9rem;
}
}
@media (max-width: 480px) {
.heroTitle {
font-size: 2rem;
}
.projectCard {
margin: 0 10px;
}
.projectContent {
padding: 20px;
}
}

640
src/app/projects/page.tsx Normal file
View File

@@ -0,0 +1,640 @@
"use client";
import {
CloseOutlined,
EyeOutlined,
LinkOutlined,
RocketOutlined,
UserOutlined
} from "@ant-design/icons";
import {
Badge,
Button,
Card,
Carousel,
Col,
Modal,
Row,
Tag,
Typography,
} from "antd";
import { AnimatePresence, motion } from "framer-motion";
import Image from "next/image";
import { useState } from "react";
import Footer from "../components/Footer/Footer";
import styles from "./page.module.css";
const { Title, Paragraph, Text } = Typography;
interface Project {
id: string;
title: string;
description: string;
imageUrl: string;
category: string;
technologies: string[];
featured: boolean;
detailedDescription: string;
images: string[];
liveUrl?: string;
githubUrl?: string;
features: string[];
duration: string;
teamSize: string;
}
// Sample project data (same as in ProjectsShowcase)
const projectsData: Project[] = [
{
id: "p1",
title: "BPro ERP System",
description:
"Comprehensive enterprise resource planning system with advanced business process management and real-time analytics.",
imageUrl: "https://tech-masters.guru/photos/projects/bpro-erp.jpg",
category: "Enterprise Software",
technologies: ["React", "Node.js", "PostgreSQL", "Redis"],
featured: true,
detailedDescription:
"A comprehensive ERP system designed for modern businesses, featuring advanced business process management, real-time analytics, and seamless integration with existing enterprise systems. The platform streamlines operations across all departments.",
images: [
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
"https://tech-masters.guru/photos/projects/bpro-erp.jpg",
],
liveUrl: "https://bpro-erp.com",
githubUrl: "https://github.com/company/bpro-erp",
features: [
"Advanced business process management",
"Real-time analytics and reporting",
"Multi-department integration",
"Custom workflow automation",
"Comprehensive audit trails",
],
duration: "8 months",
teamSize: "12 developers",
},
{
id: "p2",
title: "Law Office Management",
description:
"Complete legal practice management solution with case tracking, document management, and client portal.",
imageUrl: "https://tech-masters.guru/photos/projects/law-office-home.png",
category: "Legal Software",
technologies: ["Angular", ".NET Core", "SQL Server", "Azure"],
featured: true,
detailedDescription:
"A comprehensive legal practice management system designed to streamline law office operations, manage cases, track billable hours, and provide secure client communication portals.",
images: [
"https://tech-masters.guru/photos/projects/law-office-home.png",
"https://tech-masters.guru/photos/projects/law-office-login.png",
"https://tech-masters.guru/photos/projects/law-office-home.png",
],
liveUrl: "https://law-office-demo.com",
githubUrl: "https://github.com/company/law-office-system",
features: [
"Case management and tracking",
"Document management system",
"Client portal and communication",
"Time tracking and billing",
"Calendar and appointment management",
],
duration: "6 months",
teamSize: "8 developers",
},
{
id: "p3",
title: "MoneyOut Payment Platform",
description:
"Secure digital payment processing platform with multi-currency support and advanced fraud detection.",
imageUrl: "https://tech-masters.guru/photos/projects/moneyout.png",
category: "FinTech",
technologies: ["Next.js", "Stripe", "MongoDB", "GraphQL"],
featured: true,
detailedDescription:
"A modern payment processing platform that enables secure digital transactions with multi-currency support, advanced fraud detection, and comprehensive merchant tools.",
images: [
"https://tech-masters.guru/photos/projects/moneyout.png",
"https://tech-masters.guru/photos/projects/moneyout.png",
"https://tech-masters.guru/photos/projects/moneyout.png",
],
liveUrl: "https://moneyout-demo.com",
githubUrl: "https://github.com/company/moneyout-platform",
features: [
"Multi-currency payment processing",
"Advanced fraud detection",
"Merchant dashboard and analytics",
"Secure API integration",
"Real-time transaction monitoring",
],
duration: "7 months",
teamSize: "10 developers",
},
{
id: "p4",
title: "Cloths E-commerce Platform",
description:
"Modern fashion e-commerce platform with advanced product catalog, virtual try-on, and personalized recommendations.",
imageUrl: "https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
category: "E-commerce",
technologies: ["React", "Node.js", "MongoDB", "AWS"],
featured: false,
detailedDescription:
"A cutting-edge fashion e-commerce platform featuring virtual try-on technology, personalized recommendations, and seamless mobile shopping experience.",
images: [
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
"https://tech-masters.guru/photos/projects/cloths-e-commerce.png",
],
liveUrl: "https://cloths-ecommerce.com",
githubUrl: "https://github.com/company/cloths-ecommerce",
features: [
"Virtual try-on technology",
"Personalized recommendations",
"Advanced product catalog",
"Mobile-first design",
"Social commerce integration",
],
duration: "5 months",
teamSize: "6 developers",
},
{
id: "p5",
title: "Nanas Dashboard",
description:
"Comprehensive business intelligence dashboard with real-time data visualization and predictive analytics.",
imageUrl:
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
category: "Business Intelligence",
technologies: ["Vue.js", "Python", "PostgreSQL", "Docker"],
featured: false,
detailedDescription:
"A powerful business intelligence dashboard that provides real-time data visualization, predictive analytics, and comprehensive reporting for data-driven decision making.",
images: [
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
"https://tech-masters.guru/photos/projects/nanas-main-dashboard.png",
],
liveUrl: "https://nanas-dashboard.com",
githubUrl: "https://github.com/company/nanas-dashboard",
features: [
"Real-time data visualization",
"Predictive analytics",
"Custom reporting tools",
"Interactive dashboards",
"Data export capabilities",
],
duration: "4 months",
teamSize: "5 developers",
},
{
id: "p6",
title: "Easy Pay Login System",
description:
"Secure authentication system with multi-factor authentication and advanced security features for financial applications.",
imageUrl: "https://tech-masters.guru/photos/projects/easy-pay-login.png",
category: "Security",
technologies: ["React", "Node.js", "JWT", "Redis"],
featured: false,
detailedDescription:
"A robust authentication system designed for financial applications, featuring multi-factor authentication, advanced security protocols, and seamless user experience.",
images: [
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
"https://tech-masters.guru/photos/projects/easy-pay-login.png",
],
liveUrl: "https://easy-pay-login.com",
githubUrl: "https://github.com/company/easy-pay-login",
features: [
"Multi-factor authentication",
"Advanced security protocols",
"Session management",
"Audit logging",
"Password recovery system",
],
duration: "3 months",
teamSize: "4 developers",
},
{
id: "p7",
title: "Majsin Dashboard",
description:
"Advanced analytics dashboard with machine learning insights and customizable reporting for enterprise clients.",
imageUrl: "https://tech-masters.guru/photos/projects/majsin-dashborad.png",
category: "Analytics",
technologies: ["Angular", "Python", "TensorFlow", "AWS"],
featured: false,
detailedDescription:
"An advanced analytics dashboard powered by machine learning, providing deep insights and customizable reporting for enterprise-level decision making.",
images: [
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
"https://tech-masters.guru/photos/projects/majsin-dashborad.png",
],
liveUrl: "https://majsin-dashboard.com",
githubUrl: "https://github.com/company/majsin-dashboard",
features: [
"Machine learning insights",
"Customizable reporting",
"Real-time data processing",
"Advanced visualizations",
"API integration capabilities",
],
duration: "6 months",
teamSize: "7 developers",
},
{
id: "p8",
title: "SVU Hardware Management",
description:
"Comprehensive hardware inventory and management system for educational institutions with asset tracking.",
imageUrl: "https://tech-masters.guru/photos/projects/svu-hw.png",
category: "Education",
technologies: ["React", "Node.js", "MySQL", "Docker"],
featured: false,
detailedDescription:
"A comprehensive hardware management system designed for educational institutions, featuring asset tracking, maintenance scheduling, and detailed reporting capabilities.",
images: [
"https://tech-masters.guru/photos/projects/svu-hw.png",
"https://tech-masters.guru/photos/projects/svu-hw.png",
"https://tech-masters.guru/photos/projects/svu-hw.png",
],
liveUrl: "https://svu-hardware.com",
githubUrl: "https://github.com/company/svu-hardware",
features: [
"Asset tracking and management",
"Maintenance scheduling",
"Inventory control",
"Detailed reporting",
"User access management",
],
duration: "5 months",
teamSize: "6 developers",
},
];
const categories = [
"All",
"Enterprise Software",
"Legal Software",
"FinTech",
"E-commerce",
"Business Intelligence",
"Security",
"Analytics",
"Education",
];
export default function ProjectsPage() {
const [selectedCategory, setSelectedCategory] = useState("All");
const [selectedProject, setSelectedProject] = useState<Project | null>(null);
const [isModalVisible, setIsModalVisible] = useState(false);
const [visibleProjects, setVisibleProjects] = useState(9);
const filteredProjects =
selectedCategory === "All"
? projectsData
: projectsData.filter((project) => project.category === selectedCategory);
const displayedProjects = filteredProjects.slice(0, visibleProjects);
const handleProjectClick = (project: Project) => {
setSelectedProject(project);
setIsModalVisible(true);
};
const handleModalClose = () => {
setIsModalVisible(false);
setTimeout(() => {
setSelectedProject(null);
}, 300);
};
const handleLoadMore = () => {
setVisibleProjects((prev) => Math.min(prev + 6, filteredProjects.length));
};
const handleCategoryClick = (category: string) => {
if (selectedCategory === category) {
// If clicking on the same category, remove the filter
setSelectedCategory("All");
// When showing all projects, show more initially
setVisibleProjects(9);
} else {
// Otherwise, set the new category
setSelectedCategory(category);
// When filtering, show fewer projects initially
setVisibleProjects(6);
}
};
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 },
},
};
return (
<main className={styles.main}>
{/* Hero Section */}
<section className={styles.heroSection}>
<div className={styles.heroBackground}>
<div className={styles.heroOrb1}></div>
<div className={styles.heroOrb2}></div>
</div>
<div className={styles.heroContent}>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<Title level={1} className={styles.heroTitle}>
Our <span className={styles.gradientText}>Projects</span>
</Title>
<Paragraph className={styles.heroSubtitle}>
Explore our portfolio of innovative solutions that have
transformed businesses and delivered exceptional results across
various industries.
</Paragraph>
<div className={styles.projectStats}>
<div className={styles.statItem}>
<span className={styles.statNumber}>50+</span>
<span className={styles.statLabel}>Projects Completed</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>8</span>
<span className={styles.statLabel}>Industries Served</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>100%</span>
<span className={styles.statLabel}>Client Satisfaction</span>
</div>
</div>
</motion.div>
</div>
</section>
{/* Projects Section */}
<section className={styles.projectsSection}>
<div className={styles.projectsBackground}></div>
<div className={styles.projectsContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className={styles.projectsHeader}
>
<Title level={2} className={styles.projectsTitle}>
Featured <span className={styles.gradientText}>Work</span>
</Title>
<Paragraph className={styles.projectsSubtitle}>
Discover our latest projects and see how we&apos;ve helped businesses
achieve their digital transformation goals.
</Paragraph>
</motion.div>
{/* Filter Section */}
<div className={styles.filterSection}>
<div className={styles.filterButtons}>
{categories.map((category) => (
<button
key={category}
className={`${styles.filterButton} ${
selectedCategory === category ? styles.active : ""
}`}
onClick={() => handleCategoryClick(category)}
>
{category}
</button>
))}
</div>
</div>
{/* Projects Grid */}
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.projectsGrid}
>
{displayedProjects.map((project) => (
<motion.div key={project.id} variants={itemVariants}>
<Card
hoverable
onClick={() => handleProjectClick(project)}
className={styles.projectCard}
cover={
<div className={styles.projectImageContainer}>
<Image
alt={project.title}
src={project.imageUrl}
className={styles.projectImage}
width={400}
height={250}
/>
<div className={styles.projectOverlay}>
<Button
type="primary"
shape="circle"
icon={<EyeOutlined />}
className={styles.viewButton}
/>
</div>
{project.featured && (
<Badge.Ribbon
text="Featured"
className={styles.featuredBadge}
/>
)}
</div>
}
>
<div className={styles.projectContent}>
<div className={styles.categoryTag}>
<Tag color="blue">{project.category}</Tag>
</div>
<Title level={4} className={styles.projectTitle}>
{project.title}
</Title>
<Paragraph className={styles.projectDescription}>
{project.description}
</Paragraph>
<div className={styles.technologiesList}>
{project.technologies.slice(0, 4).map((tech) => (
<Tag key={tech} className={styles.techTag}>
{tech}
</Tag>
))}
{project.technologies.length > 4 && (
<Tag className={styles.techTag}>
+{project.technologies.length - 4} more
</Tag>
)}
</div>
<div className={styles.projectMeta}>
<div className={styles.projectDuration}>
<RocketOutlined /> {project.duration}
</div>
<div className={styles.projectTeam}>
<UserOutlined /> {project.teamSize}
</div>
</div>
</div>
</Card>
</motion.div>
))}
</motion.div>
{/* Load More Section */}
{visibleProjects < filteredProjects.length && (
<div className={styles.loadMoreSection}>
<Button
type="primary"
size="large"
onClick={handleLoadMore}
className={styles.loadMoreButton}
>
Load More Projects
</Button>
</div>
)}
</div>
</section>
{/* Project Details Modal */}
<AnimatePresence>
{isModalVisible && selectedProject && (
<Modal
open={isModalVisible}
onCancel={handleModalClose}
footer={null}
width={1000}
className={styles.projectModal}
closeIcon={<CloseOutlined />}
>
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.3 }}
>
<div style={{ padding: "20px 0" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "flex-start",
marginBottom: "24px",
}}
>
<div>
<Title level={2} style={{ marginBottom: "8px" }}>
{selectedProject.title}
</Title>
<Tag color="blue">{selectedProject.category}</Tag>
</div>
<div style={{ display: "flex", gap: "12px" }}>
{selectedProject.liveUrl && (
<Button
type="primary"
icon={<LinkOutlined />}
href={selectedProject.liveUrl}
target="_blank"
>
Live Demo
</Button>
)}
{/* {selectedProject.githubUrl && (
<Button
icon={<GithubOutlined />}
href={selectedProject.githubUrl}
target="_blank"
>
View Code
</Button>
)} */}
</div>
</div>
<div style={{ marginBottom: "24px" }}>
<Carousel autoplay dots={{ className: "custom-dots" }}>
{selectedProject.images.map((image, index) => (
<div key={index}>
<Image
src={image}
alt={`${selectedProject.title} - Image ${index + 1}`}
width={800}
height={400}
style={{
width: "100%",
height: "auto",
borderRadius: "8px",
}}
/>
</div>
))}
</Carousel>
</div>
<Row gutter={[24, 24]}>
<Col xs={24} md={12}>
<Title level={4}>Project Overview</Title>
<Paragraph>{selectedProject.detailedDescription}</Paragraph>
<Title level={4} style={{ marginTop: "24px" }}>
Key Features
</Title>
<ul>
{selectedProject.features.map((feature, index) => (
<li key={index} style={{ marginBottom: "8px" }}>
{feature}
</li>
))}
</ul>
</Col>
<Col xs={24} md={12}>
<Title level={4}>Project Details</Title>
<div style={{ marginBottom: "16px" }}>
<Text strong>Duration:</Text> {selectedProject.duration}
</div>
<div style={{ marginBottom: "16px" }}>
<Text strong>Team Size:</Text> {selectedProject.teamSize}
</div>
<div style={{ marginBottom: "16px" }}>
<Text strong>Technologies:</Text>
<div style={{ marginTop: "8px" }}>
{selectedProject.technologies.map((tech) => (
<Tag key={tech} style={{ marginBottom: "4px" }}>
{tech}
</Tag>
))}
</div>
</div>
</Col>
</Row>
</div>
</motion.div>
</Modal>
)}
</AnimatePresence>
<Footer />
</main>
);
}

12
src/app/robots.ts Normal file
View File

@@ -0,0 +1,12 @@
import { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: '/private/',
},
sitemap: 'https://tech-masters.guru/sitemap.xml',
}
}

View File

@@ -0,0 +1,35 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Our Services | Tech Master - Digital Transformation & IT Solutions",
description:
"Explore our comprehensive IT services including web development, mobile apps, AI solutions, ERP systems, e-commerce platforms, and digital transformation services in Dubai.",
keywords: [
"web development Dubai",
"mobile app development",
"AI solutions",
"ERP systems",
"e-commerce development",
"digital transformation",
"cloud migration",
"cybersecurity services",
"IT consulting Dubai",
],
openGraph: {
title: "Our Services | Tech Master - Digital Transformation & IT Solutions",
description:
"Comprehensive IT services including web development, mobile apps, AI solutions, ERP systems, and digital transformation in Dubai.",
url: "https://tech-masters.guru/services",
},
alternates: {
canonical: "/services",
},
};
export default function ServicesLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -0,0 +1,723 @@
/* Services Page Enhanced Styles */
.main {
padding-top: 80px;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
min-height: 100vh;
}
/* Hero Section */
.heroSection {
position: relative;
padding: 80px 0 60px;
background: linear-gradient(135deg, #0f0525 0%, #1a0b3a 50%, #2a0b45 100%);
color: white;
overflow: hidden;
}
.heroBackground {
position: absolute;
inset: 0;
opacity: 0.1;
}
.heroOrb1 {
position: absolute;
top: -100px;
left: -100px;
width: 300px;
height: 300px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border-radius: 50%;
filter: blur(40px);
animation: float 6s ease-in-out infinite;
}
.heroOrb2 {
position: absolute;
top: 50px;
right: -150px;
width: 250px;
height: 250px;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
border-radius: 50%;
filter: blur(35px);
animation: float 8s ease-in-out infinite reverse;
}
@keyframes float {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
.heroContent {
position: relative;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
text-align: center;
}
.heroTitle {
font-size: 3.5rem;
font-weight: 700;
margin-bottom: 20px;
line-height: 1.2;
color: white;
}
.gradientText {
background: linear-gradient(135deg, #a855f7 0%, #ec4899 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.heroSubtitle {
font-size: 1.25rem;
color: #cbd5e1;
max-width: 600px;
margin: 0 auto 30px;
line-height: 1.6;
}
.serviceStats {
display: flex;
justify-content: center;
gap: 40px;
margin-top: 40px;
}
.statItem {
text-align: center;
}
.statNumber {
font-size: 2rem;
font-weight: 700;
color: #a855f7;
display: block;
}
.statLabel {
font-size: 0.9rem;
color: #94a3b8;
margin-top: 4px;
}
/* Hero Footer */
.heroFooter {
margin-top: 60px;
padding-top: 40px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.heroFooterContent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 40px;
margin-bottom: 30px;
}
.footerColumn {
text-align: left;
}
.footerColumnTitle {
font-size: 1.1rem;
font-weight: 600;
color: white;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.footerColumnIcon {
color: #a855f7;
font-size: 1.2rem;
}
.footerLinks {
list-style: none;
padding: 0;
margin: 0;
}
.footerLink {
margin-bottom: 8px;
}
.footerLink a {
color: #cbd5e1;
text-decoration: none;
font-size: 0.9rem;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 6px;
}
.footerLink a:hover {
color: #a855f7;
transform: translateX(4px);
}
.footerLinkIcon {
font-size: 0.8rem;
transition: all 0.3s ease;
}
.footerBottom {
text-align: center;
padding-top: 30px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.footerBottomText {
color: #94a3b8;
font-size: 0.9rem;
margin-bottom: 20px;
}
.socialLinks {
display: flex;
justify-content: center;
gap: 20px;
margin-bottom: 20px;
}
.socialLink {
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
color: white;
text-decoration: none;
transition: all 0.3s ease;
backdrop-filter: blur(8px);
}
.socialLink:hover {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
transform: translateY(-2px);
color: white;
}
.copyright {
color: #64748b;
font-size: 0.8rem;
}
/* Services Section */
.servicesSection {
padding: 80px 0;
position: relative;
}
.servicesBackground {
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(139, 92, 246, 0.05) 0%,
rgba(236, 72, 153, 0.05) 100%
);
}
.servicesContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
position: relative;
}
.servicesHeader {
text-align: center;
margin-bottom: 60px;
}
.servicesTitle {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 16px;
color: #1e293b;
}
.servicesSubtitle {
font-size: 1.1rem;
color: #64748b;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.servicesGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 30px;
margin-bottom: 60px;
}
/* Service Cards */
.serviceCard {
background: white;
border-radius: 24px;
padding: 0;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
border: none;
height: 100%;
}
.serviceCard::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.serviceCard:hover::before {
transform: scaleX(1);
}
.serviceCard:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(139, 92, 246, 0.15);
}
.cardHeader {
padding: 32px 32px 24px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
position: relative;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.serviceIconWrapper {
width: 70px;
height: 70px;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
position: relative;
z-index: 1;
}
.serviceCard:hover .serviceIconWrapper {
transform: scale(1.1) rotate(5deg);
}
.serviceBadge {
background: rgba(139, 92, 246, 0.1);
color: #8b5cf6;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
border: 1px solid rgba(139, 92, 246, 0.2);
}
.serviceIcon {
font-size: 32px;
color: white;
}
/* Service Icon Colors */
.iconWebDev {
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
}
.iconBranding {
background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
}
.iconEcommerce {
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
.iconSEO {
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
}
.iconMobile {
background: linear-gradient(135deg, #ec4899 0%, #db2777 100%);
}
.iconCloud {
background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);
}
.iconAI {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
}
.iconConsulting {
background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
}
.cardContent {
padding: 0 32px 32px;
}
.serviceTitle {
font-size: 1.4rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 12px;
line-height: 1.3;
}
.serviceDescription {
color: #64748b;
line-height: 1.6;
margin-bottom: 24px;
font-size: 0.95rem;
}
.featuresContainer {
margin-bottom: 24px;
}
.featuresTitle {
font-size: 0.9rem;
font-weight: 600;
color: #475569;
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.serviceFeatures {
list-style: none;
padding: 0;
margin: 0;
}
.serviceFeature {
display: flex;
align-items: center;
gap: 10px;
color: #64748b;
font-size: 0.9rem;
margin-bottom: 10px;
padding: 8px 0;
}
.featureIcon {
color: #8b5cf6;
font-size: 0.8rem;
font-weight: bold;
}
.cardFooter {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid #f1f5f9;
}
.learnMoreBtn {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none;
color: white;
padding: 10px 20px;
border-radius: 20px;
font-weight: 600;
font-size: 0.9rem;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 6px;
height: auto;
}
.learnMoreBtn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(139, 92, 246, 0.3);
background: linear-gradient(135deg, #7c3aed 0%, #db2777 100%);
color: white;
}
/* Process Section */
.processSection {
padding: 80px 0;
background: white;
position: relative;
}
.processBackground {
position: absolute;
inset: 0;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}
.processContainer {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
position: relative;
}
.processHeader {
text-align: center;
margin-bottom: 60px;
}
.processTitle {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 16px;
color: #1e293b;
}
.processSubtitle {
font-size: 1.1rem;
color: #64748b;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.processSteps {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-top: 40px;
}
.processStep {
text-align: center;
padding: 30px 20px;
background: white;
border-radius: 16px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
position: relative;
}
.processStep:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
}
.stepNumber {
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
font-size: 1.5rem;
font-weight: 700;
color: white;
}
.stepTitle {
font-size: 1.25rem;
font-weight: 600;
color: #1e293b;
margin-bottom: 12px;
}
.stepDescription {
color: #64748b;
line-height: 1.6;
font-size: 0.9rem;
}
/* CTA Section */
.ctaSection {
padding: 80px 0;
background: linear-gradient(135deg, #0f0525 0%, #1a0b3a 50%, #2a0b45 100%);
color: white;
text-align: center;
}
.ctaContainer {
max-width: 800px;
margin: 0 auto;
padding: 0 20px;
}
.ctaTitle {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 20px;
color: white;
}
.ctaSubtitle {
font-size: 1.1rem;
color: #cbd5e1;
margin-bottom: 40px;
line-height: 1.6;
}
.ctaButton {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
border: none;
color: white;
padding: 16px 32px;
border-radius: 30px;
font-weight: 600;
font-size: 1.1rem;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.ctaButton:hover {
transform: translateY(-2px);
box-shadow: 0 12px 35px rgba(139, 92, 246, 0.4);
background: linear-gradient(135deg, #7c3aed 0%, #db2777 100%);
color: white;
}
/* Responsive Design */
@media (max-width: 1024px) {
.servicesGrid {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 25px;
}
.heroTitle {
font-size: 3rem;
}
.processSteps {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
}
@media (max-width: 768px) {
.main {
padding-top: 60px;
}
.heroSection {
padding: 60px 0 40px;
}
.heroTitle {
font-size: 2.5rem;
}
.heroSubtitle {
font-size: 1.1rem;
}
.serviceStats {
flex-direction: column;
gap: 20px;
}
.heroFooterContent {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 30px;
}
.footerColumn {
text-align: center;
}
.socialLinks {
gap: 15px;
}
.servicesSection {
padding: 60px 0;
}
.servicesGrid {
grid-template-columns: 1fr;
gap: 20px;
}
.serviceCard {
margin: 0 10px;
}
.cardHeader {
padding: 24px 20px 20px;
}
.cardContent {
padding: 0 20px 24px;
}
.cardFooter {
flex-direction: column;
gap: 16px;
align-items: stretch;
}
.serviceStats {
text-align: center;
flex-direction: row;
justify-content: center;
gap: 20px;
}
.processSteps {
grid-template-columns: 1fr;
gap: 20px;
}
.ctaTitle {
font-size: 2rem;
}
}
@media (max-width: 480px) {
.heroTitle {
font-size: 2rem;
}
.serviceCard {
margin: 0 5px;
}
.cardHeader {
padding: 20px 16px 16px;
}
.cardContent {
padding: 0 16px 20px;
}
.serviceIconWrapper {
width: 60px;
height: 60px;
}
.serviceIcon {
font-size: 24px;
}
.servicesTitle,
.processTitle {
font-size: 2rem;
}
}

382
src/app/services/page.tsx Normal file
View File

@@ -0,0 +1,382 @@
"use client";
import {
ArrowRightOutlined,
CloudOutlined,
CodeOutlined,
GlobalOutlined,
LineChartOutlined,
MobileOutlined,
RobotOutlined,
RocketOutlined,
ShoppingOutlined,
} from "@ant-design/icons";
import { Button, Typography } from "antd";
import { motion } from "framer-motion";
import React from "react";
import Footer from "../components/Footer/Footer";
import styles from "./page.module.css";
const { Title, Paragraph } = Typography;
interface Service {
id: string;
title: string;
description: string;
icon: React.ReactNode;
iconClass: string;
features: string[];
preferenceMatches: string[];
}
const allServices: Service[] = [
{
id: "webdev",
title: "Web Development",
description:
"Custom web applications with cutting-edge technologies and responsive design.",
icon: <CodeOutlined />,
iconClass: styles.iconWebDev,
features: [
"React & Next.js",
"Node.js Backend",
"Responsive Design",
"Performance Optimization",
],
preferenceMatches: ["ecommerce", "cloud", "seo"],
},
{
id: "branding",
title: "Branding & Identity",
description:
"Complete brand identity packages including logos, guidelines, and visual systems.",
icon: <RocketOutlined />,
iconClass: styles.iconBranding,
features: [
"Logo Design",
"Brand Guidelines",
"Visual Identity",
"Marketing Materials",
],
preferenceMatches: ["branding", "seo"],
},
{
id: "ecom",
title: "E-commerce Solutions",
description:
"Full-stack e-commerce platforms with secure payment integration and inventory management.",
icon: <ShoppingOutlined />,
iconClass: styles.iconEcommerce,
features: [
"Payment Integration",
"Inventory Management",
"Order Processing",
"Analytics Dashboard",
],
preferenceMatches: ["ecommerce", "branding"],
},
{
id: "seo",
title: "SEO & Marketing",
description:
"Data-driven digital marketing strategies to improve visibility and drive conversions.",
icon: <LineChartOutlined />,
iconClass: styles.iconSEO,
features: [
"Keyword Research",
"Content Strategy",
"Technical SEO",
"Performance Tracking",
],
preferenceMatches: ["seo", "branding"],
},
{
id: "mobile",
title: "Mobile Development",
description:
"Native and cross-platform mobile applications for iOS and Android.",
icon: <MobileOutlined />,
iconClass: styles.iconMobile,
features: [
"iOS Development",
"Android Development",
"Cross-platform",
"App Store Optimization",
],
preferenceMatches: ["mobile", "ai"],
},
{
id: "cloud",
title: "Cloud Solutions",
description:
"Scalable cloud infrastructures, migrations, and DevOps automation.",
icon: <CloudOutlined />,
iconClass: styles.iconCloud,
features: [
"AWS/Azure/GCP",
"Infrastructure Setup",
"DevOps Automation",
"Scalability",
],
preferenceMatches: ["cloud", "ai"],
},
{
id: "ai",
title: "AI & Machine Learning",
description:
"Custom AI solutions for automation, prediction, and data analysis.",
icon: <RobotOutlined />,
iconClass: styles.iconAI,
features: [
"Custom AI Models",
"Data Analysis",
"Process Automation",
"Predictive Analytics",
],
preferenceMatches: ["ai", "cloud"],
},
{
id: "consulting",
title: "Global IT Consulting",
description:
"Strategic technology consulting to drive digital transformation and innovation.",
icon: <GlobalOutlined />,
iconClass: styles.iconConsulting,
features: [
"Technology Strategy",
"Digital Transformation",
"Project Management",
"Team Training",
],
preferenceMatches: ["cloud", "branding", "seo"],
},
];
const processSteps = [
{
number: "01",
title: "Discovery & Planning",
description:
"We analyze your requirements and create a comprehensive project plan tailored to your goals.",
},
{
number: "02",
title: "Design & Development",
description:
"Our expert team builds your solution using the latest technologies and best practices.",
},
{
number: "03",
title: "Testing & Quality",
description:
"Rigorous testing ensures your solution is robust, secure, and performs flawlessly.",
},
{
number: "04",
title: "Launch & Support",
description:
"We deploy your solution and provide ongoing support to ensure continued success.",
},
];
export default function ServicesPage() {
const services = allServices;
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { y: 50, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.5 },
},
};
return (
<main className={styles.main}>
{/* Hero Section */}
<section className={styles.heroSection}>
<div className={styles.heroBackground}>
<div className={styles.heroOrb1}></div>
<div className={styles.heroOrb2}></div>
</div>
<div className={styles.heroContent}>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<Title level={1} className={styles.heroTitle}>
Our <span className={styles.gradientText}>Services</span>
</Title>
<Paragraph className={styles.heroSubtitle}>
Innovative technology solutions customized for your business
needs. From web development to AI solutions, we deliver excellence
in every project.
</Paragraph>
<div className={styles.serviceStats}>
<div className={styles.statItem}>
<span className={styles.statNumber}>50+</span>
<span className={styles.statLabel}>Projects Completed</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>8</span>
<span className={styles.statLabel}>Service Categories</span>
</div>
<div className={styles.statItem}>
<span className={styles.statNumber}>100%</span>
<span className={styles.statLabel}>Client Satisfaction</span>
</div>
</div>
</motion.div>
</div>
</section>
{/* Services Section */}
<section className={styles.servicesSection}>
<div className={styles.servicesBackground}></div>
<div className={styles.servicesContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className={styles.servicesHeader}
>
<Title level={2} className={styles.servicesTitle}>
What We <span className={styles.gradientText}>Offer</span>
</Title>
<Paragraph className={styles.servicesSubtitle}>
Comprehensive technology solutions designed to drive your business
forward. Each service is crafted with precision and delivered with
excellence.
</Paragraph>
</motion.div>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.servicesGrid}
>
{services.map((service, index) => (
<motion.div
key={service.id}
variants={itemVariants}
whileHover={{
scale: 1.02,
transition: { duration: 0.2 },
}}
>
<div className={styles.serviceCard}>
<div className={styles.cardHeader}>
<div
className={`${styles.serviceIconWrapper} ${service.iconClass}`}
>
{service.icon}
</div>
<div className={styles.serviceBadge}>
Service {String(index + 1).padStart(2, "0")}
</div>
</div>
<div className={styles.cardContent}>
<Title level={3} className={styles.serviceTitle}>
{service.title}
</Title>
<Paragraph className={styles.serviceDescription}>
{service.description}
</Paragraph>
<div className={styles.featuresContainer}>
<h4 className={styles.featuresTitle}>Key Features</h4>
<ul className={styles.serviceFeatures}>
{service.features.map((feature, index) => (
<motion.li
key={index}
className={styles.serviceFeature}
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
>
<span className={styles.featureIcon}></span>
{feature}
</motion.li>
))}
</ul>
</div>
<div className={styles.cardFooter}>
<Button type="primary" className={styles.learnMoreBtn}>
Explore Service <ArrowRightOutlined />
</Button>
</div>
</div>
</div>
</motion.div>
))}
</motion.div>
</div>
</section>
{/* Process Section */}
<section className={styles.processSection}>
<div className={styles.processBackground}></div>
<div className={styles.processContainer}>
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className={styles.processHeader}
>
<Title level={2} className={styles.processTitle}>
Our <span className={styles.gradientText}>Process</span>
</Title>
<Paragraph className={styles.processSubtitle}>
A proven methodology that ensures successful project delivery and
exceeds expectations.
</Paragraph>
</motion.div>
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className={styles.processSteps}
>
{processSteps.map((step, index) => (
<motion.div key={index} variants={itemVariants}>
<div className={styles.processStep}>
<div className={styles.stepNumber}>{step.number}</div>
<Title level={4} className={styles.stepTitle}>
{step.title}
</Title>
<Paragraph className={styles.stepDescription}>
{step.description}
</Paragraph>
</div>
</motion.div>
))}
</motion.div>
</div>
</section>
<Footer />
</main>
);
}

44
src/app/sitemap.ts Normal file
View File

@@ -0,0 +1,44 @@
import { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
const baseUrl = 'https://tech-masters.guru'
return [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 1,
},
{
url: `${baseUrl}/about`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/services`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/projects`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.9,
},
{
url: `${baseUrl}/testimonials`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.7,
},
{
url: `${baseUrl}/contact`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
]
}

View File

@@ -0,0 +1,32 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Client Testimonials | Tech Master - What Our Clients Say",
description: "Read testimonials from our satisfied clients in Dubai. Discover how Tech Master has helped businesses achieve digital transformation and success through innovative IT solutions.",
keywords: [
"client testimonials",
"customer reviews",
"Dubai IT company reviews",
"digital transformation success",
"IT solutions testimonials",
"web development reviews",
"mobile app development feedback",
"enterprise software testimonials"
],
openGraph: {
title: "Client Testimonials | Tech Master - What Our Clients Say",
description: "Read testimonials from our satisfied clients in Dubai. Discover how Tech Master has helped businesses achieve digital transformation.",
url: "https://tech-masters.guru/testimonials",
},
alternates: {
canonical: "/testimonials",
},
};
export default function TestimonialsLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -0,0 +1,11 @@
"use client";
import TestimonialsSection from "../components/Testimonials/Testimonials";
export default function TestimonialsPage() {
return (
<main className="pt-20">
<TestimonialsSection />
</main>
);
}

View File

@@ -1,7 +1,11 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES2017", "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"], "lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"strict": true, "strict": true,
@@ -11,7 +15,7 @@
"moduleResolution": "bundler", "moduleResolution": "bundler",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "react-jsx",
"incremental": true, "incremental": true,
"plugins": [ "plugins": [
{ {
@@ -19,9 +23,19 @@
} }
], ],
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": [
"./src/*"
]
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "include": [
"exclude": ["node_modules"] "next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
} }

2314
yarn.lock

File diff suppressed because it is too large Load Diff