Merge from dev to loaf-prod for DEMO #25

Merged
andika merged 45 commits from dev into loaf-prod 2026-02-02 11:12:58 +00:00
8 changed files with 93 additions and 38 deletions
Showing only changes of commit 6c844c0e19 - Show all commits

View File

@@ -36,6 +36,7 @@
"@radix-ui/react-tooltip": "^1.2.4", "@radix-ui/react-tooltip": "^1.2.4",
"@stripe/react-stripe-js": "^2.0.0", "@stripe/react-stripe-js": "^2.0.0",
"@stripe/stripe-js": "^2.0.0", "@stripe/stripe-js": "^2.0.0",
"@tailwindcss/line-clamp": "^0.4.4",
"axios": "^1.8.4", "axios": "^1.8.4",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",

View File

@@ -7,30 +7,77 @@ export const StatCard = ({
icon: Icon, icon: Icon,
iconBgClass, iconBgClass,
dataTestId, dataTestId,
}) => ( }) => {
<Card const valueString = value == null ? "" : String(value);
className="p-6 flex flex-col justify-between bg-background rounded-2xl border border-[var(--neutral-800)]"
data-testid={dataTestId}
>
<div className="flex items-start gap-4 mb-4 ">
<div className={`${iconBgClass} p-3 rounded-lg `}>
<Icon className="size-8" />
</div>
<div className="space-y-8"> const digitCount =
<p valueString.replace(/\D/g, "").length || valueString.length;
className="text-6xl font-semibold text-[var(--purple-ink)] mb-1" /**
style={{ fontFamily: "'Inter', sans-serif" }} *
> const getValueFontSize = () => {
{value} if (digitCount <= 3) {
</p> // 3.75rem for 3 or fewer digits
</div> return "3.75rem";
</div> } else if (digitCount <= 6) {
<p // Scale down for more digits
className="text-sm text-brand-purple " return "clamp(2rem, 5cqi, 3rem)";
style={{ fontFamily: "'Nunito Sans', sans-serif" }} } else if (digitCount <= 9) {
return "clamp(1.5rem, 4cqi, 2.5rem)";
} else {
return "clamp(1.25rem, 3cqi, 2rem)";
}
};
* */
const getValueFontSize = () => {
switch (true) {
case digitCount <= 3:
// 3.75rem for 3 or fewer digits
return "3.75rem";
case digitCount <= 6:
// Scale down for more digits
return "clamp(2rem, 5cqi, 3rem)";
case digitCount <= 9:
return "clamp(1.5rem, 4cqi, 2.5rem)";
default:
return "clamp(1.25rem, 3cqi, 2rem)";
}
};
const valueFontSize = getValueFontSize();
return (
<Card
className="p-6 flex flex-col justify-between bg-background rounded-2xl border border-[var(--neutral-800)]"
data-testid={dataTestId}
> >
{title} <div className="flex items-start gap-4 mb-4 justify-between">
</p> <div
</Card> className="space-y-8 "
); style={{
containerType: "inline-size",
maxWidth: "200px",
width: "100%",
}}
>
<p
className="font-semibold text-[var(--purple-ink)] mb-1"
style={{ fontSize: valueFontSize, lineHeight: 1 }}
>
{value}
</p>
</div>
<div className={`${iconBgClass} p-3 rounded-lg `}>
<Icon className="size-8" />
</div>
</div>
<p
className="text-sm text-brand-purple "
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
{title}
</p>
</Card>
);
};

View File

