Rework of fiscal sponsorship page (#1238)

Co-authored-by: Sam Poder <sampoder@berkeley.edu>
This commit is contained in:
julian-kbjkjbdkfjb 2025-05-31 19:35:21 -04:00 committed by GitHub
parent 909d203dd9
commit 1723cb5d67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 339 additions and 376 deletions

View file

@ -0,0 +1,333 @@
/** @jsxImportSource theme-ui */
export const badges = [
{
label: 'Transparent',
id: 'Transparent',
tooltip: 'Transparent',
color: 'purple',
icon: 'explore',
match: org => org.isTransparent
}
]
badges.__proto__.forOrg = function (org) {
return this.filter(badge => badge.match?.(org))
}
import {
Badge as ThemeBadge,
Box,
Container,
Flex,
Grid,
Heading,
Input
} from 'theme-ui'
import { Text, Button, Card } from 'theme-ui'
import Icon from '@hackclub/icons'
import OrganizationCard, {
Badge
} from './fiscal-sponsorship/directory/card'
import Tooltip from './fiscal-sponsorship/tooltip'
export function OrganizationModal({ organization, onClose }) {
return (
<Box
sx={{
position: 'fixed',
top: '0px',
left: '0px',
right: '0px',
bottom: '0px',
zIndex: 1000,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
bg: '#00000044'
}}
onClick={onClose}
>
<Card
sx={{
width: 'min(640px, 90%)',
bg: 'elevated',
borderRadius: '10px',
position: 'relative',
display: 'flex',
boxSizing: 'border-box',
flexDirection: 'column',
maxHeight: '90vh',
overflowY: 'scroll'
}}
onClick={e => {
e.stopPropagation()
}}
>
<Flex
sx={{
position: 'absolute',
top: '10px',
right: '10px',
width: '40px',
height: '40px',
bg: 'smoke',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer'
}}
>
<Icon glyph="view-close" size={32} onClick={onClose} />
</Flex>
<Flex
sx={{
flexDirection: 'column',
alignItems: 'stretch',
gap: 3
}}
>
<Flex
sx={{
flexDirection: 'column',
justifyContent: 'end',
minHeight: '200px',
m: -4,
p: "24px",
boxSizing: 'content-box',
backgroundPosition: 'center center',
color: 'white',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
backgroundImage: `url('${organization.branding.backgroundImage}')`
}}
>
<Flex
sx={{
flexDirection: ['column', 'row', 'row'],
alignItems: 'center',
justifyContent: 'start',
gap: "24px"
}}
>
{organization.branding.logo && (
<img
alt={`${organization.name}'s logo`}
src={organization.branding.logo}
sx={{
width: 'auto',
height: '96px',
borderRadius: '8px'
}}
/>
)}
<Flex
sx={{
flexDirection: "column"
}}
>
<Text
variant="title"
sx={{
wordBreak: 'break-word',
marginBottom: '12px',
textAlign: ['center', 'left', 'left'],
fontSize: ['36px', '36px', '36px'],
color: 'white',
textShadow: '0px 10px 10px rgba(0, 0, 0, 0.25)'
}}
>
{organization.name}
</Text>
<Text
variant="subheadline"
sx={{
whiteSpace: "nowrap",
textAlign: ['center', 'left', 'left'],
color: 'white',
textShadow: '0px 10px 10px rgba(0, 0, 0, 0.25)',
marginBottom: "0px"
}}
>
{organization.location.country}
</Text>
</Flex>
</Flex>
</Flex>
{/* Badges */}
<Flex
sx={{
flexDirection: 'row',
justifyContent: ['center', 'start', 'start'],
alignItems: 'center',
gap: 2,
width: '100%',
mt: "40px",
mb: -2,
flexWrap: 'wrap'
}}
>
{/* hardcoded "nonprofit" badge */}
<ThemeBadge
as="span"
aria-label="Nonprofit"
sx={{
bg: 'blue',
color: 'snow',
fontSize: '20px',
textShadow: 'none',
borderRadius: '15px',
px: 2,
display: 'block'
}}
>
Nonprofit
</ThemeBadge>
{organization.raw.transparent && (
<ThemeBadge
as="span"
aria-label="Transparent"
sx={{
bg: 'purple',
color: 'snow',
fontSize: '20px',
textShadow: 'none',
borderRadius: '15px',
px: 2,
display: 'block'
}}
>
Transparent
</ThemeBadge>
)}
</Flex>
<Flex
sx={{
flexDirection: 'row',
alignItems: 'start',
gap: 4,
width: '100%'
}}
>
{/* info & buttons */}
<Flex
sx={{
flexDirection: 'column',
alignItems: 'start',
flex: '1'
}}
>
{organization.branding.description && (
<Text variant="lead" style={{ fontSize: '22px' }}>
{organization.branding.description}
</Text>
)}
<Flex
sx={{
flexDirection: 'column',
alignItems: 'start',
my: 2,
ml: -1,
gap: 1
}}
>
{organization.links.website && (
<Flex
as="a"
target="_blank"
href={organization.links.website}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="web" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Website
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
{organization.links.financials && (
<Flex
as="a"
target="_blank"
href={organization.links.financials}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="explore" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Transparent Finances
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
</Flex>
</Flex>
</Flex>
<Flex
sx={{
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
alignItems: 'center'
}}
>
<Text sx={{ display: ['none', 'none', 'block'] }}>
All donations are tax-deductible.
</Text>
<Button
as="a"
variant="lg"
href={organization.links.donations}
target="_blank"
sx={{
backgroundImage: t => t.util.gx('green', 'blue'),
width: ['100%', 'auto', 'auto']
}}
>
<Flex
sx={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
width: '24px',
height: '24px',
marginLeft: -1,
marginRight: 2
}}
>
<Icon glyph="friend" size={20} style={{ scale: '2.5' }} />
</Flex>
Make a Donation
</Button>
</Flex>
</Flex>
</Card>
</Box>
)
}

View file

@ -125,7 +125,7 @@ export const OrganizationCard = ({
alt={`${organization.name} logo`} alt={`${organization.name} logo`}
loading="lazy" loading="lazy"
sx={{ sx={{
minWidth: 64, // minWidth: 64,
height: 64, height: 64,
objectFit: 'contain', objectFit: 'contain',
objectPosition: 'left', objectPosition: 'left',

View file

@ -26,6 +26,7 @@ import theme from '@hackclub/theme'
import Tooltip from '../../../components/fiscal-sponsorship/tooltip' import Tooltip from '../../../components/fiscal-sponsorship/tooltip'
const GeoPattern = require('geopattern') const GeoPattern = require('geopattern')
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { OrganizationModal, badges } from "../../../components/directoryModal.js"
const styles = ` const styles = `
html { html {
@ -33,17 +34,6 @@ const styles = `
} }
` `
export const badges = [
{
label: 'Transparent',
id: 'Transparent',
tooltip: 'Transparent',
color: 'purple',
icon: 'explore',
match: org => org.isTransparent
}
]
export const regions = [ export const regions = [
{ {
label: 'North America', label: 'North America',
@ -91,18 +81,6 @@ export const regions = [
} }
] ]
badges.__proto__.forOrg = function (org) {
return this.filter(badge => badge.match?.(org))
}
export const tags = [
{
label: 'Nonprofit',
id: 'Nonprofit',
color: 'blue',
match: org => true
}
]
export const categories = [ export const categories = [
{ {
@ -131,13 +109,12 @@ export const categories = [
description: `Hackers are using HCB to run hackathons that'll blow your mind away.`, description: `Hackers are using HCB to run hackathons that'll blow your mind away.`,
match: org => org.category == 'hackathon', match: org => org.category == 'hackathon',
icon: 'event-code' icon: 'event-code'
},
{
label: ""
} }
] ]
tags.__proto__.forOrg = function (org) {
return this.filter(tag => tag.match?.(org))
}
const FilterPanel = ({ filter, mobile, clearOffset }) => { const FilterPanel = ({ filter, mobile, clearOffset }) => {
const [regionsHiddenOnMobile, setRegionsHiddenOnMobile] = useState(mobile) const [regionsHiddenOnMobile, setRegionsHiddenOnMobile] = useState(mobile)
const [categoriesHiddenOnMobile, setCategoriesHiddenOnMobile] = const [categoriesHiddenOnMobile, setCategoriesHiddenOnMobile] =
@ -415,354 +392,7 @@ export default function Directory({ rawOrganizations, pageRegion, category }) {
/> />
<style>{styles}</style> <style>{styles}</style>
{modalOrganization && ( {modalOrganization && (
<Box <OrganizationModal organization={modalOrganization} onClose={closeModal} />
sx={{
position: 'fixed',
top: '0px',
left: '0px',
right: '0px',
bottom: '0px',
zIndex: 1000,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
bg: '#00000044'
}}
onClick={closeModal}
>
<Card
sx={{
width: 'min(800px, 80%)',
bg: 'elevated',
borderRadius: '10px',
position: 'relative',
display: 'flex',
boxSizing: 'border-box',
flexDirection: 'column',
maxHeight: '90vh',
overflowY: 'scroll'
}}
onClick={e => {
e.stopPropagation()
}}
>
<Flex
sx={{
position: 'absolute',
top: '10px',
right: '10px',
width: '40px',
height: '40px',
bg: 'smoke',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer'
}}
>
<Icon glyph="view-close" size={32} onClick={closeModal} />
</Flex>
<Flex sx={{ flexDirection: 'column', alignItems: 'start', gap: 3 }}>
<Flex
sx={{
flexDirection: 'column',
justifyContent: 'end',
width: '100%',
minHeight: '200px',
m: -4,
p: 4,
pb: '48px',
boxSizing: 'content-box',
backgroundPosition: 'center center',
color: 'white',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
backgroundImage: `linear-gradient(rgba(0,0,0,0.2) 0%, rgba(0,0,0,0.4) 80%, rgba(255,255,255,1) 100%), url('${modalOrganization.branding.backgroundImage}')`
}}
>
<Flex
sx={{
flexDirection: ['column', 'row', 'row'],
alignItems: ['center', 'end', 'end'],
justifyContent: 'start'
}}
>
{modalOrganization.branding.logo && (
<img
alt={`${modalOrganization.name}'s logo`}
src={modalOrganization.branding.logo}
sx={{
width: '100px',
height: '100px',
borderRadius: '8px',
marginRight: [0, 4, 4],
boxShadow: '0px 0px 45px 0px rgba(0, 0, 0, 0.72)'
}}
/>
)}
<Text
variant="title"
sx={{
wordBreak: 'break-word',
marginBottom: '16px',
textAlign: ['center', 'left', 'left'],
fontSize: ['48px', '48px', '64px'],
color: 'white',
textShadow: '0px 10px 10px rgba(0, 0, 0, 0.25)'
}}
>
{modalOrganization.name}
</Text>
</Flex>
</Flex>
{/* Badges */}
<Flex
sx={{
flexDirection: 'row',
justifyContent: ['center', 'start', 'start'],
alignItems: 'center',
gap: 2,
width: '100%',
mt: -1,
mb: -2,
flexWrap: 'wrap'
}}
>
{tags.forOrg(modalOrganization).map((tag, i) => (
<ThemeBadge
key={i}
as="span"
aria-label="Hello there"
sx={{
bg: tag.color,
color: 'snow',
fontSize: '20px',
textShadow: 'none',
borderRadius: '15px',
px: 2,
display: 'block'
}}
>
{tag.label}
</ThemeBadge>
))}
{badges.forOrg(modalOrganization).map((badge, i) => {
return (
<Tooltip.N key={i} text={badge.tooltip} id={badge.id}>
<span class={`tooltipped-${badge.id}`}>
<Badge badge={badge} />
</span>
</Tooltip.N>
)
})}
</Flex>
<Flex
sx={{
flexDirection: 'row',
alignItems: 'start',
gap: 4,
width: '100%'
}}
>
{/* info & buttons */}
<Flex
sx={{
flexDirection: 'column',
alignItems: 'start',
flex: '1'
}}
>
<Text variant="lead" style={{ fontSize: '22px' }}>
{modalOrganization.branding.description}
</Text>
{/* mobile stats */}
<Flex
sx={{
my: 3,
display: ['flex', 'flex', 'none'],
width: '100%',
gap: 2,
flexWrap: 'wrap',
flexDirection: 'row',
alignItems: 'start',
alignSelf: 'start'
}}
>
<Text
variant="subheadline"
sx={{
mb: 0,
color: '#3b4858',
marginRight: 2
}}
>
{modalOrganization.location.country}
</Text>
<Text
variant="subheadline"
sx={{
mb: 0,
color: '#3b4858'
}}
>
{modalOrganization.location.continent}
</Text>
</Flex>
<Flex
sx={{
flexDirection: 'column',
alignItems: 'start',
my: 2,
ml: -1,
gap: 1
}}
>
{modalOrganization.links.website && (
<Flex
as="a"
target="_blank"
href={modalOrganization.links.website}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="web" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Website
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
{modalOrganization.links.financials && (
<Flex
as="a"
target="_blank"
href={modalOrganization.links.financials}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="explore" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Transparent Finances
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
</Flex>
</Flex>
{/* desktop stats */}
<Flex
sx={{
display: ['none', 'none', 'flex'],
maxWidth: '30%',
flexDirection: 'column',
alignItems: 'start',
alignSelf: 'start'
}}
>
<Flex sx={{ flexDirection: 'column', alignItems: 'start' }}>
<Text
variant="headline"
sx={{
mb: 0,
color: '#3b4858'
}}
>
{modalOrganization.location.country}
</Text>
<Text
sx={{
color: '#5b616a',
fontSize: '20px'
}}
>
Country
</Text>
</Flex>
<Flex sx={{ flexDirection: 'column', alignItems: 'start' }}>
<Text
variant="headline"
sx={{
mb: 0,
color: '#3b4858'
}}
>
{modalOrganization.location.continent}
</Text>
<Text
sx={{
color: '#5b616a',
fontSize: '20px'
}}
>
Continent
</Text>
</Flex>
</Flex>
</Flex>
<Flex
sx={{
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
alignItems: 'center'
}}
>
<Button
as="a"
variant="lg"
href={modalOrganization.links.donations}
target="_blank"
sx={{
backgroundImage: t => t.util.gx('green', 'blue'),
width: ['100%', 'auto', 'auto']
}}
>
<Flex
sx={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
width: '24px',
height: '24px',
marginLeft: -1,
marginRight: 2
}}
>
<Icon glyph="friend" size={20} style={{ scale: '2.5' }} />
</Flex>
Make a Donation
</Button>
<Text sx={{ display: ['none', 'none', 'block'] }}>
All donations are tax-deductible.
</Text>
</Flex>
</Flex>
</Card>
</Box>
)} )}
<Box as="main" key="main"> <Box as="main" key="main">
{!modalOrganization && <Nav light />} {!modalOrganization && <Nav light />}