diff --git a/README.md b/README.md index 70b7c82..408fd40 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,3 @@ -# Welcome to your Lovable project - -## Project info - -**URL**: https://lovable.dev/projects/REPLACE_WITH_PROJECT_ID - -## How can I edit this code? - -There are several ways of editing your application. - -**Use Lovable** - -Simply visit the [Lovable Project](https://lovable.dev/projects/REPLACE_WITH_PROJECT_ID) and start prompting. - -Changes made via Lovable will be committed automatically to this repo. - -**Use your preferred IDE** - -If you want to work locally using your own IDE, you can clone this repo and push changes. Pushed changes will also be reflected in Lovable. - -The only requirement is having Node.js & npm installed - [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating) - -Follow these steps: - -```sh -# Step 1: Clone the repository using the project's Git URL. -git clone - -# Step 2: Navigate to the project directory. -cd - -# Step 3: Install the necessary dependencies. -npm i - -# Step 4: Start the development server with auto-reloading and an instant preview. -npm run dev -``` - -**Edit a file directly in GitHub** - -- Navigate to the desired file(s). -- Click the "Edit" button (pencil icon) at the top right of the file view. -- Make your changes and commit the changes. - -**Use GitHub Codespaces** - -- Navigate to the main page of your repository. -- Click on the "Code" button (green button) near the top right. -- Select the "Codespaces" tab. -- Click on "New codespace" to launch a new Codespace environment. -- Edit files directly within the Codespace and commit and push your changes once you're done. - -## What technologies are used for this project? - -This project is built with: - -- Vite -- TypeScript -- React -- shadcn-ui -- Tailwind CSS - -## How can I deploy this project? - -Simply open [Lovable](https://lovable.dev/projects/REPLACE_WITH_PROJECT_ID) and click on Share -> Publish. - -## Can I connect a custom domain to my Lovable project? - -Yes, you can! - -To connect a domain, navigate to Project > Settings > Domains and click Connect Domain. - -Read more here: [Setting up a custom domain](https://docs.lovable.dev/features/custom-domain#custom-domain) +techzaa.alpha@gmail.com, +
+TechZaa@@##123 \ No newline at end of file diff --git a/src/components/home/ProjectCard.tsx b/src/components/home/ProjectCard.tsx index 75dfd4a..419a877 100644 --- a/src/components/home/ProjectCard.tsx +++ b/src/components/home/ProjectCard.tsx @@ -1,102 +1,173 @@ -import { motion } from "framer-motion"; -import { ExternalLink } from "lucide-react"; -import { useState } from "react"; +import { motion, useReducedMotion } from "framer-motion"; +import { ArrowUpRight, Layers } from "lucide-react"; +import { useId, useState } from "react"; import { Link } from "react-router-dom"; -export function ProjectCard({ project, color, index, isInView }) { +interface ProjectPayload { + _id: string; + title: string; + category: string[]; + isFeatured: boolean; + technologies: string[]; + publishedYear: string | number; + previewUrl: string; + image?: string; +} + +interface ProjectCardProps { + project: ProjectPayload; + index: number; + isInView: boolean; +} + +export function ProjectCard({ project, index, isInView }: ProjectCardProps) { const [mousePosition, setMousePosition] = useState({ x: 50, y: 50 }); const [isHovered, setIsHovered] = useState(false); + const shouldReduceMotion = useReducedMotion(); + const titleId = useId(); const handleMouseMove = (e: React.MouseEvent) => { + if (shouldReduceMotion) return; const rect = e.currentTarget.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setMousePosition({ x, y }); }; + // Safe Fallback Asset Frame + const projectImage = + project.image || + "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=800&auto=format&fit=crop"; + return ( - setIsHovered(true)} onMouseLeave={() => { setIsHovered(false); setMousePosition({ x: 50, y: 50 }); }} + aria-labelledby={titleId} > - {/* Main Card Container with 3D Tilt */} + {/* Interactive Visual Window */}
- {/* Image Container */} -
- {project.title} - - {/* Dynamic Shine Overlay */} -
-
- - {/* Gradient Overlay */} -
- {/* Content */} -
-
- {/* Category */} - - {project.category} - + {/* Techzaa Radial Spotlight Overlay */} + {!shouldReduceMotion && ( +
+ )} - {/* Title */} -

- {project.title} -

