feat: update all sections
This commit is contained in:
parent
72cdecfdea
commit
a38936fb9a
8 changed files with 212 additions and 54 deletions
103
app/components/business-section.tsx
Normal file
103
app/components/business-section.tsx
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Globe, Instagram, Facebook } from "lucide-react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
interface Business {
|
||||
_id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
established: string;
|
||||
description: string;
|
||||
url?: string;
|
||||
logo?: string;
|
||||
instagramUrl?: string;
|
||||
websiteUrl?: string;
|
||||
facebookUrl?: string;
|
||||
tiktokUrl?: string;
|
||||
}
|
||||
|
||||
interface BusinessSectionProps {
|
||||
businesses: Business[];
|
||||
}
|
||||
|
||||
export function BusinessSection({ businesses = [] }: BusinessSectionProps) {
|
||||
return (
|
||||
<section id="businesses" className="py-20">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-4xl font-bold text-center mb-16">Businesses</h2>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-8">
|
||||
{businesses.map((business) => (
|
||||
<Card
|
||||
key={business._id}
|
||||
className="hover:shadow-lg transition-shadow"
|
||||
>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
{business.name}
|
||||
<Badge variant="secondary">Est. {business.established}</Badge>
|
||||
</CardTitle>
|
||||
<div className="text-sm text-foreground mb-1">
|
||||
{business.role}
|
||||
</div>
|
||||
<CardDescription className="leading-relaxed">
|
||||
{business.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<div className="flex gap-3 pt-2">
|
||||
{business.instagramUrl && (
|
||||
<a
|
||||
href={business.instagramUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Instagram"
|
||||
>
|
||||
<Instagram className="w-5 h-5 text-pink-500" />
|
||||
</a>
|
||||
)}
|
||||
{business.websiteUrl && (
|
||||
<a
|
||||
href={business.websiteUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Website"
|
||||
>
|
||||
<Globe className="w-5 h-5 text-blue-500" />
|
||||
</a>
|
||||
)}
|
||||
{business.facebookUrl && (
|
||||
<a
|
||||
href={business.facebookUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Facebook"
|
||||
>
|
||||
<Facebook className="w-5 h-5 text-blue-700" />
|
||||
</a>
|
||||
)}
|
||||
{business.tiktokUrl && (
|
||||
<a
|
||||
href={business.tiktokUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="TikTok"
|
||||
>
|
||||
{/* <Tiktok className="w-5 h-5 text-black" /> */}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ interface ContactSectionProps {
|
|||
email: string;
|
||||
phone?: string;
|
||||
location: string;
|
||||
githubUrl?: string;
|
||||
githubUrl?: string[];
|
||||
linkedinUrl?: string;
|
||||
};
|
||||
}
|
||||
|
|
@ -34,32 +34,36 @@ export function ContactSection({ profile }: ContactSectionProps) {
|
|||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="grid gap-4">
|
||||
<div className="flex items-center space-x-3 p-3 rounded-lg bg-muted/50">
|
||||
<a
|
||||
href={`mailto:${profile.email}`}
|
||||
className="flex items-center space-x-3 p-3 rounded-lg bg-muted/50 hover:bg-muted transition-colors ring-0 hover:ring-2 hover:ring-primary/40 focus:outline-none focus:ring-2 focus:ring-primary/60"
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<Mail className="h-5 w-5 text-primary" />
|
||||
<div>
|
||||
<p className="font-medium">Email</p>
|
||||
<a
|
||||
href={`mailto:${profile.email}`}
|
||||
className="text-muted-foreground hover:text-primary transition-colors"
|
||||
>
|
||||
<span className="text-muted-foreground hover:text-primary transition-colors">
|
||||
{profile.email}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{profile.phone && (
|
||||
<div className="flex items-center space-x-3 p-3 rounded-lg bg-muted/50">
|
||||
<a
|
||||
href={`https://wa.me/${profile.phone.replace(/\s+/g, "")}`}
|
||||
className="flex items-center space-x-3 p-3 rounded-lg bg-muted/50 hover:bg-muted transition-colors ring-0 hover:ring-2 hover:ring-primary/40 focus:outline-none focus:ring-2 focus:ring-primary/60"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<Phone className="h-5 w-5 text-primary" />
|
||||
<div>
|
||||
<p className="font-medium">Phone</p>
|
||||
<a
|
||||
href={`tel:${profile.phone}`}
|
||||
className="text-muted-foreground hover:text-primary transition-colors"
|
||||
>
|
||||
<span className="text-muted-foreground hover:text-primary transition-colors">
|
||||
{profile.phone}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
)}
|
||||
|
||||
<div className="flex items-center space-x-3 p-3 rounded-lg bg-muted/50">
|
||||
|
|
@ -72,17 +76,31 @@ export function ContactSection({ profile }: ContactSectionProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex justify-center space-x-4 pt-6">
|
||||
{profile.githubUrl && (
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
<a
|
||||
href={profile.githubUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-5 w-5" />
|
||||
GitHub
|
||||
</a>
|
||||
</Button>
|
||||
{profile.githubUrl && profile.githubUrl.length > 0 && (
|
||||
<>
|
||||
<Button asChild>
|
||||
<a
|
||||
href={profile.githubUrl[0]}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-4 w-4" />
|
||||
GitHub (Main)
|
||||
</a>
|
||||
</Button>
|
||||
{profile.githubUrl[1] && (
|
||||
<Button asChild variant="outline">
|
||||
<a
|
||||
href={profile.githubUrl[1]}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-4 w-4" />
|
||||
GitHub (Alt)
|
||||
</a>
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{profile.linkedinUrl && (
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
|
|
@ -96,12 +114,6 @@ export function ContactSection({ profile }: ContactSectionProps) {
|
|||
</a>
|
||||
</Button>
|
||||
)}
|
||||
<Button size="lg" asChild>
|
||||
<a href={`mailto:${profile.email}`}>
|
||||
<Mail className="mr-2 h-5 w-5" />
|
||||
Send Email
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ interface Experience {
|
|||
company: string;
|
||||
position: string;
|
||||
duration: string;
|
||||
description: string;
|
||||
description: string[];
|
||||
technologies: string[];
|
||||
current: boolean;
|
||||
}
|
||||
|
|
@ -51,7 +51,11 @@ export function ExperienceSection({ experiences }: ExperienceSectionProps) {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-muted-foreground mb-4 leading-relaxed">
|
||||
{exp.description}
|
||||
<ul className="list-disc list-inside space-y-1">
|
||||
{exp.description.map((item, idx) => (
|
||||
<li key={idx}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{exp.technologies.map((tech) => (
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Github, Linkedin, Mail, MapPin, Phone } from "lucide-react";
|
||||
import avatar from "@/assets/avatar.png";
|
||||
|
||||
interface HeroSectionProps {
|
||||
profile: {
|
||||
name: string;
|
||||
title: string;
|
||||
bio: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
location: string;
|
||||
githubUrl?: string;
|
||||
githubUrl?: string[];
|
||||
linkedinUrl?: string;
|
||||
about?: {
|
||||
description: string[];
|
||||
technologies?: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +36,10 @@ export function HeroSection({ profile }: HeroSectionProps) {
|
|||
<div className="text-center">
|
||||
<div className="mb-8">
|
||||
<Avatar className="w-32 h-32 mx-auto mb-6">
|
||||
<AvatarImage
|
||||
src={avatar}
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
/>
|
||||
<AvatarFallback className="text-4xl font-bold bg-gradient-to-br from-primary to-primary/80 text-primary-foreground">
|
||||
{profile.name
|
||||
.split(" ")
|
||||
|
|
@ -46,22 +54,40 @@ export function HeroSection({ profile }: HeroSectionProps) {
|
|||
{profile.title}
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed">
|
||||
{profile.bio}
|
||||
{profile.about?.description?.map((desc, idx) => (
|
||||
<span key={idx} className={idx > 0 ? "block mt-2" : undefined}>
|
||||
{desc}
|
||||
</span>
|
||||
))}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap justify-center gap-4 mb-8">
|
||||
{profile.githubUrl && (
|
||||
<Button asChild>
|
||||
<a
|
||||
href={profile.githubUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-4 w-4" />
|
||||
GitHub
|
||||
</a>
|
||||
</Button>
|
||||
{profile.githubUrl && profile.githubUrl.length > 0 && (
|
||||
<>
|
||||
<Button asChild>
|
||||
<a
|
||||
href={profile.githubUrl[0]}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-4 w-4" />
|
||||
GitHub (Main)
|
||||
</a>
|
||||
</Button>
|
||||
{profile.githubUrl[1] && (
|
||||
<Button asChild variant="outline">
|
||||
<a
|
||||
href={profile.githubUrl[1]}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Github className="mr-2 h-4 w-4" />
|
||||
GitHub (Alt)
|
||||
</a>
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{profile.linkedinUrl && (
|
||||
<Button asChild variant="outline">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,13 @@ export function Navigation({ profile }: NavigationProps) {
|
|||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const sections = ["about", "experience", "projects", "skills", "contact"];
|
||||
const sections = [
|
||||
"about",
|
||||
"experience",
|
||||
"projects",
|
||||
"businesses",
|
||||
"contact",
|
||||
];
|
||||
const scrollPosition = window.scrollY + 100;
|
||||
|
||||
for (const section of sections) {
|
||||
|
|
@ -46,7 +52,7 @@ export function Navigation({ profile }: NavigationProps) {
|
|||
<div className="flex justify-between items-center h-16">
|
||||
<div className="font-bold text-xl">{profile.name}</div>
|
||||
<div className="hidden md:flex space-x-2">
|
||||
{["about", "experience", "projects", "skills", "contact"].map(
|
||||
{["about", "experience", "projects", "businesses", "contact"].map(
|
||||
(section) => (
|
||||
<Button
|
||||
key={section}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ export function ProjectsSection({ projects }: ProjectsSectionProps) {
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
Live Demo
|
||||
Go to site
|
||||
</a>
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -143,7 +143,7 @@ export function ProjectsSection({ projects }: ProjectsSectionProps) {
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<ExternalLink className="mr-1 h-3 w-3" />
|
||||
Demo
|
||||
Go to site
|
||||
</a>
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue