enhance footer mobile style & implement footer in each page
This commit is contained in:
@@ -14,6 +14,7 @@ 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() {
|
||||
@@ -391,6 +392,8 @@ export default function AboutPage() {
|
||||
</Row>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -73,17 +73,30 @@
|
||||
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 {
|
||||
@@ -98,12 +111,17 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px 0;
|
||||
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 {
|
||||
@@ -124,6 +142,7 @@
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.socialLinks {
|
||||
@@ -131,6 +150,7 @@
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.socialLink {
|
||||
@@ -146,6 +166,8 @@
|
||||
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 {
|
||||
@@ -155,20 +177,77 @@
|
||||
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 */
|
||||
@@ -184,36 +263,99 @@
|
||||
padding: 60px 0 30px;
|
||||
}
|
||||
|
||||
.footerContainer {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.footerContent {
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 30px;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.footerColumn {
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.footerColumnTitle {
|
||||
justify-content: center;
|
||||
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: center;
|
||||
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: 15px;
|
||||
gap: 16px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.socialLink {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.footerBottomText {
|
||||
font-size: 0.9rem;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,29 +364,131 @@
|
||||
padding: 50px 0 25px;
|
||||
}
|
||||
|
||||
.footerContainer {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.footerContent {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 25px;
|
||||
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.85rem;
|
||||
font-size: 0.9rem;
|
||||
padding: 10px 0;
|
||||
min-height: 44px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.socialLinks {
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.socialLink {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
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.8rem;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,26 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { Typography } from 'antd';
|
||||
import { motion } from 'framer-motion';
|
||||
import React from 'react';
|
||||
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: {
|
||||
@@ -40,6 +54,70 @@ const Footer: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
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}>
|
||||
@@ -55,137 +133,49 @@ const Footer: React.FC = () => {
|
||||
viewport={{ once: true }}
|
||||
className={styles.footerContent}
|
||||
>
|
||||
<motion.div variants={itemVariants} className={styles.footerColumn}>
|
||||
<div className={styles.footerColumnTitle}>
|
||||
<TeamOutlined className={styles.footerColumnIcon} />
|
||||
Company
|
||||
</div>
|
||||
<ul className={styles.footerLinks}>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/about">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
About Us
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/services">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Our Services
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/projects">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Portfolio
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/contact">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Contact Us
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
<motion.div variants={itemVariants} className={styles.footerColumn}>
|
||||
<div className={styles.footerColumnTitle}>
|
||||
<BulbOutlined className={styles.footerColumnIcon} />
|
||||
Services
|
||||
</div>
|
||||
<ul className={styles.footerLinks}>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/services#webdev">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Web Development
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/services#mobile">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Mobile Apps
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/services#ai">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
AI Solutions
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/services#cloud">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Cloud Services
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
<motion.div variants={itemVariants} className={styles.footerColumn}>
|
||||
<div className={styles.footerColumnTitle}>
|
||||
<TrophyOutlined className={styles.footerColumnIcon} />
|
||||
Resources
|
||||
</div>
|
||||
<ul className={styles.footerLinks}>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/blog">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Blog & Insights
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/case-studies">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Case Studies
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/whitepapers">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Whitepapers
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/webinars">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
Webinars
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
<motion.div variants={itemVariants} className={styles.footerColumn}>
|
||||
<div className={styles.footerColumnTitle}>
|
||||
<MailOutlined className={styles.footerColumnIcon} />
|
||||
Contact Info
|
||||
</div>
|
||||
<ul className={styles.footerLinks}>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="mailto:info@techmaster.com">
|
||||
<MailOutlined className={styles.footerLinkIcon} />
|
||||
info@techmaster.com
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="tel:+15551234567">
|
||||
<PhoneOutlined className={styles.footerLinkIcon} />
|
||||
+1 (555) 123-4567
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="#">
|
||||
<EnvironmentOutlined className={styles.footerLinkIcon} />
|
||||
San Francisco, CA
|
||||
</a>
|
||||
</li>
|
||||
<li className={styles.footerLink}>
|
||||
<a href="/support">
|
||||
<ArrowRightOutlined className={styles.footerLinkIcon} />
|
||||
24/7 Support
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
{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
|
||||
@@ -200,22 +190,46 @@ const Footer: React.FC = () => {
|
||||
</Paragraph>
|
||||
|
||||
<div className={styles.socialLinks}>
|
||||
<a href="#" className={styles.socialLink}>
|
||||
<a
|
||||
href="#"
|
||||
className={styles.socialLink}
|
||||
onClick={(e) => e.preventDefault()}
|
||||
aria-label="Facebook"
|
||||
>
|
||||
<FacebookOutlined />
|
||||
</a>
|
||||
<a href="#" className={styles.socialLink}>
|
||||
<a
|
||||
href="#"
|
||||
className={styles.socialLink}
|
||||
onClick={(e) => e.preventDefault()}
|
||||
aria-label="Twitter"
|
||||
>
|
||||
<TwitterOutlined />
|
||||
</a>
|
||||
<a href="#" className={styles.socialLink}>
|
||||
<a
|
||||
href="#"
|
||||
className={styles.socialLink}
|
||||
onClick={(e) => e.preventDefault()}
|
||||
aria-label="LinkedIn"
|
||||
>
|
||||
<LinkedinOutlined />
|
||||
</a>
|
||||
<a href="#" className={styles.socialLink}>
|
||||
<a
|
||||
href="#"
|
||||
className={styles.socialLink}
|
||||
onClick={(e) => e.preventDefault()}
|
||||
aria-label="Instagram"
|
||||
>
|
||||
<InstagramOutlined />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className={styles.copyright}>
|
||||
© 2024 Tech Master. All rights reserved. | Privacy Policy | Terms of Service
|
||||
<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>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { BellOutlined, SearchOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { BellOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { Avatar, Button, Menu, MenuProps, Typography } from "antd";
|
||||
import { motion } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
@@ -81,22 +81,22 @@ const Header = () => {
|
||||
className={styles.actionsSection}
|
||||
>
|
||||
<div className={styles.actionButtons}>
|
||||
<Button
|
||||
{/* <Button
|
||||
type="text"
|
||||
icon={<SearchOutlined />}
|
||||
className={styles.actionButton}
|
||||
/>
|
||||
/> */}
|
||||
<Button
|
||||
type="text"
|
||||
icon={<BellOutlined />}
|
||||
className={styles.actionButton}
|
||||
/>
|
||||
<Button
|
||||
{/* <Button
|
||||
type="primary"
|
||||
className={styles.ctaButton}
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
</Button> */}
|
||||
<Avatar
|
||||
icon={<UserOutlined />}
|
||||
className={styles.userAvatar}
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
CloseOutlined,
|
||||
EyeOutlined,
|
||||
GithubOutlined,
|
||||
LeftOutlined,
|
||||
LinkOutlined,
|
||||
RightOutlined,
|
||||
CloseOutlined,
|
||||
EyeOutlined,
|
||||
LeftOutlined,
|
||||
LinkOutlined,
|
||||
RightOutlined
|
||||
} from "@ant-design/icons";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
Carousel,
|
||||
Col,
|
||||
Modal,
|
||||
Row,
|
||||
Tag,
|
||||
Typography,
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
Carousel,
|
||||
Col,
|
||||
Modal,
|
||||
Row,
|
||||
Tag,
|
||||
Typography,
|
||||
} from "antd";
|
||||
import { AnimatePresence, motion, useAnimation } from "framer-motion";
|
||||
import Image from "next/image";
|
||||
@@ -262,7 +261,7 @@ const ProjectsShowcaseClient: React.FC<ProjectsShowcaseClientProps> = ({
|
||||
Live Demo
|
||||
</Button>
|
||||
)}
|
||||
{selectedProject.githubUrl && (
|
||||
{/* {selectedProject.githubUrl && (
|
||||
<Button
|
||||
icon={<GithubOutlined />}
|
||||
href={selectedProject.githubUrl}
|
||||
@@ -271,7 +270,7 @@ const ProjectsShowcaseClient: React.FC<ProjectsShowcaseClientProps> = ({
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
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;
|
||||
@@ -405,6 +406,8 @@ export default function ContactPage() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
import {
|
||||
CloseOutlined,
|
||||
EyeOutlined,
|
||||
GithubOutlined,
|
||||
LinkOutlined,
|
||||
RocketOutlined,
|
||||
UserOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons";
|
||||
import {
|
||||
Badge,
|
||||
@@ -561,7 +560,7 @@ export default function ProjectsPage() {
|
||||
Live Demo
|
||||
</Button>
|
||||
)}
|
||||
{selectedProject.githubUrl && (
|
||||
{/* {selectedProject.githubUrl && (
|
||||
<Button
|
||||
icon={<GithubOutlined />}
|
||||
href={selectedProject.githubUrl}
|
||||
@@ -569,7 +568,7 @@ export default function ProjectsPage() {
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@ import {
|
||||
MobileOutlined,
|
||||
RobotOutlined,
|
||||
RocketOutlined,
|
||||
ShoppingOutlined
|
||||
ShoppingOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Button, Typography } from "antd";
|
||||
import { motion } from "framer-motion";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Footer from "../components/Footer/Footer";
|
||||
import styles from "./page.module.css";
|
||||
|
||||
const { Title, Paragraph } = Typography;
|
||||
@@ -276,12 +277,12 @@ export default function ServicesPage() {
|
||||
className={styles.servicesGrid}
|
||||
>
|
||||
{services.map((service, index) => (
|
||||
<motion.div
|
||||
key={service.id}
|
||||
<motion.div
|
||||
key={service.id}
|
||||
variants={itemVariants}
|
||||
whileHover={{
|
||||
whileHover={{
|
||||
scale: 1.02,
|
||||
transition: { duration: 0.2 }
|
||||
transition: { duration: 0.2 },
|
||||
}}
|
||||
>
|
||||
<div className={styles.serviceCard}>
|
||||
@@ -292,7 +293,7 @@ export default function ServicesPage() {
|
||||
{service.icon}
|
||||
</div>
|
||||
<div className={styles.serviceBadge}>
|
||||
Service {String(index + 1).padStart(2, '0')}
|
||||
Service {String(index + 1).padStart(2, "0")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -309,8 +310,8 @@ export default function ServicesPage() {
|
||||
<h4 className={styles.featuresTitle}>Key Features</h4>
|
||||
<ul className={styles.serviceFeatures}>
|
||||
{service.features.map((feature, index) => (
|
||||
<motion.li
|
||||
key={index}
|
||||
<motion.li
|
||||
key={index}
|
||||
className={styles.serviceFeature}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
@@ -380,29 +381,7 @@ export default function ServicesPage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={styles.ctaSection}>
|
||||
<div className={styles.ctaContainer}>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<Title level={2} className={styles.ctaTitle}>
|
||||
Ready to Start Your{" "}
|
||||
<span className={styles.gradientText}>Project</span>?
|
||||
</Title>
|
||||
<Paragraph className={styles.ctaSubtitle}>
|
||||
Let's discuss how we can help bring your vision to life. Our team
|
||||
is ready to create something amazing together.
|
||||
</Paragraph>
|
||||
<Button size="large" className={styles.ctaButton}>
|
||||
Get Started Today <ArrowRightOutlined />
|
||||
</Button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user