+ {/* Absolute Year Floating Tag */} + + {project.publishedYear} + +
- {/* View Project Link */} - - live - - + {/* Structured Informational Body Content */} +
+
+ {/* Category Chip List Mapping handles strings or arrays cleanly */} +
+ {Array.isArray(project.category) ? ( + project.category.slice(0, 3).map((cat) => ( + + {cat} + + )) + ) : ( + + {project.category} + + )}
+ + {/* Title Identifier linked to parent card components via standard a11y specs */} +

+ {project.title} +

+ + {/* Previewing active Framework stacks cleanly underneath */} + {project.technologies && project.technologies.length > 0 && ( +
+ {project.technologies.slice(0, 4).map((tech) => ( + + {tech} + + ))} + {project.technologies.length > 4 && ( + + +{project.technologies.length - 4} more + + )} +
+ )}
- {/* Neon Border Glow */} -
+ {/* Action Controls Matrix Bar */} +
+ + + Case Study + + + + Live Platform + + +
- ); -} \ No newline at end of file +} diff --git a/src/components/home/ProjectsSection.tsx b/src/components/home/ProjectsSection.tsx index 1adf35e..2fe7ee4 100644 --- a/src/components/home/ProjectsSection.tsx +++ b/src/components/home/ProjectsSection.tsx @@ -4,8 +4,8 @@ import { motion, useInView } from "framer-motion"; import { ArrowRight } from "lucide-react"; import { useRef } from "react"; import { Link } from "react-router-dom"; -import { ProjectCard } from "./ProjectCard"; import PremiumBadge from "../shared/PremiumBadge"; +import { ProjectCard } from "./ProjectCard"; const gradientColors = [ "from-neon-blue/90", @@ -19,9 +19,9 @@ export default function ProjectsSection() { fields: "category, title, image, liveUrl", limit: 6, }); - - const projects = projectsData?.data.data.result || []; - + console.log(projectsData?.data.data); + const projects = projectsData?.data.data || []; + console.log("project from homepage", projects); const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); @@ -50,9 +50,12 @@ export default function ProjectsSection() { transition={{ duration: 0.7 }} className="text-center mb-20" > - +

- Featured Projects + Featured{" "} + + Projects +

Crafted with passion. Delivered with excellence. @@ -62,13 +65,10 @@ export default function ProjectsSection() { {/* Projects Grid */}

{projects.map((project, index) => { - const color = gradientColors[index % gradientColors.length]; - return ( diff --git a/src/components/home/TeamSection.tsx b/src/components/home/TeamSection.tsx index ebd58c4..400f0b0 100644 --- a/src/components/home/TeamSection.tsx +++ b/src/components/home/TeamSection.tsx @@ -59,7 +59,7 @@ export default function TeamSection() { } pagination={{ clickable: true }} modules={[Autoplay, Pagination]} - className="pb-12" // Space for pagination dots + className="pb-12" breakpoints={{ 640: { slidesPerView: 2 }, 1024: { slidesPerView: 3 }, @@ -84,18 +84,7 @@ export default function TeamSection() { className="absolute inset-0 w-full h-full object-cover object-top transition-transform duration-500 group-hover:scale-110" />
-
- - - - - - - - {" "} - - -
+

diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index dc2dd67..5ff5dec 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -17,7 +17,7 @@ const Index = () => { - + {/* */} {/* */} diff --git a/src/pages/ProjectDetails.tsx b/src/pages/ProjectDetails.tsx index c2b830b..e2a48c5 100644 --- a/src/pages/ProjectDetails.tsx +++ b/src/pages/ProjectDetails.tsx @@ -1,67 +1,77 @@ import PageTransition from "@/components/home/PageTransition"; import { Button } from "@/components/ui/button"; import { useProjectById } from "@/hooks/queires/useProjects"; -import { motion } from "framer-motion"; +import { motion, useReducedMotion } from "framer-motion"; import { + AlertCircle, Calendar, + CheckCircle, ChevronRight, Clock, ExternalLink, - Github, - Users, + HelpCircle, + Sliders, + Sparkles, } from "lucide-react"; -import ReactMarkdown from "react-markdown"; import { Link, useNavigate, useParams } from "react-router-dom"; -import remarkGfm from "remark-gfm"; -interface Result { - label: string; - value: string | number; -} - -interface ProjectData { - id: string; - category: string; +// Standardizing backend data matching layer safely +interface BackendProjectPayload { + _id: string; title: string; description: string; - year: string | number; - duration: string; - team: string | number; - client: string; - liveUrl: string; - codeUrl?: string; + category: string[]; + status: string; + isFeatured: boolean; image: string; - results?: Result[]; - fullDescription: string; - features?: string[]; - technologies?: string[]; - challenges?: string[]; - gallery?: string[]; + imageGallery: string[]; + technologies: string[]; + publishedYear: string | number; + problem: string; + solutions: string; + challenges: string; + workingDuration: string; + previewUrl: string; + features: string[]; } -const CATEGORY_LABELS: Record = { - web: "Web Development", - mobile: "Mobile App", - ai: "AI & Machine Learning", - cloud: "Cloud Solutions", -}; - export default function ProjectDetails() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); + const shouldReduceMotion = useReducedMotion(); const { data, isLoading, isError } = useProjectById(id || ""); - const project: ProjectData | null = + const project: BackendProjectPayload | null = data?.data?.data || data?.data || data || null; + const faderUpVariants = { + hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 20 }, + visible: (custom: number) => ({ + opacity: 1, + y: 0, + transition: { + duration: 0.5, + delay: custom * 0.08, + ease: [0.215, 0.61, 0.355, 1], + }, + }), + }; + if (isLoading) { return ( -
+
-
- - Loading project details... +
+
+
+
+ + Parsing Techzaa Case Asset...
@@ -72,20 +82,25 @@ export default function ProjectDetails() { if (isError || !project) { return ( -
-
-

- Project Not Found -

-

- The project you're looking for does not exist or could not be - loaded. -

+
+
+
+ +
+
+

+ Deployment Not Located +

+

+ The targeted project record configuration cannot be pulled from + the API ecosystem. +

+
@@ -95,272 +110,222 @@ export default function ProjectDetails() { return ( -
+
+ {/* HERO SECTION - Architectural Dynamic Header */} +
+
+ {/* Dynamic Breadcrumbs */} + - - {/* Hero Section */} -
- {/* Ambient Background Glows */} -
-
-
-
- -
- {/* Breadcrumb Navigation */} - - - Home - - - - Projects - - - - {project.title} - - - -
- {/* Content Block */} -
- + {/* Primary Metas Block */} +
+ - {CATEGORY_LABELS[project.category] || project.category} - + {Array.isArray(project.category) ? ( + project.category.map((cat) => ( + + {cat} + + )) + ) : ( + + {project.category} + + )} + {project.title} {project.description} - {/* Project Metadata */} + {/* Primary Interaction Arrays */} - {[ - { label: "Year", value: project.year, icon: Calendar }, - { label: "Duration", value: project.duration, icon: Clock }, - { label: "Team Size", value: project.team, icon: Users }, - { label: "Client", value: project.client }, - ].map((item, idx) => ( -
- {item.icon ? ( - - ) : ( -
- )} - - {item.label} - - - {item.value} - -
- ))} - - - {/* Call to Actions */} - - - - - {project.codeUrl && ( - - - - )} + + Live Preview Link + +
- {/* Project Cover Visual */} - - {project.title} -
- + {/* Cover Interactive Card Frame */} +
+ + {`Case + +
- {/* Key Results Section */} - {project.results && project.results.length > 0 && ( -
-
- -

- Key Performance Outcomes -

-

- Measurable impact and business value generated by this - project. -

-
- -
- {project.results.map((result, index) => ( - - - {result.value} + {/* METADATA BAR SECTION */} +
+
+
+ {[ + { + label: "Deployment Year", + value: project.publishedYear, + icon: Calendar, + }, + { + label: "Production Period", + value: project.workingDuration, + icon: Clock, + }, + { + label: "Project Status", + value: project.status, + icon: Sliders, + }, + ].map((item) => ( +
+
+ + {item.label} - - {result.label} + + {item.value} - - ))} -
-
-
- )} - - {/* Main Details Section */} -
-
-
- {/* Main Text Content */} -
-

- About the Project -

-
- ( -

- {children} -

- ), - strong: ({ children }) => ( - - {children} - - ), - ul: ({ children }) => ( -
    - {children} -
- ), - li: ({ children }) => ( -
  • {children}
  • - ), - }} - > - {project.fullDescription} -
    +
    +
    -
    + ))} +
    +
    +
    - {/* Sidebar Capabilities */} -
    - {/* Features */} - {project.features && project.features.length > 0 && ( -
    -

    - Key Capabilities + {/* COMPREHENSIVE CASE LOGIC SECTION */} +
    +
    +
    + {/* Engineering Metrics Column (Left side) */} +
    + {project.problem && ( +
    +

    + + The Structural Problem

    -
      - {project.features.map((feature, index) => ( -
    • - - - {feature} - -
    • - ))} -
    +

    + {project.problem} +

    )} - {/* Technologies Used */} - {project.technologies && project.technologies.length > 0 && ( -
    -

    - Technologies Used + {project.solutions && ( +
    +

    + + Our Applied Strategy

    -
    +

    + {project.solutions} +

    +
    + )} + + {project.challenges && ( +
    +

    + Critical Bottlenecks Resolved +

    +

    + {project.challenges} +

    +
    + )} +
    + +
    + {project.technologies && project.technologies.length > 0 && ( +
    +

    + Tech Stack +

    +
    {project.technologies.map((tech) => ( {tech} @@ -369,19 +334,20 @@ export default function ProjectDetails() {
    )} - {/* Challenges Solved */} - {project.challenges && project.challenges.length > 0 && ( -
    -

    - Challenges Solved + {project.features && project.features.length > 0 && ( +
    +

    + + Delivered Platform Capabilities

    -
      - {project.challenges.map((challenge, index) => ( -
    • - - - {challenge} - +
        + {project.features.map((feature, idx) => ( +
      • +
        + {feature}
      • ))}
      @@ -392,36 +358,36 @@ export default function ProjectDetails() {

    - {/* Gallery Section */} - {project.gallery && project.gallery.length > 0 && ( -
    -
    -
    -

    - Project Gallery + {/* PLATFORM PRESENTATION SHOWCASE GALLERY */} + {project.imageGallery && project.imageGallery.length > 0 && ( +
    +
    +
    +

    + Platform Interface Metrics

    -

    - A visual overview of the implementation and user interface. +

    + Operational state validation screens captured during + deployment execution.

    -
    - {project.gallery.map((image, index) => ( +
    + {project.imageGallery.map((image, index) => ( {`${project.title} -
    ))}
    diff --git a/src/pages/Projects.tsx b/src/pages/Projects.tsx index 970bda2..9ffb12f 100644 --- a/src/pages/Projects.tsx +++ b/src/pages/Projects.tsx @@ -1,315 +1,271 @@ import PageTransition from "@/components/home/PageTransition"; +import { ProjectCard } from "@/components/home/ProjectCard"; import { Button } from "@/components/ui/button"; import { useProjects } from "@/hooks/queires/useProjects"; -import { AnimatePresence, motion } from "framer-motion"; +import { AnimatePresence, motion, useReducedMotion } from "framer-motion"; import { ArrowLeft, Brain, Cloud, - ExternalLink, - Github, Globe, - Loader2, + Layers, Search, Smartphone, + Sparkles, Workflow, } from "lucide-react"; -import { useMemo, useState } from "react"; +import { useDeferredValue, useMemo, useState } from "react"; import { Link } from "react-router-dom"; -const categories = [ - { id: "all", name: "All Projects", icon: null }, - { id: "web", name: "Web", icon: Globe }, +const CATEGORIES = [ + { id: "all", name: "All Work", icon: Layers }, + { id: "web", name: "Web Systems", 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: "ai", name: "AI & ML", icon: Brain }, + { id: "cloud", name: "Cloud Platforms", icon: Cloud }, + { id: "devops", name: "DevOps", icon: Workflow }, ]; const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, - transition: { - staggerChildren: 0.08, - }, + transition: { staggerChildren: 0.04 }, }, }; export default function Projects() { const { data: projectsData, isLoading, isError } = useProjects(); + const shouldReduceMotion = useReducedMotion(); const [activeCategory, setActiveCategory] = useState("all"); const [searchQuery, setSearchQuery] = useState(""); + const deferredSearchQuery = useDeferredValue(searchQuery); + const filteredProjects = useMemo(() => { - const projects = projectsData?.data?.data?.result || []; - if (!projects) return []; + const projects = projectsData?.data?.data || projectsData?.data || []; + if (!Array.isArray(projects)) return []; + return projects.filter((project) => { const matchesCategory = - activeCategory === "all" || project.category === activeCategory; + activeCategory === "all" || + (Array.isArray(project.category) + ? project.category.some( + (cat: string) => + cat.toLowerCase() === activeCategory.toLowerCase() || + cat.toLowerCase().includes(activeCategory.toLowerCase()), + ) + : project.category?.toLowerCase() === activeCategory.toLowerCase()); + const normalizedSearch = deferredSearchQuery.trim().toLowerCase(); const matchesSearch = - searchQuery.trim() === "" || - project.title.toLowerCase().includes(searchQuery.toLowerCase()) || - project.description.toLowerCase().includes(searchQuery.toLowerCase()) || - project.technologies.some((tech: string) => - tech.toLowerCase().includes(searchQuery.toLowerCase()), - ); + normalizedSearch === "" || + project.title?.toLowerCase().includes(normalizedSearch) || + project.description?.toLowerCase().includes(normalizedSearch) || + (Array.isArray(project.technologies) && + project.technologies.some((tech: string) => + tech.toLowerCase().includes(normalizedSearch), + )); return matchesCategory && matchesSearch; }); - }, [projectsData, activeCategory, searchQuery]); + }, [projectsData, activeCategory, deferredSearchQuery]); return ( -
    - {/* Hero Section */} -
    -
    -
    -
    -
    - -
    - {/* Back Button */} +
    +
    +
    + + {/* Back Arrow Wrapper - Kept clean on left side */} - - - + + - {/* Header */} - -

    - Our Projects -

    -

    - Explore our portfolio of innovative solutions designed to scale - and transform businesses across industries. -

    -
    - - {/* Interactive Search and Filter Section */} - - {/* Search Bar */} -
    - - setSearchQuery(e.target.value)} - className="w-full pl-10 pr-4 py-2.5 rounded-full border border-border/50 bg-background/50 backdrop-blur-sm focus:outline-none focus:ring-2 focus:ring-primary/40 transition-all text-sm shadow-sm" - aria-label="Search projects" - /> + {/* Core Header Content Module - Flex-centered alignment */} +
    +
    + + All Projects + + + A high-fidelity showroom tracking production ecosystems, AI + operations, and cloud architectures compiled by Techzaa. +
    - {/* Filter Tabs */} -
    - {categories.map((category) => { - const Icon = category.icon; - const isActive = activeCategory === category.id; + {/* Interface Control Bar Matrix - Fully Centered Substructures */} + + {/* Search input container centralized down the layout grid */} +
    + + setSearchQuery(e.target.value)} + className="w-full pl-10 pr-4 py-2 text-sm rounded-xl border border-border bg-card/60 placeholder:text-muted-foreground/60 focus:outline-none focus:ring-2 focus:ring-primary/30 transition-all shadow-sm" + aria-label="Search deployment records" + /> +
    + + {/* Categories Tab Matrix - Wrapped with center axis parameters */} +
    + {CATEGORIES.map((cat) => { + const Icon = cat.icon; + const isActive = activeCategory === cat.id; + + return ( + + ); + })} +
    +
    +
    - return ( - - ); - })} -
    -
    - {/* Projects Grid */} -
    -
    - {/* Loading / Error State */} + {/* Projects View Output Section */} +
    +
    {isLoading && ( -
    - - Loading projects... +
    + {[...Array(6)].map((_, idx) => ( +
    +
    +
    +
    +
    +
    +
    +
    + ))}
    )} {isError && ( -
    -

    - Failed to load projects. +

    +

    + API Synchronization Failure

    -

    - Please check your network connection or try again later. +

    + Could not safely sync target records from Techzaa's data layer + cluster. Confirm connection status parameters.

    )} {!isLoading && !isError && ( - - - {filteredProjects.map((project) => ( - -
    - {/* Project Image */} -
    - {project.title} -
    - - {/* Category Badge */} -
    - - { - categories.find( - (c) => c.id === project.category, - )?.name - } - -
    - - {/* Quick External Links */} -
    - {project.liveUrl && ( - - - - )} - {project.githubUrl && ( - - - - )} -
    -
    - - {/* Title & Description */} -
    -
    - {project.client} - - {project.year} -
    - -

    - - {project.title} - -

    - -

    - {project.description} -

    -
    -
    - - {/* Technologies and Detail Navigation */} -
    -
    - {project.technologies - .slice(0, 5) - .map((tech: string) => ( - - {tech} - - ))} - {project.technologies.length > 5 && ( - - +{project.technologies.length - 5} - - )} -
    - -
    - - - -
    -
    - - ))} - + + {filteredProjects.length > 0 ? ( + + {filteredProjects.map((project, idx) => ( + + + + ))} + + ) : ( + + +

    + No Projects Located +

    +

    + Your lookup parameter variations produced zero operational + matches in our architecture records. +

    +
    + )}
    )} - - {/* Empty State */} - {!isLoading && !isError && filteredProjects.length === 0 && ( - -

    - No projects match your current search or category. -

    -
    - )}
    ); -} +} \ No newline at end of file