feat:change all section color
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { motion, useInView } from "framer-motion";
|
import { motion, useInView } from "framer-motion";
|
||||||
import { Award, Rocket, Users, Zap } from "lucide-react";
|
import { Award, Rocket, Users, Zap } from "lucide-react";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
const stats = [
|
const stats = [
|
||||||
{ icon: Zap, value: 10, suffix: "+", label: "Years Experience" },
|
{ icon: Zap, value: 10, suffix: "+", label: "Years Experience" },
|
||||||
@@ -41,7 +42,7 @@ function AnimatedCounter({
|
|||||||
}, [isInView, value]);
|
}, [isInView, value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="text-4xl md:text-5xl font-bold text-primary neon-text-glow">
|
<span className="text-4xl md:text-5xl font-bold text-primary">
|
||||||
{count}
|
{count}
|
||||||
{suffix}
|
{suffix}
|
||||||
</span>
|
</span>
|
||||||
@@ -66,11 +67,9 @@ export default function AboutSection() {
|
|||||||
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
||||||
transition={{ duration: 0.6 }}
|
transition={{ duration: 0.6 }}
|
||||||
>
|
>
|
||||||
<span className="inline-block px-4 py-1.5 rounded-full glass text-sm font-medium text-primary mb-4">
|
<PremiumBadge text="About Us" />
|
||||||
About Us
|
|
||||||
</span>
|
|
||||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-6">
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-6">
|
||||||
About <span className="text-primary neon-text-glow">TechZaa</span>
|
About <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">TechZaa</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div className="space-y-4 text-muted-foreground text-lg">
|
<div className="space-y-4 text-muted-foreground text-lg">
|
||||||
<p>
|
<p>
|
||||||
@@ -97,7 +96,7 @@ export default function AboutSection() {
|
|||||||
(value) => (
|
(value) => (
|
||||||
<span
|
<span
|
||||||
key={value}
|
key={value}
|
||||||
className="px-4 py-2 rounded-full glass neon-glow text-sm font-medium hover:border-primary border transition-all cursor-default"
|
className="px-4 py-2 glass neon-glow text-sm font-medium hover:border-primary border rounded-md transition-all cursor-default "
|
||||||
>
|
>
|
||||||
{value}
|
{value}
|
||||||
</span>
|
</span>
|
||||||
@@ -119,10 +118,10 @@ export default function AboutSection() {
|
|||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
animate={isInView ? { opacity: 1, y: 0 } : {}}
|
||||||
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
||||||
className="p-6 rounded-2xl bg-primary/5 hover:neon-glow transition-all text-center group"
|
className="p-6 rounded-2xl hover:border transition-all text-center group shadow-sm shadow-primary"
|
||||||
>
|
>
|
||||||
{/* Icon */}
|
{/* Icon */}
|
||||||
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center mx-auto mb-4 group-hover:neon-glow transition-all">
|
<div className="w-12 h-12 rounded-xl bg-blend-lighten flex items-center justify-center mx-auto mb-4 neon-glow transition-all">
|
||||||
<stat.icon className="w-6 h-6 text-primary" />
|
<stat.icon className="w-6 h-6 text-primary" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useBlogs } from "@/hooks/queires/useBlogs";
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
|
import { ArrowRight, Calendar, Clock, User } from "lucide-react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
const containerVariants = {
|
const containerVariants = {
|
||||||
hidden: { opacity: 0 },
|
hidden: { opacity: 0 },
|
||||||
@@ -41,11 +42,13 @@ export default function BlogSection() {
|
|||||||
transition={{ duration: 0.6 }}
|
transition={{ duration: 0.6 }}
|
||||||
className="text-center mb-16"
|
className="text-center mb-16"
|
||||||
>
|
>
|
||||||
<span className="inline-block px-4 py-2 rounded-full glass text-primary text-sm font-medium mb-4">
|
<PremiumBadge text="Latest Insights" />
|
||||||
Latest Insights
|
|
||||||
</span>
|
|
||||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||||
News & <span className="text-primary neon-text-glow">Blog</span>
|
News &{" "}
|
||||||
|
<span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-sidebar-primary">
|
||||||
|
Blog
|
||||||
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Stay updated with the latest trends, insights, and thought
|
Stay updated with the latest trends, insights, and thought
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default function ContactModal({ isOpen, onClose }: ContactModalProps) {
|
|||||||
delay: 0.2,
|
delay: 0.2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CheckCircle className="w-20 h-20 text-primary mx-auto mb-4 neon-text-glow" />
|
<CheckCircle className="w-20 h-20 text-primary mx-auto mb-4" />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<h3 className="text-2xl font-bold mb-2">Message Sent!</h3>
|
<h3 className="text-2xl font-bold mb-2">Message Sent!</h3>
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Textarea } from "@/components/ui/textarea";
|
|||||||
import { motion, useInView } from "framer-motion";
|
import { motion, useInView } from "framer-motion";
|
||||||
import { CheckCircle, Mail, MapPin, Phone, Send } from "lucide-react";
|
import { CheckCircle, Mail, MapPin, Phone, Send } from "lucide-react";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
const contactInfo = [
|
const contactInfo = [
|
||||||
{ icon: Mail, label: "Email", value: "techzaa.alpha@gmail.com" },
|
{ icon: Mail, label: "Email", value: "techzaa.alpha@gmail.com" },
|
||||||
@@ -91,11 +92,10 @@ export default function ContactSection() {
|
|||||||
transition={{ duration: 0.7 }}
|
transition={{ duration: 0.7 }}
|
||||||
className="text-center mb-20"
|
className="text-center mb-20"
|
||||||
>
|
>
|
||||||
<span className="inline-block px-5 py-2 rounded-full glass text-sm font-medium text-primary mb-4 tracking-widest">
|
|
||||||
LET'S CONNECT
|
<PremiumBadge text="Let's talk"/>
|
||||||
</span>
|
<h2 className="text-4xl md:text-5xl font-bold">
|
||||||
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">
|
Get In <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">Touch</span>
|
||||||
Get In <span className="text-primary neon-text-glow">Touch</span>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Ready to bring your vision to life? Drop us a message.
|
Ready to bring your vision to life? Drop us a message.
|
||||||
@@ -178,7 +178,7 @@ export default function ContactSection() {
|
|||||||
animate={{ opacity: 1, scale: 1 }}
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
className="text-center py-16"
|
className="text-center py-16"
|
||||||
>
|
>
|
||||||
<CheckCircle className="w-24 h-24 text-primary mx-auto mb-6 neon-text-glow" />
|
<CheckCircle className="w-24 h-24 text-primary mx-auto mb-6" />
|
||||||
<h3 className="text-3xl font-bold mb-3">
|
<h3 className="text-3xl font-bold mb-3">
|
||||||
Message Sent Successfully!
|
Message Sent Successfully!
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import {
|
|||||||
AccordionTrigger,
|
AccordionTrigger,
|
||||||
} from "@/components/ui/accordion";
|
} from "@/components/ui/accordion";
|
||||||
import { motion, useInView, useScroll, useSpring } from "framer-motion";
|
import { motion, useInView, useScroll, useSpring } from "framer-motion";
|
||||||
import { ArrowUpRight, ShieldQuestion, Sparkles } from "lucide-react";
|
import { Sparkles } from "lucide-react";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
const faqs = [
|
const faqs = [
|
||||||
{
|
{
|
||||||
@@ -61,18 +62,11 @@ export default function FAQSection() {
|
|||||||
<div className="mx-auto px-6 max-w-6xl">
|
<div className="mx-auto px-6 max-w-6xl">
|
||||||
<div className="flex flex-col gap-10">
|
<div className="flex flex-col gap-10">
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<div className="flex items-center gap-2 mb-6">
|
<PremiumBadge text="Got Questions?" />
|
||||||
<div className="p-2 bg-primary rounded-lg text-primary-foreground">
|
|
||||||
<ShieldQuestion size={20} />
|
|
||||||
</div>
|
|
||||||
<span className="text-sm font-bold uppercase text-primary/80">
|
|
||||||
Got Questions?
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2 className="text-4xl md:text-5xl font-bold">
|
<h2 className="text-4xl md:text-5xl font-bold">
|
||||||
Clear Answers {" "}
|
Clear Answers{" "}{" "}
|
||||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-primary-foreground">
|
<span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">
|
||||||
For Big Ideas.
|
For Big Ideas.
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
@@ -139,7 +133,6 @@ export default function FAQSection() {
|
|||||||
<AccordionContent className="px-6 pb-8 md:pl-[104px]">
|
<AccordionContent className="px-6 pb-8 md:pl-[104px]">
|
||||||
<div className="text-muted-foreground text-base md:text-lg leading-relaxed max-w-2xl border-l-2 border-primary/20 pl-6">
|
<div className="text-muted-foreground text-base md:text-lg leading-relaxed max-w-2xl border-l-2 border-primary/20 pl-6">
|
||||||
{faq.answer}
|
{faq.answer}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export default function HeroSection() {
|
|||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ delay: 0.5 }}
|
transition={{ delay: 0.5 }}
|
||||||
className="block text-primary"
|
className="block text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground"
|
||||||
>
|
>
|
||||||
with Technology
|
with Technology
|
||||||
</motion.span>
|
</motion.span>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { ArrowRight } from "lucide-react";
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { ProjectCard } from "./ProjectCard";
|
import { ProjectCard } from "./ProjectCard";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
const gradientColors = [
|
const gradientColors = [
|
||||||
"from-neon-blue/90",
|
"from-neon-blue/90",
|
||||||
@@ -49,12 +50,9 @@ export default function ProjectsSection() {
|
|||||||
transition={{ duration: 0.7 }}
|
transition={{ duration: 0.7 }}
|
||||||
className="text-center mb-20"
|
className="text-center mb-20"
|
||||||
>
|
>
|
||||||
<span className="inline-block px-5 py-2 rounded-full glass text-sm font-medium text-primary mb-4 tracking-widest">
|
<PremiumBadge text="our projects"/>
|
||||||
OUR PORTFOLIO
|
|
||||||
</span>
|
|
||||||
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6">
|
||||||
Featured{" "}
|
Featured <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">Projects</span>
|
||||||
<span className="text-primary neon-text-glow">Projects</span>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Crafted with passion. Delivered with excellence.
|
Crafted with passion. Delivered with excellence.
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default function ServicesSection() {
|
|||||||
>
|
>
|
||||||
<PremiumBadge text="Our Expertise" />
|
<PremiumBadge text="Our Expertise" />
|
||||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4 mt-2">
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4 mt-2">
|
||||||
What We <span className="text-primary">Do</span>
|
What We <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">Do</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground text-lg leading-relaxed">
|
<p className="text-muted-foreground text-lg leading-relaxed">
|
||||||
We deliver comprehensive technology solutions that empower
|
We deliver comprehensive technology solutions that empower
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Swiper, SwiperSlide } from "swiper/react";
|
|||||||
|
|
||||||
import { useTeam } from "@/hooks/queires/useTeam";
|
import { useTeam } from "@/hooks/queires/useTeam";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import PremiumBadge from "./shared/PremiumBadge";
|
||||||
|
|
||||||
export default function TeamSection() {
|
export default function TeamSection() {
|
||||||
const { data: teamdata } = useTeam();
|
const { data: teamdata } = useTeam();
|
||||||
@@ -21,7 +22,7 @@ export default function TeamSection() {
|
|||||||
{/* Background decoration */}
|
{/* Background decoration */}
|
||||||
<div className="absolute inset-0 opacity-30">
|
<div className="absolute inset-0 opacity-30">
|
||||||
<div className="absolute top-0 right-1/4 w-72 h-72 bg-neon-purple/10 rounded-full blur-[120px]" />
|
<div className="absolute top-0 right-1/4 w-72 h-72 bg-neon-purple/10 rounded-full blur-[120px]" />
|
||||||
<div className="absolute bottom-0 left-1/4 w-64 h-64 bg-primary/10 rounded-full blur-[100px]" />
|
<div className="absolute bottom-0 left-1/4 w-64 h-64 bg-primary/10 rounded-full blur-xl" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="container mx-auto px-4 relative z-10">
|
<div className="container mx-auto px-4 relative z-10">
|
||||||
@@ -32,11 +33,9 @@ export default function TeamSection() {
|
|||||||
transition={{ duration: 0.6 }}
|
transition={{ duration: 0.6 }}
|
||||||
className="text-center mb-16"
|
className="text-center mb-16"
|
||||||
>
|
>
|
||||||
<span className="inline-block px-4 py-1.5 rounded-full glass text-sm font-medium text-primary mb-4">
|
<PremiumBadge text="Our experts"/>
|
||||||
The Experts
|
|
||||||
</span>
|
|
||||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-4">
|
||||||
Meet Our <span className="text-primary neon-text-glow">Team</span>
|
Meet Our <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">Team</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
A passionate team of innovators, designers, and developers.
|
A passionate team of innovators, designers, and developers.
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ export default function TestimonialsSection() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="testimonials" className="py-24 relative overflow-hidden">
|
<section id="testimonials" className="py-24 relative overflow-hidden">
|
||||||
|
|
||||||
|
|
||||||
<div className="container mx-auto px-4 relative z-10">
|
<div className="container mx-auto px-4 relative z-10">
|
||||||
{/* Section Header */}
|
{/* Section Header */}
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -56,8 +54,7 @@ export default function TestimonialsSection() {
|
|||||||
Client Stories
|
Client Stories
|
||||||
</span>
|
</span>
|
||||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||||
What Our{" "}
|
What Our <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent-foreground">Clients Say</span>
|
||||||
<span className="text-primary neon-text-glow">Clients Say</span>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Don't just take our word for it - hear from the amazing companies
|
Don't just take our word for it - hear from the amazing companies
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ export default function Blog() {
|
|||||||
className="text-center mb-12"
|
className="text-center mb-12"
|
||||||
>
|
>
|
||||||
<h1 className="text-5xl md:text-6xl font-bold mb-6">
|
<h1 className="text-5xl md:text-6xl font-bold mb-6">
|
||||||
Our <span className="text-primary neon-text-glow">Blog</span>
|
Our <span className="text-primary">Blog</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
<p className="text-muted-foreground max-w-2xl mx-auto text-lg">
|
||||||
Insights, tutorials, and thought leadership from our team of
|
Insights, tutorials, and thought leadership from our team of
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { T_projects } from "@/types/projects.type";
|
import { T_projects } from "@/types/projects.type";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
export const EditProjectModal = ({
|
export const EditProjectModal = ({
|
||||||
project,
|
project,
|
||||||
onClose,
|
onClose,
|
||||||
onSave
|
onSave,
|
||||||
}: {
|
}: {
|
||||||
project: T_projects;
|
project: T_projects;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: (data: Partial<T_projects>) => void
|
onSave: (data: Partial<T_projects>) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
name: project.name,
|
name: project.name,
|
||||||
@@ -25,38 +25,53 @@ export const EditProjectModal = ({
|
|||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
||||||
<div className="glass-strong w-full max-w-md p-8 rounded-2xl shadow-2xl relative">
|
<div className="glass-strong w-full max-w-md p-8 rounded-2xl shadow-2xl relative">
|
||||||
<button onClick={onClose} className="absolute top-4 right-4 text-muted-foreground hover:text-foreground">
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
className="absolute top-4 right-4 text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
<X size={24} />
|
<X size={24} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h2 className="text-2xl font-bold mb-6 neon-text-glow">Edit Project</h2>
|
<h2 className="text-2xl font-bold mb-6">Edit Project</h2>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="space-y-4">
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="text-sm font-medium mb-1 block">Project Title</label>
|
<label className="text-sm font-medium mb-1 block">
|
||||||
|
Project Title
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none"
|
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none"
|
||||||
value={formData.name}
|
value={formData.name}
|
||||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
onChange={(e) =>
|
||||||
|
setFormData({ ...formData, name: e.target.value })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="text-sm font-medium mb-1 block">Short Description</label>
|
<label className="text-sm font-medium mb-1 block">
|
||||||
|
Short Description
|
||||||
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none h-24"
|
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none h-24"
|
||||||
value={formData.shortDescription}
|
value={formData.shortDescription}
|
||||||
onChange={(e) => setFormData({ ...formData, shortDescription: e.target.value })}
|
onChange={(e) =>
|
||||||
|
setFormData({ ...formData, shortDescription: e.target.value })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="text-sm font-medium mb-1 block">Preview URL</label>
|
<label className="text-sm font-medium mb-1 block">
|
||||||
|
Preview URL
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none"
|
className="w-full bg-background border border-border p-2.5 rounded-lg focus:ring-2 focus:ring-primary outline-none"
|
||||||
value={formData.previewUrl}
|
value={formData.previewUrl}
|
||||||
onChange={(e) => setFormData({ ...formData, previewUrl: e.target.value })}
|
onChange={(e) =>
|
||||||
|
setFormData({ ...formData, previewUrl: e.target.value })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="w-full py-3 bg-primary text-primary-foreground font-bold rounded-lg mt-4 neon-glow hover:neon-glow-strong transition-all"
|
className="w-full py-3 bg-primary text-primary-foreground font-bold rounded-lg mt-4 neon-glow hover:neon-glow-strong transition-all"
|
||||||
@@ -67,4 +82,4 @@ export const EditProjectModal = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,24 +1,33 @@
|
|||||||
|
import {
|
||||||
|
useDeleteProject,
|
||||||
|
useProjects,
|
||||||
|
useUpdateProject,
|
||||||
|
} from "@/hooks/queires/useProjects";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useProjects, useUpdateProject, useDeleteProject } from "@/hooks/queires/useProjects";
|
|
||||||
|
|
||||||
import { T_projects } from "@/types/projects.type";
|
import { T_projects } from "@/types/projects.type";
|
||||||
import { ProjectCard } from "./ProjectCard";
|
|
||||||
import { EditProjectModal } from "./EditProjectModal";
|
import { EditProjectModal } from "./EditProjectModal";
|
||||||
|
import { ProjectCard } from "./ProjectCard";
|
||||||
|
|
||||||
export default function ManageProject() {
|
export default function ManageProject() {
|
||||||
const { data: projectsData, isLoading } = useProjects();
|
const { data: projectsData, isLoading } = useProjects();
|
||||||
const updateMutation = useUpdateProject();
|
const updateMutation = useUpdateProject();
|
||||||
const deleteMutation = useDeleteProject();
|
const deleteMutation = useDeleteProject();
|
||||||
|
|
||||||
const [selectedProject, setSelectedProject] = useState<T_projects | null>(null);
|
const [selectedProject, setSelectedProject] = useState<T_projects | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
const projects: T_projects[] = projectsData?.data?.data?.result || [];
|
const projects: T_projects[] = projectsData?.data?.data?.result || [];
|
||||||
|
|
||||||
const handleUpdate = (data: Partial<T_projects>) => {
|
const handleUpdate = (data: Partial<T_projects>) => {
|
||||||
if (selectedProject) {
|
if (selectedProject) {
|
||||||
updateMutation.mutate({ id: selectedProject.id, data }, {
|
updateMutation.mutate(
|
||||||
onSuccess: () => setSelectedProject(null)
|
{ id: selectedProject.id, data },
|
||||||
});
|
{
|
||||||
|
onSuccess: () => setSelectedProject(null),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,33 +37,38 @@ export default function ManageProject() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isLoading) return <div className="p-10 text-center animate-pulse">Loading Projects...</div>;
|
if (isLoading)
|
||||||
|
return (
|
||||||
|
<div className="p-10 text-center animate-pulse">Loading Projects...</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-8 max-w-5xl mx-auto">
|
<div className="p-8 max-w-5xl mx-auto">
|
||||||
<header className="mb-10">
|
<header className="mb-10">
|
||||||
<h1 className="text-4xl font-extrabold neon-text-glow">Manage Projects</h1>
|
<h1 className="text-4xl font-extrabold">Manage Projects</h1>
|
||||||
<p className="text-muted-foreground">Edit, update or remove your portfolio items.</p>
|
<p className="text-muted-foreground">
|
||||||
|
Edit, update or remove your portfolio items.
|
||||||
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 gap-6">
|
<div className="grid grid-cols-1 gap-6">
|
||||||
{projects.map((item) => (
|
{projects.map((item) => (
|
||||||
<ProjectCard
|
<ProjectCard
|
||||||
key={item.id}
|
key={item.id}
|
||||||
project={item}
|
project={item}
|
||||||
onEdit={setSelectedProject}
|
onEdit={setSelectedProject}
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedProject && (
|
{selectedProject && (
|
||||||
<EditProjectModal
|
<EditProjectModal
|
||||||
project={selectedProject}
|
project={selectedProject}
|
||||||
onClose={() => setSelectedProject(null)}
|
onClose={() => setSelectedProject(null)}
|
||||||
onSave={handleUpdate}
|
onSave={handleUpdate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user