Merge version_2 into main #6
150
src/app/page.tsx
150
src/app/page.tsx
@@ -5,51 +5,51 @@ import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloating
|
||||
import HeroLogo from '@/components/sections/hero/HeroLogo';
|
||||
import MetricSplitMediaAbout from '@/components/sections/about/MetricSplitMediaAbout';
|
||||
import ProductCardThree from '@/components/sections/product/ProductCardThree';
|
||||
import TeamCardSix from '@/components/sections/team/TeamCardSix';
|
||||
import TestimonialCardTwelve from '@/components/sections/testimonial/TestimonialCardTwelve';
|
||||
import MetricCardEleven from '@/components/sections/metrics/MetricCardEleven';
|
||||
import SocialProofOne from '@/components/sections/socialProof/SocialProofOne';
|
||||
import FooterBase from '@/components/sections/footer/FooterBase';
|
||||
import { Zap, Users, Award, Handshake, Github, Linkedin, Twitter } from "lucide-react";
|
||||
import { Zap, Users, Award, Handshake } from "lucide-react";
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function LandingPage() {
|
||||
const [flippedCards, setFlippedCards] = useState<{[key: string]: boolean}>({});
|
||||
const [flipped, setFlipped] = useState<{ [key: string]: boolean }>({});
|
||||
|
||||
const toggleFlip = (memberId: string) => {
|
||||
setFlippedCards(prev => ({
|
||||
setFlipped(prev => ({
|
||||
...prev,
|
||||
[memberId]: !prev[memberId]
|
||||
}));
|
||||
};
|
||||
|
||||
// Team members with social links
|
||||
const teamMembers = [
|
||||
{
|
||||
id: "1", name: "Alex Johnson", role: "Club President", imageSrc: "http://img.b2bpic.net/free-photo/happy-businessman-smiling-camera_1163-4660.jpg?_wi=1", imageAlt: "Alex Johnson, Club President", socials: [
|
||||
{ icon: Github, href: "https://github.com/alexjohnson", label: "GitHub" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/in/alexjohnson", label: "LinkedIn" },
|
||||
{ icon: Twitter, href: "https://twitter.com/alexjohnson", label: "Twitter" }
|
||||
{ icon: "linkedin", url: "https://linkedin.com/in/alexjohnson" },
|
||||
{ icon: "github", url: "https://github.com/alexjohnson" },
|
||||
{ icon: "twitter", url: "https://twitter.com/alexjohnson" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "2", name: "Sarah Chen", role: "VP of Projects", imageSrc: "http://img.b2bpic.net/free-photo/happy-businessman-smiling-camera_1163-4660.jpg?_wi=2", imageAlt: "Sarah Chen, VP of Projects", socials: [
|
||||
{ icon: Github, href: "https://github.com/sarahchen", label: "GitHub" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/in/sarahchen", label: "LinkedIn" },
|
||||
{ icon: Twitter, href: "https://twitter.com/sarahchen", label: "Twitter" }
|
||||
{ icon: "linkedin", url: "https://linkedin.com/in/sarahchen" },
|
||||
{ icon: "github", url: "https://github.com/sarahchen" },
|
||||
{ icon: "twitter", url: "https://twitter.com/sarahchen" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "3", name: "Marcus Williams", role: "Tech Lead", imageSrc: "http://img.b2bpic.net/free-photo/happy-businessman-smiling-camera_1163-4660.jpg?_wi=3", imageAlt: "Marcus Williams, Tech Lead", socials: [
|
||||
{ icon: Github, href: "https://github.com/marcuswilliams", label: "GitHub" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/in/marcuswilliams", label: "LinkedIn" },
|
||||
{ icon: Twitter, href: "https://twitter.com/marcuswilliams", label: "Twitter" }
|
||||
{ icon: "linkedin", url: "https://linkedin.com/in/marcuswilliams" },
|
||||
{ icon: "github", url: "https://github.com/marcuswilliams" },
|
||||
{ icon: "twitter", url: "https://twitter.com/marcuswilliams" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "4", name: "Emily Rodriguez", role: "Community Manager", imageSrc: "http://img.b2bpic.net/free-photo/happy-businessman-smiling-camera_1163-4660.jpg?_wi=4", imageAlt: "Emily Rodriguez, Community Manager", socials: [
|
||||
{ icon: Github, href: "https://github.com/emilyrodriguez", label: "GitHub" },
|
||||
{ icon: Linkedin, href: "https://linkedin.com/in/emilyrodriguez", label: "LinkedIn" },
|
||||
{ icon: Twitter, href: "https://twitter.com/emilyrodriguez", label: "Twitter" }
|
||||
{ icon: "linkedin", url: "https://linkedin.com/in/emilyrodriguez" },
|
||||
{ icon: "github", url: "https://github.com/emilyrodriguez" },
|
||||
{ icon: "twitter", url: "https://twitter.com/emilyrodriguez" }
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -137,85 +137,75 @@ export default function LandingPage() {
|
||||
</div>
|
||||
|
||||
<div id="team" data-section="team">
|
||||
<div className="w-full">
|
||||
<div className="mx-auto w-content-width px-vw-1_5">
|
||||
<div className="flex flex-col gap-vw-2 mb-vw-3">
|
||||
<div>
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-4 py-2 mb-4">
|
||||
<Users className="w-4 h-4" />
|
||||
<span className="text-sm font-medium text-foreground/70">Leadership</span>
|
||||
</div>
|
||||
<h2 className="text-5xl font-medium text-foreground mb-4">Meet Our Team</h2>
|
||||
<p className="text-foreground/70">The passionate individuals driving innovation and mentorship within CodeClub.</p>
|
||||
<div className="w-full py-20">
|
||||
<div className="w-full max-w-screen-2xl mx-auto px-4 md:px-8">
|
||||
<div className="mb-12">
|
||||
<div className="inline-flex items-center gap-2 mb-4">
|
||||
<Users className="w-5 h-5" />
|
||||
<span className="text-sm font-medium">Leadership</span>
|
||||
</div>
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-4">Meet Our Team</h2>
|
||||
<p className="text-lg text-foreground/80">The passionate individuals driving innovation and mentorship within CodeClub.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{teamMembers.map((member) => {
|
||||
const isFlipped = flippedCards[member.id];
|
||||
return (
|
||||
<div key={member.id} className="h-96">
|
||||
{teamMembers.map((member) => (
|
||||
<div
|
||||
key={member.id}
|
||||
className="h-96 cursor-pointer perspective"
|
||||
onClick={() => toggleFlip(member.id)}
|
||||
>
|
||||
<div
|
||||
className="relative w-full h-full transition-transform duration-500 transform-gpu"
|
||||
style={{
|
||||
transformStyle: 'preserve-3d',
|
||||
transform: flipped[member.id] ? 'rotateY(180deg)' : 'rotateY(0deg)'
|
||||
}}
|
||||
>
|
||||
{/* Front side - Image */}
|
||||
<div
|
||||
className="relative w-full h-full cursor-pointer transition-transform duration-500 transform-gpu"
|
||||
style={{
|
||||
transformStyle: 'preserve-3d',
|
||||
transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)'
|
||||
}}
|
||||
onClick={() => toggleFlip(member.id)}
|
||||
className="absolute w-full h-full bg-white rounded-lg shadow-lg p-4 flex flex-col items-center justify-center"
|
||||
style={{ backfaceVisibility: 'hidden' }}
|
||||
>
|
||||
{/* Front side - Profile */}
|
||||
<div
|
||||
className="absolute w-full h-full rounded-lg overflow-hidden bg-card border border-accent/20 flex flex-col items-end justify-end p-6 shadow-lg"
|
||||
style={{
|
||||
backfaceVisibility: 'hidden'
|
||||
}}
|
||||
>
|
||||
<div className="w-full h-64 mb-4 rounded-lg overflow-hidden">
|
||||
<img
|
||||
src={member.imageSrc}
|
||||
alt={member.imageAlt}
|
||||
className="absolute inset-0 w-full h-full object-cover"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/30 to-transparent" />
|
||||
<div className="relative z-10">
|
||||
<h3 className="text-xl font-semibold text-white">{member.name}</h3>
|
||||
<p className="text-sm text-white/80">{member.role}</p>
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-center">{member.name}</h3>
|
||||
<p className="text-sm text-foreground/60 text-center mt-2">{member.role}</p>
|
||||
<p className="text-xs text-foreground/50 text-center mt-4">Click to view social links</p>
|
||||
</div>
|
||||
|
||||
{/* Back side - Social Links */}
|
||||
<div
|
||||
className="absolute w-full h-full rounded-lg overflow-hidden bg-primary-cta border border-accent/20 flex flex-col items-center justify-center p-6 shadow-lg"
|
||||
style={{
|
||||
backfaceVisibility: 'hidden',
|
||||
transform: 'rotateY(180deg)'
|
||||
}}
|
||||
>
|
||||
<div className="text-center mb-6">
|
||||
<p className="text-white font-medium text-lg">Connect</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
{member.socials.map((social) => {
|
||||
const Icon = social.icon;
|
||||
return (
|
||||
<a
|
||||
key={social.label}
|
||||
href={social.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-3 px-4 py-3 rounded-lg bg-white/20 hover:bg-white/30 text-white transition-colors"
|
||||
title={social.label}
|
||||
>
|
||||
<Icon className="w-5 h-5" />
|
||||
<span className="text-sm font-medium">{social.label}</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{/* Back side - Social Links */}
|
||||
<div
|
||||
className="absolute w-full h-full bg-gradient-to-br from-primary-cta to-primary-cta/80 rounded-lg shadow-lg p-4 flex flex-col items-center justify-center"
|
||||
style={{
|
||||
backfaceVisibility: 'hidden',
|
||||
transform: 'rotateY(180deg)'
|
||||
}}
|
||||
>
|
||||
<h3 className="text-xl font-bold text-white mb-6 text-center">{member.name}</h3>
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
{member.socials.map((social, idx) => (
|
||||
<a
|
||||
key={idx}
|
||||
href={social.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-full py-3 px-4 bg-white/20 hover:bg-white/30 text-white rounded-lg text-center font-medium transition-colors capitalize"
|
||||
>
|
||||
{social.icon}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<p className="text-xs text-white/70 text-center mt-6">Click to flip back</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ interface ServiceWrapperProps {
|
||||
|
||||
export function ServiceWrapper({ children }: ServiceWrapperProps) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900">
|
||||
<div className="min-h-screen w-full bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
'use client';
|
||||
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
|
||||
interface SocialLink {
|
||||
platform: string;
|
||||
url: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
interface TeamMember {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
image: string;
|
||||
socialLinks: SocialLink[];
|
||||
}
|
||||
|
||||
interface TeamCardProps {
|
||||
member: TeamMember;
|
||||
interface ThemeProviderProps {
|
||||
children: ReactNode;
|
||||
defaultButtonVariant?: string;
|
||||
defaultTextAnimation?: string;
|
||||
borderRadius?: 'soft' | 'medium' | 'sharp';
|
||||
contentWidth?: 'small' | 'medium' | 'large';
|
||||
sizing?: string;
|
||||
background?: string;
|
||||
cardStyle?: string;
|
||||
primaryButtonStyle?: string;
|
||||
secondaryButtonStyle?: string;
|
||||
headingFontWeight?: string;
|
||||
}
|
||||
|
||||
interface ThemeContextType {
|
||||
@@ -35,141 +31,19 @@ interface ThemeContextType {
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
||||
|
||||
export function useTheme(): ThemeContextType {
|
||||
const context = useContext(ThemeContext);
|
||||
if (context === undefined) {
|
||||
return {
|
||||
defaultButtonVariant: 'text-stagger',
|
||||
defaultTextAnimation: 'entrance-slide',
|
||||
borderRadius: 'rounded',
|
||||
contentWidth: 'medium',
|
||||
sizing: 'medium',
|
||||
background: 'circleGradient',
|
||||
cardStyle: 'glass-elevated',
|
||||
primaryButtonStyle: 'gradient',
|
||||
secondaryButtonStyle: 'glass',
|
||||
headingFontWeight: 'normal'
|
||||
};
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
function TeamCard({ member }: TeamCardProps) {
|
||||
const [isFlipped, setIsFlipped] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="h-80 w-full cursor-pointer perspective bg-glass-elevated rounded-lg border border-accent/20"
|
||||
onMouseEnter={() => setIsFlipped(true)}
|
||||
onMouseLeave={() => setIsFlipped(false)}
|
||||
>
|
||||
<div
|
||||
className="relative w-full h-full transition-transform duration-500 transform-gpu"
|
||||
style={{
|
||||
transformStyle: 'preserve-3d',
|
||||
transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)',
|
||||
}}
|
||||
>
|
||||
{/* Front Side */}
|
||||
<div
|
||||
className="absolute w-full h-full bg-gradient-to-br from-slate-900 to-slate-800 rounded-lg p-6 flex flex-col items-center justify-center border border-slate-700"
|
||||
style={{ backfaceVisibility: 'hidden' }}
|
||||
>
|
||||
<div className="w-24 h-24 rounded-full bg-slate-700 mb-4 overflow-hidden flex items-center justify-center">
|
||||
<img
|
||||
src={member.image}
|
||||
alt={member.name}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-white text-center">
|
||||
{member.name}
|
||||
</h3>
|
||||
<p className="text-sm text-slate-400 text-center mt-2">
|
||||
{member.role}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Back Side */}
|
||||
<div
|
||||
className="absolute w-full h-full bg-gradient-to-br from-blue-900 to-blue-800 rounded-lg p-6 flex flex-col items-center justify-center border border-blue-700"
|
||||
style={{
|
||||
backfaceVisibility: 'hidden',
|
||||
transform: 'rotateY(180deg)',
|
||||
}}
|
||||
>
|
||||
<h4 className="text-white font-semibold mb-4 text-center">
|
||||
Connect
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-3 justify-center">
|
||||
{member.socialLinks.map((link) => (
|
||||
<a
|
||||
key={link.platform}
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-10 h-10 rounded-full bg-white bg-opacity-20 hover:bg-opacity-30 flex items-center justify-center transition-all duration-300 text-white text-sm font-bold"
|
||||
title={link.platform}
|
||||
>
|
||||
{link.icon}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ThemeProviderProps {
|
||||
children: React.ReactNode;
|
||||
defaultButtonVariant?: string;
|
||||
defaultTextAnimation?: string;
|
||||
borderRadius?: string;
|
||||
contentWidth?: string;
|
||||
sizing?: string;
|
||||
background?: string;
|
||||
cardStyle?: string;
|
||||
primaryButtonStyle?: string;
|
||||
secondaryButtonStyle?: string;
|
||||
headingFontWeight?: string;
|
||||
}
|
||||
|
||||
export function ThemeProvider({
|
||||
children,
|
||||
defaultButtonVariant,
|
||||
defaultTextAnimation,
|
||||
borderRadius,
|
||||
contentWidth,
|
||||
sizing,
|
||||
background,
|
||||
cardStyle,
|
||||
primaryButtonStyle,
|
||||
secondaryButtonStyle,
|
||||
headingFontWeight,
|
||||
defaultButtonVariant = 'default',
|
||||
defaultTextAnimation = 'none',
|
||||
borderRadius = 'medium',
|
||||
contentWidth = 'medium',
|
||||
sizing = 'medium',
|
||||
background = 'light',
|
||||
cardStyle = 'solid',
|
||||
primaryButtonStyle = 'solid',
|
||||
secondaryButtonStyle = 'outline',
|
||||
headingFontWeight = 'bold',
|
||||
}: ThemeProviderProps) {
|
||||
const backgroundClasses = {
|
||||
aurora: 'bg-gradient-to-br from-slate-950 via-purple-900 to-slate-950',
|
||||
light: 'bg-white',
|
||||
dark: 'bg-slate-900',
|
||||
};
|
||||
|
||||
const borderRadiusClasses = {
|
||||
soft: 'rounded-lg',
|
||||
sharp: 'rounded-none',
|
||||
smooth: 'rounded-2xl',
|
||||
};
|
||||
|
||||
const contentWidthClasses = {
|
||||
small: 'max-w-2xl',
|
||||
medium: 'max-w-6xl',
|
||||
large: 'max-w-7xl',
|
||||
};
|
||||
|
||||
const bgClass = backgroundClasses[background as keyof typeof backgroundClasses] || backgroundClasses.aurora;
|
||||
const radiusClass = borderRadiusClasses[borderRadius as keyof typeof borderRadiusClasses] || borderRadiusClasses.soft;
|
||||
const widthClass = contentWidthClasses[contentWidth as keyof typeof contentWidthClasses] || contentWidthClasses.medium;
|
||||
|
||||
const themeValue: ThemeContextType = {
|
||||
defaultButtonVariant,
|
||||
defaultTextAnimation,
|
||||
@@ -183,20 +57,30 @@ export function ThemeProvider({
|
||||
headingFontWeight,
|
||||
};
|
||||
|
||||
const borderRadiusClass = {
|
||||
soft: 'rounded-2xl',
|
||||
medium: 'rounded-lg',
|
||||
sharp: 'rounded-none',
|
||||
}[borderRadius] || 'rounded-lg';
|
||||
|
||||
const contentWidthClass = {
|
||||
small: 'max-w-2xl',
|
||||
medium: 'max-w-4xl',
|
||||
large: 'max-w-6xl',
|
||||
}[contentWidth] || 'max-w-4xl';
|
||||
|
||||
const backgroundClass = {
|
||||
aurora: 'bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900',
|
||||
light: 'bg-white',
|
||||
dark: 'bg-gray-900',
|
||||
}[background] || 'bg-white';
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={themeValue}>
|
||||
<div
|
||||
className={`${bgClass} min-h-screen transition-colors duration-300`}
|
||||
style={{
|
||||
'--default-button-variant': defaultButtonVariant,
|
||||
'--default-text-animation': defaultTextAnimation,
|
||||
'--card-style': cardStyle,
|
||||
'--primary-button-style': primaryButtonStyle,
|
||||
'--secondary-button-style': secondaryButtonStyle,
|
||||
'--heading-font-weight': headingFontWeight,
|
||||
} as React.CSSProperties}
|
||||
className={`${backgroundClass} ${borderRadiusClass} min-h-screen transition-colors duration-300`}
|
||||
>
|
||||
<div className={`${widthClass} mx-auto px-4 sm:px-6 lg:px-8`}>
|
||||
<div className={`${contentWidthClass} mx-auto px-4 sm:px-6 lg:px-8`}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,12 +88,10 @@ export function ThemeProvider({
|
||||
);
|
||||
}
|
||||
|
||||
export function TeamCardGrid({ members }: { members: TeamMember[] }) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 py-12">
|
||||
{members.map((member) => (
|
||||
<TeamCard key={member.id} member={member} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
export function useTheme(): ThemeContextType {
|
||||
const context = useContext(ThemeContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useTheme must be used within a ThemeProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
113
src/tag/Tag.tsx
113
src/tag/Tag.tsx
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
'use client';
|
||||
|
||||
import { useState } from "react";
|
||||
import { useState } from 'react';
|
||||
|
||||
interface TeamMember {
|
||||
id: string;
|
||||
@@ -39,25 +39,26 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
{members.map((member) => (
|
||||
<div
|
||||
key={member.id}
|
||||
className="h-80 cursor-pointer perspective bg-glass-elevated rounded-lg border border-accent/20"
|
||||
className="h-80 cursor-pointer perspective"
|
||||
onClick={() => toggleFlip(member.id)}
|
||||
>
|
||||
<div
|
||||
className="relative w-full h-full transition-transform duration-500 transform-gpu"
|
||||
style={{
|
||||
transformStyle: "preserve-3d", transform: flipped[member.id]
|
||||
? "rotateY(180deg)"
|
||||
: "rotateY(0deg)"
|
||||
transformStyle: 'preserve-3d',
|
||||
transform: flipped[member.id]
|
||||
? 'rotateY(180deg)'
|
||||
: 'rotateY(0deg)',
|
||||
}}
|
||||
>
|
||||
{/* Front Side */}
|
||||
<div
|
||||
className="absolute w-full h-full bg-white rounded-lg shadow-lg p-6 flex flex-col items-center justify-center"
|
||||
className="absolute w-full h-full bg-white rounded-lg shadow-lg overflow-hidden flex flex-col items-center justify-center p-6"
|
||||
style={{
|
||||
backfaceVisibility: "hidden"
|
||||
backfaceVisibility: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div className="w-32 h-32 mb-4 rounded-full overflow-hidden bg-gray-200">
|
||||
<div className="w-32 h-32 mb-4 rounded-full overflow-hidden bg-gray-200 flex-shrink-0">
|
||||
<img
|
||||
src={member.image}
|
||||
alt={member.name}
|
||||
@@ -68,18 +69,21 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
{member.name}
|
||||
</h3>
|
||||
<p className="text-gray-600 text-center mt-2">{member.role}</p>
|
||||
<p className="text-sm text-gray-400 mt-4">Hover to see links</p>
|
||||
<p className="text-sm text-gray-400 mt-4 text-center">
|
||||
Hover to see social links
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Back Side */}
|
||||
<div
|
||||
className="absolute w-full h-full bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg shadow-lg p-6 flex flex-col items-center justify-center"
|
||||
className="absolute w-full h-full bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg shadow-lg overflow-hidden flex flex-col items-center justify-center p-6"
|
||||
style={{
|
||||
backfaceVisibility: "hidden", transform: "rotateY(180deg)"
|
||||
backfaceVisibility: 'hidden',
|
||||
transform: 'rotateY(180deg)',
|
||||
}}
|
||||
>
|
||||
<h3 className="text-2xl font-bold text-white mb-6 text-center">
|
||||
{member.name}
|
||||
Connect
|
||||
</h3>
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
{member.social.twitter && (
|
||||
@@ -89,8 +93,14 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white py-2 px-4 rounded-lg transition-all duration-200"
|
||||
>
|
||||
<span>𝕏</span>
|
||||
<span>Twitter</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2s9 5 20 5a9.5 9.5 0 00-9-5.5c4.75 2.25 9-1 9-5.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z" />
|
||||
</svg>
|
||||
Twitter
|
||||
</a>
|
||||
)}
|
||||
{member.social.linkedin && (
|
||||
@@ -100,8 +110,15 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white py-2 px-4 rounded-lg transition-all duration-200"
|
||||
>
|
||||
<span>in</span>
|
||||
<span>LinkedIn</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z" />
|
||||
<circle cx="4" cy="4" r="2" />
|
||||
</svg>
|
||||
LinkedIn
|
||||
</a>
|
||||
)}
|
||||
{member.social.github && (
|
||||
@@ -111,8 +128,14 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white py-2 px-4 rounded-lg transition-all duration-200"
|
||||
>
|
||||
<span>⚙</span>
|
||||
<span>GitHub</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v 3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
</svg>
|
||||
GitHub
|
||||
</a>
|
||||
)}
|
||||
{member.social.email && (
|
||||
@@ -120,8 +143,20 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
href={`mailto:${member.social.email}`}
|
||||
className="flex items-center justify-center gap-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white py-2 px-4 rounded-lg transition-all duration-200"
|
||||
>
|
||||
<span>✉</span>
|
||||
<span>Email</span>
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
Email
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@@ -137,21 +172,39 @@ export default function Tag({ members = defaultMembers }: TagProps) {
|
||||
|
||||
const defaultMembers: TeamMember[] = [
|
||||
{
|
||||
id: "1", name: "Sarah Johnson", role: "Lead Designer", image:
|
||||
"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&h=400&fit=crop", social: {
|
||||
twitter: "https://twitter.com", linkedin: "https://linkedin.com", email: "sarah@example.com"
|
||||
id: '1',
|
||||
name: 'Sarah Johnson',
|
||||
role: 'Lead Designer',
|
||||
image:
|
||||
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&h=400&fit=crop',
|
||||
social: {
|
||||
twitter: 'https://twitter.com',
|
||||
linkedin: 'https://linkedin.com',
|
||||
email: 'sarah@example.com',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "2", name: "Michael Chen", role: "Full Stack Developer", image:
|
||||
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop", social: {
|
||||
github: "https://github.com", linkedin: "https://linkedin.com", email: "michael@example.com"
|
||||
id: '2',
|
||||
name: 'Michael Chen',
|
||||
role: 'Full Stack Developer',
|
||||
image:
|
||||
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop',
|
||||
social: {
|
||||
github: 'https://github.com',
|
||||
linkedin: 'https://linkedin.com',
|
||||
email: 'michael@example.com',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "3", name: "Emma Rodriguez", role: "Product Manager", image:
|
||||
"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop", social: {
|
||||
twitter: "https://twitter.com", linkedin: "https://linkedin.com", email: "emma@example.com"
|
||||
id: '3',
|
||||
name: 'Emma Rodriguez',
|
||||
role: 'Product Manager',
|
||||
image:
|
||||
'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop',
|
||||
social: {
|
||||
twitter: 'https://twitter.com',
|
||||
linkedin: 'https://linkedin.com',
|
||||
email: 'emma@example.com',
|
||||
},
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user