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
12 changed files with 194 additions and 18 deletions
Showing only changes of commit 3c0b1396bc - Show all commits

View File

@@ -66,7 +66,7 @@ const ChangePasswordDialog = ({ open, onOpenChange }) => {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-md bg-background">
<DialogContent className="sm:max-w-md bg-background overflow-y-auto max-h-[90vh]">
<DialogHeader>
<div className="flex items-center gap-2 mb-2">
<div className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-[var(--lavender-300)]">

View File

@@ -77,7 +77,7 @@ export default function ChangeRoleDialog({ open, onClose, user, onSuccess }) {
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent className="sm:max-w-[500px]">
<DialogContent className="sm:max-w-[500px] overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Shield className="h-5 w-5 text-[#664fa3]" />

View File

@@ -181,7 +181,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
value={formData.first_name}
onChange={(e) => handleChange('first_name', e.target.value)}
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
placeholder="John"
placeholder="Jane"
/>
{errors.first_name && (
<p className="text-sm text-red-500">{errors.first_name}</p>

View File

@@ -106,7 +106,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px] rounded-2xl">
<DialogContent className="sm:max-w-[600px] rounded-2xl overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle className="text-2xl text-[var(--purple-ink)] flex items-center gap-2" style={{ fontFamily: "'Inter', sans-serif" }}>
<UserPlus className="h-6 w-6" />
@@ -165,7 +165,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
value={formData.first_name}
onChange={(e) => handleChange('first_name', e.target.value)}
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
placeholder="John"
placeholder="Jane"
/>
{errors.first_name && (
<p className="text-sm text-red-500">{errors.first_name}</p>

View File

@@ -123,7 +123,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
return (
<Dialog open={open} onOpenChange={handleClose}>
<DialogContent className="sm:max-w-[600px] rounded-2xl">
<DialogContent className="sm:max-w-[600px] rounded-2xl overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle className="text-2xl text-[var(--purple-ink)] flex items-center gap-2" style={{ fontFamily: "'Inter', sans-serif" }}>
<Mail className="h-6 w-6" />
@@ -196,7 +196,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
value={formData.first_name}
onChange={(e) => handleChange('first_name', e.target.value)}
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
placeholder="John"
placeholder="Jane"
/>
</div>

View File

@@ -156,8 +156,8 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
if (!user) return null;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px] bg-background rounded-2xl">
<Dialog open={open} onOpenChange={onOpenChange} className="">
<DialogContent className="sm:max-w-[600px] bg-background rounded-2xl overflow-y-auto max-h-[90vh] p-6">
<DialogHeader>
<DialogTitle className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Activate Manual Payment

View File

@@ -75,8 +75,24 @@ const PublicNavbar = () => {
<div className='sticky top-0 inset-x-0 z-50'>
<header className="bg-gradient-to-r flex-wrap from-[var(--purple-amethyst)] to-[var(--purple-deep)] px-[20px] py-[10px] flex md:justify-end justify-between items-center gap-4 sm:gap-6">
<div className='flex gap-4 sm:gap-6'>
<div className='flex gap-4 sm:gap-6 items-center'>
{user && (
<span
className="text-white text-base font-medium"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Welcome, {user.first_name}
</span>
)}
{(user?.role === 'admin' || user?.role === 'superadmin') && (
<Link
to="/admin"
className="text-white text-base font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Dashboard
</Link>
)}
<button
onClick={handleAuthAction}
className="text-white text-base font-medium hover:opacity-80 transition-opacity bg-transparent border-none cursor-pointer"
@@ -176,7 +192,71 @@ const PublicNavbar = () => {
Members Only
</Link>
)}
{user && (
<>
<Link
to="/events"
className={getDesktopLinkClasses('/events')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Events
</Link>
<Link
to="/members/calendar"
className={getDesktopLinkClasses('/members/calendar')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Calendar
</Link>
<Link
to="/members/directory"
className={getDesktopLinkClasses('/members/directory')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Directory
</Link>
<Link
to="/members/gallery"
className={getDesktopLinkClasses('/members/gallery')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Gallery
</Link>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
className={`${location.pathname.startsWith('/members/newsletters') || location.pathname.startsWith('/members/financials') || location.pathname.startsWith('/members/bylaws')
? "text-[var(--orange-light)] hover:text-[var(--orange-coral)]"
: "text-white hover:opacity-80"} text-[17.5px] font-medium transition-all flex items-center gap-1 bg-transparent border-none cursor-pointer px-3 py-1 rounded-md`}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Documents
<ChevronDown className="h-4 w-4" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="bg-background min-w-[220px]">
<DropdownMenuItem asChild>
<Link to="/members/newsletters" className="w-full px-3 py-2 text-[var(--purple-deep)] hover:bg-[var(--lavender-300)] cursor-pointer"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Newsletters
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link to="/members/financials" className="w-full px-3 py-2 text-[var(--purple-deep)] hover:bg-[var(--lavender-300)] cursor-pointer"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Financials
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link to="/members/bylaws" className="w-full px-3 py-2 text-[var(--purple-deep)] hover:bg-[var(--lavender-300)] cursor-pointer"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Bylaws
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
)}
{/* <Link
to="/resources"
className={getDesktopLinkClasses('/resources')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
@@ -189,7 +269,7 @@ const PublicNavbar = () => {
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Contact Us
</Link>
</Link> */}
</nav>
</header>
@@ -219,6 +299,18 @@ const PublicNavbar = () => {
</button>
</div>
{/* User Info */}
{user && (
<div className="px-6 py-4 border-b border-[var(--purple-deep)]">
<p className="text-white text-sm opacity-90" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Welcome,
</p>
<p className="text-white font-semibold text-base" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{user.first_name} {user.last_name}
</p>
</div>
)}
{/* Navigation Links */}
<nav className="flex flex-col p-6 space-y-4">
<Link
@@ -284,6 +376,80 @@ const PublicNavbar = () => {
</Link>
)}
{user && (
<>
<Link
to="/events"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileLinkClasses('/events')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Events
</Link>
<Link
to="/members/calendar"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileLinkClasses('/members/calendar')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Calendar
</Link>
<Link
to="/members/directory"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileLinkClasses('/members/directory')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Directory
</Link>
<Link
to="/members/gallery"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileLinkClasses('/members/gallery')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Gallery
</Link>
{/* Documents Section */}
<div className="space-y-2">
<p
className={`text-base font-semibold px-4 py-2 rounded-md ${location.pathname.startsWith('/members/newsletters') || location.pathname.startsWith('/members/financials') || location.pathname.startsWith('/members/bylaws') ? 'text-[var(--orange-light)]' : 'text-white'}`}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Documents
</p>
<Link
to="/members/newsletters"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileSubLinkClasses('/members/newsletters')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Newsletters
</Link>
<Link
to="/members/financials"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileSubLinkClasses('/members/financials')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Financials
</Link>
<Link
to="/members/bylaws"
onClick={() => setIsMobileMenuOpen(false)}
className={getMobileSubLinkClasses('/members/bylaws')}
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Bylaws
</Link>
</div>
</>
)}
<Link
to="/resources"
onClick={() => setIsMobileMenuOpen(false)}
@@ -304,6 +470,16 @@ const PublicNavbar = () => {
{/* Auth Actions */}
<div className="pt-4 border-t border-[var(--purple-deep)] space-y-2">
{(user?.role === 'admin' || user?.role === 'superadmin') && (
<Link
to="/admin"
onClick={() => setIsMobileMenuOpen(false)}
className="block text-white text-base font-medium hover:bg-[var(--purple-deep)] px-4 py-3 rounded-md transition-colors"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
>
Dashboard
</Link>
)}
<button
onClick={() => {
handleAuthAction();

View File

@@ -387,7 +387,7 @@ const AcceptInvitation = () => {
value={formData.first_name}
onChange={(e) => handleChange('first_name', e.target.value)}
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
placeholder="John"
placeholder="Jane"
/>
{formErrors.first_name && (
<p className="text-sm text-red-500">{formErrors.first_name}</p>

View File

@@ -330,7 +330,7 @@ const AdminBylaws = () => {
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent>
<DialogContent className="overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle>
{selectedBylaws ? 'Edit Bylaws' : 'Add Bylaws Version'}

View File

@@ -287,7 +287,7 @@ const AdminNewsletters = () => {
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent className="max-w-2xl">
<DialogContent className="max-w-2xl overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle>
{selectedNewsletter ? 'Edit Newsletter' : 'Add Newsletter'}

View File

@@ -848,7 +848,7 @@ Proceed with activation?`;
{/* Edit Subscription Dialog */}
<Dialog open={editDialogOpen} onOpenChange={setEditDialogOpen}>
<DialogContent className="sm:max-w-[500px] bg-background rounded-2xl">
<DialogContent className="sm:max-w-[500px] bg-background rounded-2xl overflow-y-auto max-h-[90vh]">
<DialogHeader>
<DialogTitle className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Edit Subscription

View File

@@ -285,7 +285,7 @@ const EventGallery = () => {
{/* Lightbox Modal */}
<Dialog open={selectedImageIndex !== null} onOpenChange={closeLightbox}>
<DialogContent className="max-w-7xl w-full h-[90vh] p-0 bg-black border-0">
<DialogContent className="max-w-7xl w-full h-[90vh] p-0 bg-black border-0 overflow-y-auto max-h-[90vh]">
{selectedImageIndex !== null && galleryImages[selectedImageIndex] && (
<div className="relative w-full h-full flex items-center justify-center">
{/* Close Button */}