🎨 refactor(pages): rearrange imports and formatting for Blog, BlogArticle, ProjectDetails, and Projects
This commit organizes import statements and standardizes code formatting across the Blog, BlogArticle, ProjectDetails, and Projects pages. Improvements include consistent spacing, use of double quotes, and more readable conditional rendering, contributing to better maintainability and readability of the codebase.
This commit is contained in:
+36
-32
@@ -1,15 +1,19 @@
|
||||
import { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowLeft, Calendar, Clock, User, Search } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import Navbar from '@/components/Navbar';
|
||||
import Footer from '@/components/Footer';
|
||||
import PageTransition from '@/components/PageTransition';
|
||||
import { useBlogs } from './../hooks/queires/useBlogs';
|
||||
import PageTransition from "@/components/PageTransition";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Calendar, Clock, Search, User } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useBlogs } from "./../hooks/queires/useBlogs";
|
||||
|
||||
const categories = ['All', 'AI & Machine Learning', 'Cloud Solutions', 'Web Development', 'Mobile Development'];
|
||||
const categories = [
|
||||
"All",
|
||||
"AI & Machine Learning",
|
||||
"Cloud Solutions",
|
||||
"Web Development",
|
||||
"Mobile Development",
|
||||
];
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
@@ -24,23 +28,22 @@ const itemVariants = {
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.5, ease: 'easeOut' as const },
|
||||
transition: { duration: 0.5, ease: "easeOut" as const },
|
||||
},
|
||||
};
|
||||
|
||||
export default function Blog() {
|
||||
|
||||
const {data} = useBlogs();
|
||||
const { data } = useBlogs();
|
||||
const blogPosts = data?.data.result;
|
||||
|
||||
const [activeCategory, setActiveCategory] = useState("All");
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
|
||||
const [activeCategory, setActiveCategory] = useState('All');
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
const filteredPosts = blogPosts?.filter(post => {
|
||||
const matchesCategory = activeCategory === 'All' || post.category === activeCategory;
|
||||
const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
const filteredPosts = blogPosts?.filter((post) => {
|
||||
const matchesCategory =
|
||||
activeCategory === "All" || post.category === activeCategory;
|
||||
const matchesSearch =
|
||||
post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
post.excerpt.toLowerCase().includes(searchQuery.toLowerCase());
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
@@ -48,8 +51,6 @@ export default function Blog() {
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||
<Navbar />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="pt-32 pb-16 relative overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
@@ -81,7 +82,8 @@ export default function Blog() {
|
||||
Our <span className="text-primary neon-text-glow">Blog</span>
|
||||
</h1>
|
||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||
Insights, tutorials, and thought leadership from our team of experts.
|
||||
Insights, tutorials, and thought leadership from our team of
|
||||
experts.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -114,12 +116,13 @@ export default function Blog() {
|
||||
{categories.map((category) => (
|
||||
<Button
|
||||
key={category}
|
||||
variant={activeCategory === category ? 'default' : 'outline'}
|
||||
variant={activeCategory === category ? "default" : "outline"}
|
||||
onClick={() => setActiveCategory(category)}
|
||||
className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category
|
||||
? 'neon-glow bg-primary text-primary-foreground'
|
||||
: 'glass border-primary/30 hover:border-primary'
|
||||
}`}
|
||||
className={`rounded-full px-6 transition-all duration-300 ${
|
||||
activeCategory === category
|
||||
? "neon-glow bg-primary text-primary-foreground"
|
||||
: "glass border-primary/30 hover:border-primary"
|
||||
}`}
|
||||
>
|
||||
{category}
|
||||
</Button>
|
||||
@@ -171,7 +174,10 @@ export default function Blog() {
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Calendar className="w-3 h-3" />
|
||||
{new Date(post.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
|
||||
{new Date(post.date).toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
})}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" />
|
||||
@@ -197,8 +203,6 @@ export default function Blog() {
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</PageTransition>
|
||||
);
|
||||
|
||||
+109
-45
@@ -1,21 +1,27 @@
|
||||
import { useParams, Link, useNavigate } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowLeft, Calendar, Clock, Twitter, Linkedin, Facebook, Link2 } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { toast } from 'sonner';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import Navbar from '@/components/Navbar';
|
||||
import Footer from '@/components/Footer';
|
||||
import PageTransition from '@/components/PageTransition';
|
||||
import { getPostBySlug, getRelatedPosts } from '@/data/blogData';
|
||||
import { useBlogById } from '@/hooks/queires/useBlogs';
|
||||
import PageTransition from "@/components/PageTransition";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getRelatedPosts } from "@/data/blogData";
|
||||
import { useBlogById } from "@/hooks/queires/useBlogs";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
ArrowLeft,
|
||||
Calendar,
|
||||
Clock,
|
||||
Facebook,
|
||||
Link2,
|
||||
Linkedin,
|
||||
Twitter,
|
||||
} from "lucide-react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function BlogArticle() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const {data} = useBlogById(id);
|
||||
const { data } = useBlogById(id);
|
||||
|
||||
const post = data?.data.data
|
||||
const post = data?.data.data;
|
||||
const navigate = useNavigate();
|
||||
// const post = getPostBySlug(id || '');
|
||||
|
||||
@@ -25,8 +31,10 @@ export default function BlogArticle() {
|
||||
<div className="min-h-screen bg-background flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Article Not Found</h1>
|
||||
<p className="text-muted-foreground mb-8">The article you're looking for doesn't exist.</p>
|
||||
<Button onClick={() => navigate('/blog')}>Back to Blog</Button>
|
||||
<p className="text-muted-foreground mb-8">
|
||||
The article you're looking for doesn't exist.
|
||||
</p>
|
||||
<Button onClick={() => navigate("/blog")}>Back to Blog</Button>
|
||||
</div>
|
||||
</div>
|
||||
</PageTransition>
|
||||
@@ -43,19 +51,17 @@ export default function BlogArticle() {
|
||||
facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`,
|
||||
};
|
||||
|
||||
if (platform === 'copy') {
|
||||
if (platform === "copy") {
|
||||
navigator.clipboard.writeText(shareUrl);
|
||||
toast.success('Link copied to clipboard!');
|
||||
toast.success("Link copied to clipboard!");
|
||||
} else {
|
||||
window.open(urls[platform], '_blank', 'width=600,height=400');
|
||||
window.open(urls[platform], "_blank", "width=600,height=400");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||
<Navbar />
|
||||
|
||||
{/* Hero */}
|
||||
<section className="pt-32 pb-16 relative overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
@@ -110,13 +116,19 @@ export default function BlogArticle() {
|
||||
className="w-10 h-10 rounded-full object-cover border-2 border-primary/50"
|
||||
/>
|
||||
<div>
|
||||
<p className="font-medium text-foreground">{post.author.name}</p>
|
||||
<p className="font-medium text-foreground">
|
||||
{post.author.name}
|
||||
</p>
|
||||
<p className="text-sm">{post.author.role}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className="flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4" />
|
||||
{new Date(post.date).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}
|
||||
{new Date(post.date).toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})}
|
||||
</span>
|
||||
<span className="flex items-center gap-2">
|
||||
<Clock className="w-4 h-4" />
|
||||
@@ -154,17 +166,57 @@ export default function BlogArticle() {
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
h1: ({ children }) => <h1 className="text-3xl font-bold text-foreground mt-8 mb-4">{children}</h1>,
|
||||
h2: ({ children }) => <h2 className="text-2xl font-bold text-foreground mt-8 mb-4">{children}</h2>,
|
||||
h3: ({ children }) => <h3 className="text-xl font-bold text-foreground mt-6 mb-3">{children}</h3>,
|
||||
h4: ({ children }) => <h4 className="text-lg font-bold text-foreground mt-4 mb-2">{children}</h4>,
|
||||
p: ({ children }) => <p className="text-muted-foreground leading-relaxed mb-4">{children}</p>,
|
||||
ul: ({ children }) => <ul className="list-disc list-inside text-muted-foreground space-y-2 mb-4 ml-4">{children}</ul>,
|
||||
ol: ({ children }) => <ol className="list-decimal list-inside text-muted-foreground space-y-2 mb-4 ml-4">{children}</ol>,
|
||||
li: ({ children }) => <li className="text-muted-foreground">{children}</li>,
|
||||
a: ({ href, children }) => <a href={href} className="text-primary hover:underline">{children}</a>,
|
||||
strong: ({ children }) => <strong className="font-bold text-foreground">{children}</strong>,
|
||||
em: ({ children }) => <em className="italic">{children}</em>,
|
||||
h1: ({ children }) => (
|
||||
<h1 className="text-3xl font-bold text-foreground mt-8 mb-4">
|
||||
{children}
|
||||
</h1>
|
||||
),
|
||||
h2: ({ children }) => (
|
||||
<h2 className="text-2xl font-bold text-foreground mt-8 mb-4">
|
||||
{children}
|
||||
</h2>
|
||||
),
|
||||
h3: ({ children }) => (
|
||||
<h3 className="text-xl font-bold text-foreground mt-6 mb-3">
|
||||
{children}
|
||||
</h3>
|
||||
),
|
||||
h4: ({ children }) => (
|
||||
<h4 className="text-lg font-bold text-foreground mt-4 mb-2">
|
||||
{children}
|
||||
</h4>
|
||||
),
|
||||
p: ({ children }) => (
|
||||
<p className="text-muted-foreground leading-relaxed mb-4">
|
||||
{children}
|
||||
</p>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="list-disc list-inside text-muted-foreground space-y-2 mb-4 ml-4">
|
||||
{children}
|
||||
</ul>
|
||||
),
|
||||
ol: ({ children }) => (
|
||||
<ol className="list-decimal list-inside text-muted-foreground space-y-2 mb-4 ml-4">
|
||||
{children}
|
||||
</ol>
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="text-muted-foreground">{children}</li>
|
||||
),
|
||||
a: ({ href, children }) => (
|
||||
<a href={href} className="text-primary hover:underline">
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
strong: ({ children }) => (
|
||||
<strong className="font-bold text-foreground">
|
||||
{children}
|
||||
</strong>
|
||||
),
|
||||
em: ({ children }) => (
|
||||
<em className="italic">{children}</em>
|
||||
),
|
||||
blockquote: ({ children }) => (
|
||||
<blockquote className="border-l-4 border-primary pl-4 italic text-muted-foreground my-4">
|
||||
{children}
|
||||
@@ -173,7 +225,11 @@ export default function BlogArticle() {
|
||||
code: ({ className, children }) => {
|
||||
const isInline = !className;
|
||||
if (isInline) {
|
||||
return <code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">{children}</code>;
|
||||
return (
|
||||
<code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<code className="block bg-muted border border-border rounded-lg p-4 overflow-x-auto text-sm font-mono my-4">
|
||||
@@ -181,7 +237,11 @@ export default function BlogArticle() {
|
||||
</code>
|
||||
);
|
||||
},
|
||||
pre: ({ children }) => <pre className="bg-muted border border-border rounded-lg p-4 overflow-x-auto my-4">{children}</pre>,
|
||||
pre: ({ children }) => (
|
||||
<pre className="bg-muted border border-border rounded-lg p-4 overflow-x-auto my-4">
|
||||
{children}
|
||||
</pre>
|
||||
),
|
||||
hr: () => <hr className="border-border my-8" />,
|
||||
}}
|
||||
>
|
||||
@@ -194,12 +254,14 @@ export default function BlogArticle() {
|
||||
<div className="sticky top-32 space-y-8">
|
||||
{/* Share */}
|
||||
<div className="glass rounded-2xl p-6">
|
||||
<h4 className="font-bold mb-4 text-sm uppercase tracking-wide text-muted-foreground">Share</h4>
|
||||
<h4 className="font-bold mb-4 text-sm uppercase tracking-wide text-muted-foreground">
|
||||
Share
|
||||
</h4>
|
||||
<div className="flex flex-col gap-3">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleShare('twitter')}
|
||||
onClick={() => handleShare("twitter")}
|
||||
className="justify-start gap-2 glass border-primary/30"
|
||||
>
|
||||
<Twitter className="w-4 h-4" /> Twitter
|
||||
@@ -207,7 +269,7 @@ export default function BlogArticle() {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleShare('linkedin')}
|
||||
onClick={() => handleShare("linkedin")}
|
||||
className="justify-start gap-2 glass border-primary/30"
|
||||
>
|
||||
<Linkedin className="w-4 h-4" /> LinkedIn
|
||||
@@ -215,7 +277,7 @@ export default function BlogArticle() {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleShare('facebook')}
|
||||
onClick={() => handleShare("facebook")}
|
||||
className="justify-start gap-2 glass border-primary/30"
|
||||
>
|
||||
<Facebook className="w-4 h-4" /> Facebook
|
||||
@@ -223,7 +285,7 @@ export default function BlogArticle() {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleShare('copy')}
|
||||
onClick={() => handleShare("copy")}
|
||||
className="justify-start gap-2 glass border-primary/30"
|
||||
>
|
||||
<Link2 className="w-4 h-4" /> Copy Link
|
||||
@@ -233,7 +295,9 @@ export default function BlogArticle() {
|
||||
|
||||
{/* Tags */}
|
||||
<div className="glass rounded-2xl p-6">
|
||||
<h4 className="font-bold mb-4 text-sm uppercase tracking-wide text-muted-foreground">Tags</h4>
|
||||
<h4 className="font-bold mb-4 text-sm uppercase tracking-wide text-muted-foreground">
|
||||
Tags
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{post.tags.map((tag) => (
|
||||
<span
|
||||
@@ -267,7 +331,9 @@ export default function BlogArticle() {
|
||||
/>
|
||||
<div className="text-center md:text-left">
|
||||
<h3 className="text-2xl font-bold mb-2">{post.author.name}</h3>
|
||||
<p className="text-primary font-medium mb-4">{post.author.role}</p>
|
||||
<p className="text-primary font-medium mb-4">
|
||||
{post.author.role}
|
||||
</p>
|
||||
<p className="text-muted-foreground mb-4">{post.author.bio}</p>
|
||||
<div className="flex gap-3 justify-center md:justify-start">
|
||||
{post.author.twitter && (
|
||||
@@ -342,8 +408,6 @@ export default function BlogArticle() {
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</PageTransition>
|
||||
);
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { useParams, Link, useNavigate } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import { ArrowLeft, ExternalLink, Github, Calendar, Clock, Users, ChevronRight } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import Navbar from '@/components/Navbar';
|
||||
import Footer from '@/components/Footer';
|
||||
import PageTransition from '@/components/PageTransition';
|
||||
import { getProjectBySlug, getRelatedProjects } from '@/data/projectData';
|
||||
import PageTransition from "@/components/PageTransition";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getProjectBySlug, getRelatedProjects } from "@/data/projectData";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Calendar,
|
||||
ChevronRight,
|
||||
Clock,
|
||||
ExternalLink,
|
||||
Github,
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import remarkGfm from "remark-gfm";
|
||||
|
||||
export default function ProjectDetails() {
|
||||
const { slug } = useParams<{ slug: string }>();
|
||||
const navigate = useNavigate();
|
||||
const project = getProjectBySlug(slug || '');
|
||||
const project = getProjectBySlug(slug || "");
|
||||
|
||||
if (!project) {
|
||||
return (
|
||||
@@ -20,8 +25,12 @@ export default function ProjectDetails() {
|
||||
<div className="min-h-screen bg-background flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold mb-4">Project Not Found</h1>
|
||||
<p className="text-muted-foreground mb-8">The project you're looking for doesn't exist.</p>
|
||||
<Button onClick={() => navigate('/projects')}>Back to Projects</Button>
|
||||
<p className="text-muted-foreground mb-8">
|
||||
The project you're looking for doesn't exist.
|
||||
</p>
|
||||
<Button onClick={() => navigate("/projects")}>
|
||||
Back to Projects
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</PageTransition>
|
||||
@@ -30,17 +39,15 @@ export default function ProjectDetails() {
|
||||
|
||||
const relatedProjects = getRelatedProjects(project);
|
||||
const categoryLabels: Record<string, string> = {
|
||||
web: 'Web Development',
|
||||
mobile: 'Mobile App',
|
||||
ai: 'AI & Machine Learning',
|
||||
cloud: 'Cloud Solutions',
|
||||
web: "Web Development",
|
||||
mobile: "Mobile App",
|
||||
ai: "AI & Machine Learning",
|
||||
cloud: "Cloud Solutions",
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||
<Navbar />
|
||||
|
||||
{/* Hero */}
|
||||
<section className="pt-32 pb-16 relative overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
@@ -56,9 +63,16 @@ export default function ProjectDetails() {
|
||||
transition={{ duration: 0.5 }}
|
||||
className="flex items-center gap-2 text-sm text-muted-foreground mb-8"
|
||||
>
|
||||
<Link to="/" className="hover:text-primary transition-colors">Home</Link>
|
||||
<Link to="/" className="hover:text-primary transition-colors">
|
||||
Home
|
||||
</Link>
|
||||
<ChevronRight className="w-4 h-4" />
|
||||
<Link to="/projects" className="hover:text-primary transition-colors">Projects</Link>
|
||||
<Link
|
||||
to="/projects"
|
||||
className="hover:text-primary transition-colors"
|
||||
>
|
||||
Projects
|
||||
</Link>
|
||||
<ChevronRight className="w-4 h-4" />
|
||||
<span className="text-foreground">{project.title}</span>
|
||||
</motion.div>
|
||||
@@ -132,7 +146,10 @@ export default function ProjectDetails() {
|
||||
<ExternalLink className="w-4 h-4 mr-2" />
|
||||
View Live
|
||||
</Button>
|
||||
<Button variant="outline" className="rounded-full glass border-primary/30">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="rounded-full glass border-primary/30"
|
||||
>
|
||||
<Github className="w-4 h-4 mr-2" />
|
||||
View Code
|
||||
</Button>
|
||||
@@ -181,7 +198,9 @@ export default function ProjectDetails() {
|
||||
<p className="text-3xl md:text-4xl font-bold text-primary neon-text-glow mb-2">
|
||||
{result.value}
|
||||
</p>
|
||||
<p className="text-muted-foreground text-sm">{result.label}</p>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
{result.label}
|
||||
</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
@@ -203,10 +222,24 @@ export default function ProjectDetails() {
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
p: ({ children }) => <p className="text-muted-foreground leading-relaxed mb-4">{children}</p>,
|
||||
strong: ({ children }) => <strong className="font-bold text-foreground">{children}</strong>,
|
||||
ul: ({ children }) => <ul className="list-disc list-inside text-muted-foreground space-y-2 mb-4 ml-4">{children}</ul>,
|
||||
li: ({ children }) => <li className="text-muted-foreground">{children}</li>,
|
||||
p: ({ children }) => (
|
||||
<p className="text-muted-foreground leading-relaxed mb-4">
|
||||
{children}
|
||||
</p>
|
||||
),
|
||||
strong: ({ children }) => (
|
||||
<strong className="font-bold text-foreground">
|
||||
{children}
|
||||
</strong>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="list-disc list-inside text-muted-foreground space-y-2 mb-4 ml-4">
|
||||
{children}
|
||||
</ul>
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="text-muted-foreground">{children}</li>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{project.fullDescription}
|
||||
@@ -262,7 +295,9 @@ export default function ProjectDetails() {
|
||||
{project.challenges.map((challenge, index) => (
|
||||
<li key={index} className="flex items-start gap-3">
|
||||
<span className="w-2 h-2 rounded-full bg-neon-purple mt-2 flex-shrink-0" />
|
||||
<span className="text-muted-foreground">{challenge}</span>
|
||||
<span className="text-muted-foreground">
|
||||
{challenge}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@@ -356,7 +391,10 @@ export default function ProjectDetails() {
|
||||
className="text-center mt-12"
|
||||
>
|
||||
<Link to="/projects">
|
||||
<Button variant="outline" className="rounded-full px-8 glass border-primary/30 hover:neon-glow">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="rounded-full px-8 glass border-primary/30 hover:neon-glow"
|
||||
>
|
||||
View All Projects
|
||||
</Button>
|
||||
</Link>
|
||||
@@ -364,8 +402,6 @@ export default function ProjectDetails() {
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</PageTransition>
|
||||
);
|
||||
|
||||
+45
-35
@@ -1,21 +1,27 @@
|
||||
import { useState } from 'react';
|
||||
import { motion, AnimatePresence, calcLength } from 'framer-motion';
|
||||
import { ArrowLeft, Globe, Smartphone, Brain, Cloud, ExternalLink, Workflow, Github } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import Navbar from '@/components/Navbar';
|
||||
import Footer from '@/components/Footer';
|
||||
import PageTransition from '@/components/PageTransition';
|
||||
import { useProjects } from '@/hooks/queires/useProjects';
|
||||
import { projects } from '@/data/projectData';
|
||||
import PageTransition from "@/components/PageTransition";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useProjects } from "@/hooks/queires/useProjects";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import {
|
||||
ArrowLeft,
|
||||
Brain,
|
||||
Cloud,
|
||||
ExternalLink,
|
||||
Github,
|
||||
Globe,
|
||||
Smartphone,
|
||||
Workflow,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const categories = [
|
||||
{ id: 'all', name: 'All Projects', icon: null },
|
||||
{ id: 'web', name: 'Web', icon: Globe },
|
||||
{ id: 'mobile', name: 'Mobile', icon: Smartphone },
|
||||
{ id: 'ai', name: 'AI', icon: Brain },
|
||||
{ id: 'cloud', name: 'Cloud', icon: Cloud },
|
||||
{ id: 'devops', name: 'DEVOPS', icon: Workflow },
|
||||
{ id: "all", name: "All Projects", icon: null },
|
||||
{ id: "web", name: "Web", icon: Globe },
|
||||
{ id: "mobile", name: "Mobile", icon: Smartphone },
|
||||
{ id: "ai", name: "AI", icon: Brain },
|
||||
{ id: "cloud", name: "Cloud", icon: Cloud },
|
||||
{ id: "devops", name: "DEVOPS", icon: Workflow },
|
||||
];
|
||||
|
||||
const containerVariants = {
|
||||
@@ -33,26 +39,24 @@ const itemVariants = {
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.5, ease: 'easeOut' as const },
|
||||
transition: { duration: 0.5, ease: "easeOut" as const },
|
||||
},
|
||||
};
|
||||
|
||||
export default function Projects() {
|
||||
|
||||
const {data: projectsData} = useProjects();
|
||||
const { data: projectsData } = useProjects();
|
||||
const projects = projectsData?.data.data.result;
|
||||
|
||||
const [activeCategory, setActiveCategory] = useState('all');
|
||||
const [activeCategory, setActiveCategory] = useState("all");
|
||||
|
||||
const filteredProjects = activeCategory === 'all'
|
||||
? projects
|
||||
: projects?.filter(project => project.category === activeCategory);
|
||||
const filteredProjects =
|
||||
activeCategory === "all"
|
||||
? projects
|
||||
: projects?.filter((project) => project.category === activeCategory);
|
||||
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className="min-h-screen bg-background overflow-x-hidden">
|
||||
<Navbar />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="pt-32 pb-16 relative overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
@@ -83,10 +87,12 @@ export default function Projects() {
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h1 className="text-5xl md:text-6xl font-bold mb-6">
|
||||
Our <span className="text-primary neon-text-glow">Projects</span>
|
||||
Our{" "}
|
||||
<span className="text-primary neon-text-glow">Projects</span>
|
||||
</h1>
|
||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||
Explore our portfolio of innovative solutions that have transformed businesses across industries.
|
||||
Explore our portfolio of innovative solutions that have
|
||||
transformed businesses across industries.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -102,12 +108,15 @@ export default function Projects() {
|
||||
return (
|
||||
<Button
|
||||
key={category.id}
|
||||
variant={activeCategory === category.id ? 'default' : 'outline'}
|
||||
variant={
|
||||
activeCategory === category.id ? "default" : "outline"
|
||||
}
|
||||
onClick={() => setActiveCategory(category.id)}
|
||||
className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category.id
|
||||
? 'neon-glow bg-primary text-primary-foreground'
|
||||
: 'glass border-primary/30 hover:border-primary'
|
||||
}`}
|
||||
className={`rounded-full px-6 transition-all duration-300 ${
|
||||
activeCategory === category.id
|
||||
? "neon-glow bg-primary text-primary-foreground"
|
||||
: "glass border-primary/30 hover:border-primary"
|
||||
}`}
|
||||
>
|
||||
{Icon && <Icon className="w-4 h-4 mr-2" />}
|
||||
{category.name}
|
||||
@@ -149,7 +158,10 @@ export default function Projects() {
|
||||
{/* Category Badge */}
|
||||
<div className="absolute top-4 left-4">
|
||||
<span className="px-3 py-1 rounded-full bg-primary/20 text-primary text-sm font-medium backdrop-blur-sm border border-primary/30">
|
||||
{categories.find(c => c.id === project.category)?.name}
|
||||
{
|
||||
categories.find((c) => c.id === project.category)
|
||||
?.name
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -222,8 +234,6 @@ export default function Projects() {
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</PageTransition>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user