diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fa906c2..00fced2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,8 +16,7 @@ export const metadata: Metadata = { openGraph: { title: "Computer Club - Tech Community & Innovation Hub", description: "Join a vibrant community of tech enthusiasts. Access coding workshops, hackathons, networking events, and mentorship programs.", type: "website", siteName: "Computer Club", images: [ { - url: "http://img.b2bpic.net/free-photo/gradient-illuminated-neon-gaming-desk-setup-with-keyboard_23-2149529414.jpg", alt: "Computer Club Community" - }, + url: "http://img.b2bpic.net/free-photo/gradient-illuminated-neon-gaming-desk-setup-with-keyboard_23-2149529414.jpg", alt: "Computer Club Community"}, ], }, twitter: { @@ -33,9 +32,7 @@ export default function RootLayout({ return ( - + {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index 42c9a4d..b20b51c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,12 +7,53 @@ import MetricSplitMediaAbout from '@/components/sections/about/MetricSplitMediaA import FeatureBorderGlow from '@/components/sections/feature/featureBorderGlow/FeatureBorderGlow'; import ProductCardFour from '@/components/sections/product/ProductCardFour'; import TestimonialCardTwelve from '@/components/sections/testimonial/TestimonialCardTwelve'; -import TeamCardFiveFlip from '@/components/sections/team/TeamCardFiveFlip'; +import TeamCardFive from '@/components/sections/team/TeamCardFive'; import FaqBase from '@/components/sections/faq/FaqBase'; import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis'; -import { BookOpen, Calendar, Code, Info, Lightbulb, Rocket, Star, Trophy, Users, Zap, Github, Linkedin, Twitter } from "lucide-react"; +import { BookOpen, Calendar, Code, Info, Lightbulb, Rocket, Star, Trophy, Users, Zap } from "lucide-react"; +import React, { useState } from "react"; export default function ComputerClubPage() { + const [flippedCards, setFlippedCards] = useState<{ [key: string]: boolean }>({}); + + const toggleFlip = (memberId: string) => { + setFlippedCards((prev) => ({ + ...prev, + [memberId]: !prev[memberId], + })); + }; + + const teamMembers = [ + { + id: "1", name: "Alex Johnson", role: "Founder & President", imageSrc: "http://img.b2bpic.net/free-photo/black-businessman-happy-expression_1194-2533.jpg", imageAlt: "Alex Johnson", social: [ + { platform: "linkedin", url: "https://linkedin.com/in/alexjohnson" }, + { platform: "twitter", url: "https://twitter.com/alexjohnson" }, + { platform: "github", url: "https://github.com/alexjohnson" }, + ], + }, + { + id: "2", name: "Jessica Lee", role: "Vice President", imageSrc: "http://img.b2bpic.net/free-photo/smiling-beautiful-middle-aged-business-woman_1262-3085.jpg?_wi=1", imageAlt: "Jessica Lee", social: [ + { platform: "linkedin", url: "https://linkedin.com/in/jessicalee" }, + { platform: "twitter", url: "https://twitter.com/jessicalee" }, + { platform: "github", url: "https://github.com/jessicalee" }, + ], + }, + { + id: "3", name: "David Kumar", role: "Technical Director", imageSrc: "http://img.b2bpic.net/free-photo/smiling-beautiful-middle-aged-business-woman_1262-3085.jpg?_wi=2", imageAlt: "David Kumar", social: [ + { platform: "linkedin", url: "https://linkedin.com/in/davidkumar" }, + { platform: "twitter", url: "https://twitter.com/davidkumar" }, + { platform: "github", url: "https://github.com/davidkumar" }, + ], + }, + { + id: "4", name: "Rachel Martinez", role: "Event Coordinator", imageSrc: "http://img.b2bpic.net/free-photo/smiling-beautiful-middle-aged-business-woman_1262-3085.jpg?_wi=3", imageAlt: "Rachel Martinez", social: [ + { platform: "linkedin", url: "https://linkedin.com/in/rachelmartinez" }, + { platform: "twitter", url: "https://twitter.com/rachelmartinez" }, + { platform: "github", url: "https://github.com/rachelmartinez" }, + ], + }, + ]; + return (
- +
+
+
+
+ + + Leadership + +
+

Meet Our Leadership

+

Dedicated professionals driving innovation and community growth

+
+ +
+ {teamMembers.map((member) => { + const isFlipped = flippedCards[member.id]; + return ( +
toggleFlip(member.id)} + > +
+ {/* Front of card */} +
+ {member.imageAlt} +
+

{member.name}

+

{member.role}

+
+
+ + {/* Back of card */} +
+

{member.name}

+ +
+
+
+ ); + })} +
+
+
diff --git a/src/components/ServiceWrapper.tsx b/src/components/ServiceWrapper.tsx index 7e19dc0..9829b5b 100644 --- a/src/components/ServiceWrapper.tsx +++ b/src/components/ServiceWrapper.tsx @@ -8,7 +8,7 @@ interface ServiceWrapperProps { export function ServiceWrapper({ children }: ServiceWrapperProps) { return ( -
+
{children}
); diff --git a/src/components/navbar/NavbarStyleApple/NavbarStyleApple.tsx b/src/components/navbar/NavbarStyleApple/NavbarStyleApple.tsx index 766804b..08cba78 100644 --- a/src/components/navbar/NavbarStyleApple/NavbarStyleApple.tsx +++ b/src/components/navbar/NavbarStyleApple/NavbarStyleApple.tsx @@ -38,7 +38,7 @@ export default function NavbarStyleApple({
{/* Desktop Navigation */} -
+
{navItems.map((item) => ( + ))} +
)}
diff --git a/src/components/sections/about/MetricSplitMediaAbout.tsx b/src/components/sections/about/MetricSplitMediaAbout.tsx index a225ac3..e7518ad 100644 --- a/src/components/sections/about/MetricSplitMediaAbout.tsx +++ b/src/components/sections/about/MetricSplitMediaAbout.tsx @@ -1,6 +1,7 @@ "use client"; import React from "react"; +import Image from "next/image"; import { LucideIcon } from "lucide-react"; interface Metric { @@ -8,7 +9,7 @@ interface Metric { title: string; } -interface Props { +interface MetricSplitMediaAboutProps { tag: string; tagIcon: LucideIcon; title: string; @@ -32,7 +33,7 @@ export default function MetricSplitMediaAbout({ useInvertedBackground = false, mediaAnimation = "slide-up", metricsAnimation = "slide-up", -}: Props) { +}: MetricSplitMediaAboutProps) { const bgClass = useInvertedBackground ? "bg-slate-900" : "bg-white"; const textClass = useInvertedBackground ? "text-white" : "text-slate-900"; const descriptionClass = useInvertedBackground @@ -42,20 +43,47 @@ export default function MetricSplitMediaAbout({ const getAnimationClass = (animation: string) => { switch (animation) { case "slide-up": - return "animate-in fade-in slide-in-from-bottom-4 duration-700"; - case "fade": - return "animate-in fade-in duration-700"; + return "animate-slide-up"; + case "fade-in": + return "animate-fade-in"; default: return ""; } }; return ( -
-
+
+ + +
{/* Left Content */} -
+
{/* Tag */}
@@ -65,29 +93,23 @@ export default function MetricSplitMediaAbout({
{/* Title */} -

+

{title}

{/* Description */} -

+

{description}

{/* Metrics */} -
+
{metrics.map((metric, index) => (
- + {metric.value} - + {metric.title}
@@ -95,15 +117,16 @@ export default function MetricSplitMediaAbout({
- {/* Right Image */} + {/* Right Media */}
-
- + {imageAlt} -
diff --git a/src/components/sections/faq/FaqBase.tsx b/src/components/sections/faq/FaqBase.tsx index c062dd7..41edf37 100644 --- a/src/components/sections/faq/FaqBase.tsx +++ b/src/components/sections/faq/FaqBase.tsx @@ -12,7 +12,7 @@ interface FaqBaseProps { title: string; description: string; tag: string; - textboxLayout: "default" | "compact" | "wide"; + textboxLayout: "default" | "centered" | "wide"; useInvertedBackground: boolean; faqsAnimation: "slide-up" | "fade-in" | "bounce"; faqs: FaqItem[]; @@ -29,40 +29,39 @@ export default function FaqBase({ }: FaqBaseProps) { const [expandedId, setExpandedId] = useState(null); - const toggleExpanded = (id: string) => { + const toggleFaq = (id: string) => { setExpandedId(expandedId === id ? null : id); }; - const getAnimationClass = () => { - switch (faqsAnimation) { - case "fade-in": - return "animate-fade-in"; - case "bounce": - return "animate-bounce"; - case "slide-up": - default: - return "animate-slide-up"; - } - }; - const getTextboxLayoutClass = () => { switch (textboxLayout) { - case "compact": - return "max-w-2xl"; + case "centered": + return "text-center max-w-2xl mx-auto"; case "wide": - return "max-w-6xl"; - case "default": + return "max-w-4xl mx-auto"; default: - return "max-w-4xl"; + return "max-w-3xl"; + } + }; + + const getAnimationClass = (index: number) => { + switch (faqsAnimation) { + case "fade-in": + return `opacity-0 animate-fadeIn`; + case "bounce": + return `opacity-0 animate-bounce`; + case "slide-up": + default: + return `opacity-0 animate-slideUp`; } }; const bgClass = useInvertedBackground - ? "bg-gray-900 text-white" - : "bg-white text-gray-900"; + ? "bg-slate-900 text-white" + : "bg-white text-slate-900"; return ( -
+
-
- {/* Header Section */} -
- {tag && ( -
- - {tag} - -
- )} -

{title}

-

- {description} -

+
+
+ + {tag} +
+

{title}

+

{description}

+
- {/* FAQ Items */} -
- {faqs.map((faq, index) => ( -
+ {faqs.map((faq, index) => ( +
+ + + {expandedId === faq.id && ( +
- {faq.title} - - - - - - {expandedId === faq.id && ( -
-

- {faq.content} -

-
- )} -
- ))} -
+

{faq.content}

+
+ )} +
+ ))}
); diff --git a/src/components/sections/feature/featureBorderGlow/FeatureBorderGlow.tsx b/src/components/sections/feature/featureBorderGlow/FeatureBorderGlow.tsx index ceb162d..560ad19 100644 --- a/src/components/sections/feature/featureBorderGlow/FeatureBorderGlow.tsx +++ b/src/components/sections/feature/featureBorderGlow/FeatureBorderGlow.tsx @@ -51,88 +51,71 @@ export default function FeatureBorderGlow({ key={index} className="group relative h-80 rounded-xl overflow-hidden bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 border border-gray-200 dark:border-gray-700 transition-all duration-300 hover:shadow-xl" > - {/* Border Glow Effect */} + {/* Glow Border Effect */}
- {/* Front Content */} -
-
- + {/* Front Side */} +
+
+

{feature.title}

-

+

{feature.description}

- {/* Back Content (Hover) */} - diff --git a/src/components/sections/footer/FooterLogoEmphasis.tsx b/src/components/sections/footer/FooterLogoEmphasis.tsx index b8afb84..95cf8ae 100644 --- a/src/components/sections/footer/FooterLogoEmphasis.tsx +++ b/src/components/sections/footer/FooterLogoEmphasis.tsx @@ -25,23 +25,28 @@ export default function FooterLogoEmphasis({
{/* Logo Section */}
-

- {logoText} -

-

- Building the future of technology together +

+
+ C +
+

+ {logoText} +

+
+

+ Building amazing digital experiences together

{/* Links Grid */} -
+
{columns.map((column, columnIndex) => (
{column.items.map((item, itemIndex) => ( {item.label} @@ -51,22 +56,36 @@ export default function FooterLogoEmphasis({
{/* Bottom Section */} -
+

© 2024 {logoText}. All rights reserved.

-
+
- Privacy + Twitter + + + - Terms + Discord + + +
diff --git a/src/components/sections/hero/HeroBillboardScroll.tsx b/src/components/sections/hero/HeroBillboardScroll.tsx index bb99d65..ef2d46f 100644 --- a/src/components/sections/hero/HeroBillboardScroll.tsx +++ b/src/components/sections/hero/HeroBillboardScroll.tsx @@ -9,7 +9,7 @@ interface Button { href: string; } -interface Background { +interface BackgroundConfig { variant: "animated-grid" | "solid" | "gradient"; } @@ -18,12 +18,12 @@ interface HeroBillboardScrollProps { description: string; tag: string; tagIcon: LucideIcon; - tagAnimation?: string; - background?: Background; + tagAnimation: string; + background: BackgroundConfig; imageSrc: string; imageAlt: string; buttons: Button[]; - buttonAnimation?: string; + buttonAnimation: string; } export default function HeroBillboardScroll({ @@ -31,28 +31,33 @@ export default function HeroBillboardScroll({ description, tag, tagIcon: TagIcon, - tagAnimation = "slide-up", - background = { variant: "animated-grid" }, + tagAnimation, + background, imageSrc, imageAlt, buttons, - buttonAnimation = "slide-up", + buttonAnimation, }: HeroBillboardScrollProps) { const getBackgroundClass = () => { switch (background.variant) { case "animated-grid": return "bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900"; - case "solid": - return "bg-slate-900"; case "gradient": return "bg-gradient-to-r from-blue-600 to-purple-600"; + case "solid": + return "bg-slate-900"; default: return "bg-slate-900"; } }; - const getAnimationDelay = (index: number) => { - return `${index * 100}ms`; + const getAnimationClass = (animation: string) => { + switch (animation) { + case "slide-up": + return "animate-in fade-in slide-in-from-bottom-4 duration-700"; + default: + return "animate-in fade-in duration-700"; + } }; return ( @@ -64,50 +69,43 @@ export default function HeroBillboardScroll({
)} - {/* Gradient Orbs */} -
-
+ {/* Gradient Overlay */} +
-
+
{/* Left Content */}
{/* Tag */}
- {tag} + {tag}
{/* Title */}

{title}

{/* Description */}

{description}

{/* Buttons */}
{buttons.map((button, index) => ( {button.text} @@ -126,12 +124,7 @@ export default function HeroBillboardScroll({
{/* Right Image */} -
+
-
- Scroll to explore - - - +
+ Scroll to explore +
+
+
- -
); } \ No newline at end of file diff --git a/src/components/sections/product/ProductCardFour.tsx b/src/components/sections/product/ProductCardFour.tsx index 846bcf1..29eadf0 100644 --- a/src/components/sections/product/ProductCardFour.tsx +++ b/src/components/sections/product/ProductCardFour.tsx @@ -61,212 +61,169 @@ export default function ProductCardFour({ const getAnimationClass = () => { switch (animationType) { case "slide-up": - return "animate-slide-up"; + return "animate-in slide-in-from-bottom-4 duration-500"; case "fade-in": - return "animate-fade-in"; + return "animate-in fade-in duration-500"; case "scale": - return "animate-scale"; + return "animate-in zoom-in-50 duration-500"; default: - return "animate-fade-in"; + return "animate-in fade-in duration-500"; } }; - const bgClass = useInvertedBackground ? "bg-gray-900" : "bg-white"; + const bgClass = useInvertedBackground ? "bg-slate-900" : "bg-white"; + const textColorClass = useInvertedBackground ? "text-white" : "text-slate-900"; return ( -
+
- + {tag}
-

+

{title}

{description}

- {products.map((product) => ( + {products.map((product, index) => (
toggleFlip(product.id)} + className={`${getAnimationClass()}`} + style={{ + animationDelay: `${index * 100}ms`, + }} >
toggleFlip(product.id)} > - {/* Front of card */}
-
- {product.imageAlt} -
-
-

- {product.name} -

-

- {product.variant} -

-
- - {product.price} - - Click to flip -
-
-
- - {/* Back of card */} -
-

- Connect With Us -

-
- - - - - - - - - - - - - - - - - - - - + {/* Front of card */} +
+
+ {product.imageAlt} +
+
+

+ {product.name} +

+

+ {product.variant} +

+
+ {product.price} +
+

+ Hover to see more +

+
+
+ + {/* Back of card */} +
+

+ Connect With Us +

+ +

+ Click to flip back +

-

- Click to flip back -

))}
- -
); } \ No newline at end of file diff --git a/src/components/sections/team/TeamCardFive.tsx b/src/components/sections/team/TeamCardFive.tsx index 23bdba2..614c96e 100644 --- a/src/components/sections/team/TeamCardFive.tsx +++ b/src/components/sections/team/TeamCardFive.tsx @@ -1,148 +1,193 @@ "use client"; -import CardStackTextBox from "@/components/cardStack/CardStackTextBox"; -import MediaContent from "@/components/shared/MediaContent"; -import { useCardAnimation } from "@/components/cardStack/hooks/useCardAnimation"; -import { cls } from "@/lib/utils"; -import type { LucideIcon } from "lucide-react"; -import type { ButtonConfig, CardAnimationType, TitleSegment, ButtonAnimationType } from "@/components/cardStack/types"; -import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; +import { useState } from "react"; +import { Mail, Linkedin, Twitter, Github } from "lucide-react"; -type TeamMember = { - id: string; +interface TeamMember { + id: number; name: string; role: string; - imageSrc?: string; - videoSrc?: string; - imageAlt?: string; - videoAriaLabel?: string; -}; - -interface TeamCardFiveProps { - team: TeamMember[]; - animationType: CardAnimationType; - title: string; - titleSegments?: TitleSegment[]; - description: string; - textboxLayout: TextboxLayout; - useInvertedBackground: InvertedBackground; - tag?: string; - tagIcon?: LucideIcon; - tagAnimation?: ButtonAnimationType; - buttons?: ButtonConfig[]; - buttonAnimation?: ButtonAnimationType; - ariaLabel?: string; - className?: string; - containerClassName?: string; - textBoxTitleClassName?: string; - textBoxTitleImageWrapperClassName?: string; - textBoxTitleImageClassName?: string; - textBoxDescriptionClassName?: string; - textBoxClassName?: string; - textBoxTagClassName?: string; - textBoxButtonContainerClassName?: string; - textBoxButtonClassName?: string; - textBoxButtonTextClassName?: string; - gridClassName?: string; - cardClassName?: string; - mediaWrapperClassName?: string; - mediaClassName?: string; - nameClassName?: string; - roleClassName?: string; + image: string; + email?: string; + linkedin?: string; + twitter?: string; + github?: string; } -const TeamCardFive = ({ - team, - animationType, - title, - titleSegments, - description, - textboxLayout, - useInvertedBackground, - tag, - tagIcon, - tagAnimation, - buttons, - buttonAnimation, - ariaLabel = "Team section", - className = "", - containerClassName = "", - textBoxTitleClassName = "", - textBoxTitleImageWrapperClassName = "", - textBoxTitleImageClassName = "", - textBoxDescriptionClassName = "", - textBoxClassName = "", - textBoxTagClassName = "", - textBoxButtonContainerClassName = "", - textBoxButtonClassName = "", - textBoxButtonTextClassName = "", - gridClassName = "", - cardClassName = "", - mediaWrapperClassName = "", - mediaClassName = "", - nameClassName = "", - roleClassName = "", -}: TeamCardFiveProps) => { - const { itemRefs } = useCardAnimation({ animationType, itemCount: team.length }); +interface Props { + members?: TeamMember[]; +} + +const defaultMembers: TeamMember[] = [ + { + id: 1, + name: "Sarah Johnson", + role: "Chief Executive Officer", + image: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=400&h=400&fit=crop", + email: "sarah@example.com", + linkedin: "https://linkedin.com", + twitter: "https://twitter.com", + github: "https://github.com", + }, + { + id: 2, + name: "Michael Chen", + role: "Chief Technology Officer", + image: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop", + email: "michael@example.com", + linkedin: "https://linkedin.com", + twitter: "https://twitter.com", + github: "https://github.com", + }, + { + id: 3, + name: "Emily Rodriguez", + role: "Chief Financial Officer", + image: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop", + email: "emily@example.com", + linkedin: "https://linkedin.com", + twitter: "https://twitter.com", + github: "https://github.com", + }, + { + id: 4, + name: "David Park", + role: "Chief Product Officer", + image: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=400&h=400&fit=crop", + email: "david@example.com", + linkedin: "https://linkedin.com", + twitter: "https://twitter.com", + github: "https://github.com", + }, +]; + +export default function TeamCardFive({ members = defaultMembers }: Props) { + const [flipped, setFlipped] = useState<{ [key: number]: boolean }>({}); + + const toggleFlip = (id: number) => { + setFlipped((prev) => ({ + ...prev, + [id]: !prev[id], + })); + }; return ( -
-
- +
+
+
+

+ Meet Our Leadership +

+

+ Hover over cards to see social links +

+
-
- {team.map((member, index) => ( +
+ {members.map((member) => (
{ itemRefs.current[index] = el; }} - className={cls("relative flex flex-col items-center text-center w-[55%] md:w-[28%] -mx-[4%] md:-mx-[2%]", cardClassName)} + className="h-80 cursor-pointer perspective" + onClick={() => toggleFlip(member.id)} > -
- +
+ {/* Front of card */} +
+
+ {member.name} +
+
+

{member.name}

+

{member.role}

+
+
+
+ + {/* Back of card */} +
+

+ {member.name} +

+
+ {member.email && ( + e.stopPropagation()} + > + + Email + + )} + {member.linkedin && ( + e.stopPropagation()} + > + + LinkedIn + + )} + {member.twitter && ( + e.stopPropagation()} + > + + Twitter + + )} + {member.github && ( + e.stopPropagation()} + > + + GitHub + + )} +
+

+ Click to flip back +

+
-

- {member.name} -

-

- {member.role} -

))}
); -}; - -TeamCardFive.displayName = "TeamCardFive"; - -export default TeamCardFive; +} \ No newline at end of file diff --git a/src/components/sections/testimonial/TestimonialCardTwelve.tsx b/src/components/sections/testimonial/TestimonialCardTwelve.tsx index 0531220..0dbe0d9 100644 --- a/src/components/sections/testimonial/TestimonialCardTwelve.tsx +++ b/src/components/sections/testimonial/TestimonialCardTwelve.tsx @@ -44,29 +44,27 @@ export default function TestimonialCardTwelve({ ]; return ( -
+
- {TagIcon && } - - {cardTag} - + {TagIcon && } + {cardTag}
-

- {cardTitle} -

+

{cardTitle}

{testimonials.map((testimonial) => (
toggleFlip(testimonial.id)} >
{/* Front of card */}
-

- {testimonial.name} -

+

{testimonial.name}

{socialLinks.map((link) => ( ))}
+

Click to flip back

))}
- -
); } \ No newline at end of file diff --git a/src/tag/Tag.tsx b/src/tag/Tag.tsx index a2df8bf..d4dfa9e 100644 --- a/src/tag/Tag.tsx +++ b/src/tag/Tag.tsx @@ -57,131 +57,122 @@ const defaultMembers: TeamMember[] = [ }, ]; -export default function Tag({ members = defaultMembers }: TagProps) { - const [flipped, setFlipped] = useState<{ [key: string]: boolean }>({}); - - const toggleFlip = (id: string) => { - setFlipped((prev) => ({ - ...prev, - [id]: !prev[id], - })); - }; +function TeamCard({ member }: { member: TeamMember }) { + const [isFlipped, setIsFlipped] = useState(false); return ( -
-
+ + ); +} + +export default function Tag({ members = defaultMembers }: TagProps) { + return ( +
+

Meet Our Leadership

- Exceptional leaders driving innovation and excellence + Hover over each card to see social links

{members.map((member) => ( -
toggleFlip(member.id)} - > -
- {/* Front of card */} -
- {member.name} -
-

- {member.name} -

-

{member.title}

-

- Hover to see social links -

-
-
- - {/* Back of card */} -
-

- {member.name} -

- -
- {member.email && ( - e.stopPropagation()} - > - - Email - - )} - - {member.linkedin && ( - e.stopPropagation()} - > - - LinkedIn - - )} - - {member.twitter && ( - e.stopPropagation()} - > - - Twitter - - )} - - {member.github && ( - e.stopPropagation()} - > - - GitHub - - )} -
-
-
-
+ ))}