@@ -60,7 +60,7 @@ const AdminDashboard = () => {
return ( return (
<> <>
<div className='flex justify-between items-center'> <div className='flex flex-col md:flex-row md:justify-between md:items-center'>
<div className="mb-8"> <div className="mb-8">
<h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}> <h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Admin Dashboard Admin Dashboard
@@ -69,9 +69,9 @@ const AdminDashboard = () => {
Manage users, events, and membership applications. Manage users, events, and membership applications.
</p> </p>
</div> </div>
<Link to={'/'}> <Link to={'/'} className=''>
<Button <Button
className="btn-lavender" className="btn-lavender mb-8 md:mb-0 "
> >
<Globe /> <Globe />
View Public Site View Public Site

View File

@@ -244,7 +244,7 @@ const AdminMembers = () => {
return ( return (
<> <>
<div className="mb-8"> <div className="mb-8">
<div className="flex justify-between items-start mb-4"> <div className="flex flex-col md:flex-row justify-between items-start mb-4">
<div> <div>
<h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}> <h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Members Management Members Management
@@ -253,7 +253,7 @@ const AdminMembers = () => {
Manage paying members and their subscriptions. Manage paying members and their subscriptions.
</p> </p>
</div> </div>
<div className="flex gap-3 flex-wrap"> <div className="flex gap-3 flex-wrap ">
{hasPermission('users.export') && ( {hasPermission('users.export') && (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>

View File

@@ -132,7 +132,7 @@ const AdminStaff = () => {
return ( return (
<> <>
<div className="mb-8"> <div className="mb-8">
<div className="flex justify-between items-start mb-4"> <div className="flex flex-col md:flex-row justify-between items-start mb-4">
<div> <div>
<h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}> <h1 className="text-4xl md:text-5xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Staff Management Staff Management
@@ -141,7 +141,7 @@ const AdminStaff = () => {
Manage internal team members and their roles. Manage internal team members and their roles.
</p> </p>
</div> </div>
<div className="flex gap-3"> <div className="flex gap-3 ">
{hasPermission('users.create') && ( {hasPermission('users.create') && (
<Button <Button
onClick={() => setInviteDialogOpen(true)} onClick={() => setInviteDialogOpen(true)}
@@ -194,13 +194,13 @@ const AdminStaff = () => {
{/* Tabs */} {/* Tabs */}
<Tabs value={activeTab} onValueChange={setActiveTab} className="mb-8"> <Tabs value={activeTab} onValueChange={setActiveTab} className="mb-8">
<TabsList className="grid w-full grid-cols-2 mb-8"> <TabsList className="grid w-full grid-cols-2 mb-8 ">
<TabsTrigger value="staff-list" className="text-lg py-3"> <TabsTrigger value="staff-list" className="text-sm sm:text-md md:text-lg py-3">
<UserCog className="h-5 w-5 mr-2" /> <UserCog className="h-5 w-5 mr-2 hidden md:inline" />
Staff Members Staff Members
</TabsTrigger> </TabsTrigger>
<TabsTrigger value="pending-invitations" className="text-lg py-3 "> <TabsTrigger value="pending-invitations" className="text-sm sm:text-md md:text-lg py-3 ">
<Mail className="h-5 w-5 mr-2" /> <Mail className="h-5 w-5 mr-2 hidden md:inline" />
Pending Invitations Pending Invitations
</TabsTrigger> </TabsTrigger>
</TabsList> </TabsList>

View File

@@ -54,3 +54,4 @@ h6 {
#ffffff 100% #ffffff 100%
); );
} }

View File

@@ -101,6 +101,7 @@ module.exports = {
plugins: [ plugins: [
require("tailwindcss-animate"), require("tailwindcss-animate"),
require("@tailwindcss/typography") require("@tailwindcss/typography"),
require('@tailwindcss/line-clamp')
], ],
}; };

View File

@@ -2552,6 +2552,11 @@
"@svgr/plugin-svgo" "^5.5.0" "@svgr/plugin-svgo" "^5.5.0"
loader-utils "^2.0.0" loader-utils "^2.0.0"
"@tailwindcss/line-clamp@^0.4.4":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz#767cf8e5d528a5d90c9740ca66eb079f5e87d423"
integrity sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==
"@tailwindcss/typography@^0.5.19": "@tailwindcss/typography@^0.5.19":
version "0.5.19" version "0.5.19"
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.19.tgz#ecb734af2569681eb40932f09f60c2848b909456" resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.19.tgz#ecb734af2569681eb40932f09f60c2848b909456"