Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 87 additions & 43 deletions src/components/SupportUsButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import type { supportUsButtonProps } from "../types/index";
import type { Theme } from "../types/index";
import type { ButtonVariant } from "../types/index";
import type { Tier } from "../types/index";

// Function to get the appropriate classes based on the selected theme, used for styling different sections of the component according to the chosen theme
function classAccordingToTheme(Theme: Theme): string {
Expand Down Expand Up @@ -69,11 +70,38 @@ function SupportUsButton({
ctaSection: "",
},
buttonVariant = "AOSSIE",
showCopyLinkButton = false,
}: supportUsButtonProps): React.JSX.Element {
const [copiedLink, setCopiedLink] = React.useState<string | null>(null);

const handleCopyLink = (e: React.MouseEvent, link: string) => {
e.preventDefault();
e.stopPropagation();
navigator.clipboard.writeText(link);
setCopiedLink(link);
setTimeout(() => {
setCopiedLink(null);
}, 2000);
};

const sortedSponsors = sponsors ? [...sponsors].sort((a, b) => {
const tierPriority: Record<Tier, number> = {
Platinum: 1,
Gold: 2,
Silver: 3,
Bronze: 4,
};
const aTier = a.sponsorshipTier || 'Bronze';
const bTier = b.sponsorshipTier || 'Bronze';
return tierPriority[aTier] - tierPriority[bTier];
}) : [];

const resolvedTheme = Theme === "system" ? (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light") : Theme;

return (
// Container for the support us button, with dynamic classes based on the selected theme and custom class names
<div
className={`w-full font-sans justify-center items-center text-center ${Theme == "light" || Theme == "dark" ? classAccordingToTheme(Theme) : "bg-black text-white"} ${classNames.container}`}
className={`w-full font-sans justify-center items-center text-center ${resolvedTheme == "light" || resolvedTheme == "dark" ? classAccordingToTheme(resolvedTheme) : "bg-black text-white"} ${classNames.container}`}
>
{/* Hero section with optional background image*/}
<div className="relative w-full h-[50vh] flex justify-center">
Expand Down Expand Up @@ -119,7 +147,7 @@ function SupportUsButton({
{hero.title}
</h1>
<p
className={`wrap-anywhere ${Theme === "light" ? "text-slate-600" : "text-slate-400"} text-lg font-semibold`}
className={`wrap-anywhere ${resolvedTheme === "light" ? "text-slate-600" : "text-slate-400"} text-lg font-semibold`}
>
{hero.description}
</p>
Expand All @@ -134,21 +162,21 @@ function SupportUsButton({
relative w-[90%] p-15 rounded-2xl overflow-visible

// Shadows for different themes
${Theme === "AOSSIE" && "shadow-xl shadow-primary/20"}
${Theme === "light" && "shadow-xl shadow-gray-300/30"}
${Theme === "dark" && "shadow-xl shadow-gray-700/30"}
${Theme === "minimal" && "shadow-xl shadow-gray-800/30"}
${Theme === "corporate" && "shadow-xl shadow-blue-600/30"}
${resolvedTheme === "AOSSIE" && "shadow-xl shadow-primary/20"}
${resolvedTheme === "light" && "shadow-xl shadow-gray-300/30"}
${resolvedTheme === "dark" && "shadow-xl shadow-gray-700/30"}
${resolvedTheme === "minimal" && "shadow-xl shadow-gray-800/30"}
${resolvedTheme === "corporate" && "shadow-xl shadow-blue-600/30"}

// Outline for light and dark themes
${Theme === "light" && "outline-1 outline-gray-300"}
${Theme === "dark" && "outline-1 outline-gray-700"}
${classAccordingToTheme(Theme)}`}
${resolvedTheme === "light" && "outline-1 outline-gray-300"}
${resolvedTheme === "dark" && "outline-1 outline-gray-700"}
${classAccordingToTheme(resolvedTheme)}`}
>
{/* Background grid */}
<div className="absolute inset-0 bg-[radial-gradient(rgba(0,0,0,0.15)_1.5px,transparent_0)] bg-size-[20px_20px] pointer-events-none opacity-100"></div>
<div
className={`absolute top-0 left-0 bottom-0 w-1/2 h-full rounded-2xl p-6 overflow-visible ${classAccordingToTheme(Theme)}`}
className={`absolute top-0 left-0 bottom-0 w-1/2 h-full rounded-2xl p-6 overflow-visible ${classAccordingToTheme(resolvedTheme)}`}
></div>

{/* Content container */}
Expand Down Expand Up @@ -196,32 +224,32 @@ function SupportUsButton({
<div
className={`
border
${Theme === "AOSSIE" && "border-[#f1c514]/50"}
${Theme === "light" && "border-gray-300/50"}
${Theme === "dark" && "border-gray-700/50"}
${Theme === "minimal" && "border-gray-800/50"}
${Theme === "corporate" && "border-blue-600/50"}`}
${resolvedTheme === "AOSSIE" && "border-[#f1c514]/50"}
${resolvedTheme === "light" && "border-gray-300/50"}
${resolvedTheme === "dark" && "border-gray-700/50"}
${resolvedTheme === "minimal" && "border-gray-800/50"}
${resolvedTheme === "corporate" && "border-blue-600/50"}`}
></div>

{/* Project information */}
<div className="flex flex-col gap-2">
<h3
className={`font-bold w-fit uppercase text-sm p-2 rounded-lg
${Theme === "AOSSIE" && "bg-[#edc214]"}
${Theme === "light" && "bg-gray-300/50"}
${Theme === "dark" && "bg-gray-700/50"}
${Theme === "minimal" && "bg-gray-800/50"}
${Theme === "corporate" && "bg-blue-600/50"}`}
${resolvedTheme === "AOSSIE" && "bg-[#edc214]"}
${resolvedTheme === "light" && "bg-gray-300/50"}
${resolvedTheme === "dark" && "bg-gray-700/50"}
${resolvedTheme === "minimal" && "bg-gray-800/50"}
${resolvedTheme === "corporate" && "bg-blue-600/50"}`}
>
ABOUT PROJECT: {organizationInformation.projectInformation.name}
</h3>
<p
className={`italic font-semibold
${Theme === "AOSSIE" && "text-[#614f08]"}
${Theme === "light" && "text-gray-600"}
${Theme === "dark" && "text-gray-400"}
${Theme === "minimal" && "text-gray-800"}
${Theme === "corporate" && "text-blue-600/80"}
${resolvedTheme === "AOSSIE" && "text-[#614f08]"}
${resolvedTheme === "light" && "text-gray-600"}
${resolvedTheme === "dark" && "text-gray-400"}
${resolvedTheme === "minimal" && "text-gray-800"}
${resolvedTheme === "corporate" && "text-blue-600/80"}
`}
>
"{organizationInformation.projectInformation.description}"
Expand All @@ -234,16 +262,16 @@ function SupportUsButton({
{/* Sponsors section */}
<div
className={`w-full flex justify-center mt-10 p-10
${Theme === "AOSSIE" && "bg-[#1f1f1f]"}
${Theme === "light" && "bg-gray-300/50"}
${Theme === "dark" && "bg-gray-700/50"}
${Theme === "minimal" && "bg-gray-800/50"}
${Theme === "corporate" && "bg-blue-600/50"}`}
${resolvedTheme === "AOSSIE" && "bg-[#1f1f1f]"}
${resolvedTheme === "light" && "bg-gray-300/50"}
${resolvedTheme === "dark" && "bg-gray-700/50"}
${resolvedTheme === "minimal" && "bg-gray-800/50"}
${resolvedTheme === "corporate" && "bg-blue-600/50"}`}
>
{sponsors && sponsors.length > 0 && (
{sortedSponsors && sortedSponsors.length > 0 && (
// List of sponsors with their logos and links, styled according to the selected theme and custom class names
<div
className={`${classNames.sponsors} ${classAccordingToTheme(Theme)}
className={`${classNames.sponsors} ${classAccordingToTheme(resolvedTheme)}
relative w-[90%] flex flex-col p-8 rounded-2xl gap-25 mt-15 overflow-hidden`}
>
{/* Sponsor pattern AOSSIE */}
Expand Down Expand Up @@ -275,7 +303,7 @@ function SupportUsButton({

{/* Sponsor logos */}
<div className="flex flex-row flex-wrap justify-center items-center gap-10 z-10">
{sponsors.map((sponsor, index) => (
{sortedSponsors.map((sponsor, index) => (
<a
href={sponsor.link}
key={index}
Expand All @@ -284,14 +312,14 @@ function SupportUsButton({
title={`Visit ${sponsor.name}'s website`}
>
<div
className={`${Theme === "dark" ? "bg-gray-800 text-white" : "bg-white text-black"} rounded-lg flex flex-col justify-center items-center gap-2 p-8 w-fit transition-transform hover:scale-[1.02] shadow-lg min-h-75 min-w-62.5 hover:border-2
className={`${resolvedTheme === "dark" ? "bg-gray-800 text-white" : "bg-white text-black"} rounded-lg flex flex-col justify-center items-center gap-2 p-8 w-fit transition-transform hover:scale-[1.02] shadow-lg min-h-75 min-w-62.5 hover:border-2

// Shadows for different themes
${Theme === "AOSSIE" && "shadow-primary/20"}
${Theme === "light" && "shadow-gray-300/30"}
${Theme === "dark" && "shadow-gray-700/30"}
${Theme === "minimal" && "shadow-gray-800/30"}
${Theme === "corporate" && "shadow-blue-600/30"}
${resolvedTheme === "AOSSIE" && "shadow-primary/20"}
${resolvedTheme === "light" && "shadow-gray-300/30"}
${resolvedTheme === "dark" && "shadow-gray-700/30"}
${resolvedTheme === "minimal" && "shadow-gray-800/30"}
${resolvedTheme === "corporate" && "shadow-blue-600/30"}

// Size based on sponsorship tier
${sponsor.sponsorshipTier === "Platinum" && "min-w-80 min-h-90"}
Expand Down Expand Up @@ -388,7 +416,23 @@ function SupportUsButton({
)}

<div className="w-full">
<h3 className={`font-bold text-2xl`}>{sponsor.name}</h3>
<div className="flex justify-between items-start gap-2">
<h3 className={`font-bold text-2xl`}>{sponsor.name}</h3>
{showCopyLinkButton && sponsor.link && (
<button
onClick={(e) => handleCopyLink(e, sponsor.link!)}
className="p-1.5 rounded-lg transition-colors hover:bg-black/10 dark:hover:bg-white/10"
title="Copy link"
aria-label="Copy sponsor link"
>
{copiedLink === sponsor.link ? (
<span className="text-green-500 font-semibold text-sm mr-1">Copied!</span>
) : (
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>
)}
</button>
)}
</div>
{sponsor.sponsorshipTier && (
<span className="flex text-[16px] p-2 rounded-xl items-center mt-3.5 font-semibold bg-[#d0f2eb] text-black w-fit">
{sponsor.sponsorshipTier}
Expand All @@ -405,15 +449,15 @@ function SupportUsButton({

{/* Call-to-action section with title, description, and sponsor links */}
<div
className={`w-full flex justify-center p-10 ${(Theme === "light" || Theme === "dark") && classAccordingToTheme(Theme)} ${classNames.ctaSection}`}
className={`w-full flex justify-center p-10 ${(resolvedTheme === "light" || resolvedTheme === "dark") && classAccordingToTheme(resolvedTheme)} ${classNames.ctaSection}`}
>
<div className="w-4/5 flex flex-col items-center gap-5 py-20 border border-primary rounded-sm mt-20 mb-20">
<h2 className={`font-extrabold text-4xl md:text-5xl lg:text-6xl`}>
{ctaSection.title}
</h2>
<p
className={`font-semibold
${Theme === "light" ? "text-gray-600" : "text-gray-400"}`}
${resolvedTheme === "light" ? "text-gray-600" : "text-gray-400"}`}
>
{ctaSection.description}
</p>
Expand Down
7 changes: 5 additions & 2 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ReactNode } from "react";
Theme
========================= */

export type Theme = "AOSSIE" | "light" | "dark" | "minimal" | "corporate";
export type Theme = "AOSSIE" | "light" | "dark" | "minimal" | "corporate" | "system";

/* =========================================================
Button Variant
Expand Down Expand Up @@ -123,7 +123,7 @@ export type Pattern = "AOSSIE" | "dots" | "grid" | "none";
========================= */

export interface supportUsButtonProps {
// Theme for the button, can be one of "AOSSIE", "light", "dark", "minimal", or "corporate"
// Theme for the button, can be one of "AOSSIE", "light", "dark", "minimal", "corporate", or "system"
Theme?: Theme;

// Optional background pattern for the button, can be one of "dots", "grid", "stripes", or "none"
Expand Down Expand Up @@ -152,4 +152,7 @@ export interface supportUsButtonProps {

// Optional button variant for styling the call-to-action buttons
buttonVariant?: ButtonVariant;

// Optional flag to show a copy link button on sponsor cards
showCopyLinkButton?: boolean;
}
Loading