+
{
+ setTicket({ ...ticket, name: e.target.value })
+ onChange?.({ ...ticket, name: e.target.value })
+ }}
/>
{
+ const count = e.target.value
+ setTicket({ ...ticket, count })
+ onChange?.({ ...ticket, count })
+ }}
/>
{
+ const price = e.target.value
+ setTicket({ ...ticket, price })
+ onChange?.({ ...ticket, price })
+ }}
/>
+
+
+
+
+ {openGroupDiscount ? (
+ <>
+
+ {
+ const groupDiscount = e.target.value
+ setTicket({ ...ticket, groupDiscount })
+ onChange?.({ ...ticket, groupDiscount })
+ }}
+ />
+
+
% Discount for
+
+ {
+ const groupNumber = e.target.value
+ setTicket({ ...ticket, groupNumber })
+ onChange?.({ ...ticket, groupNumber })
+ }}
+ />
+
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+
)
}
@@ -129,46 +203,43 @@ type Ticket = {
name: string
count: string | null
price: string | null // Free if null
+ groupDiscount: string | null // If null, no group discount
+ groupNumber: string | null // If null, no group discount
}
-const TicketsModal = (props: { event: ClubEvent }): ReactElement => {
- const { event } = props
+const TicketsModal = ({
+ event,
+ onSuccessfulSubmit,
+}: {
+ event: ClubEvent
+ onSuccessfulSubmit: () => void
+}): ReactElement => {
const { large_image_url, image_url, club_name, name, id } = event
const [submitting, setSubmitting] = useState(false)
const [tickets, setTickets] = useState
([
- { name: 'Regular Ticket', count: null, price: null },
+ {
+ name: 'Regular Ticket',
+ count: null,
+ price: null,
+ groupDiscount: null,
+ groupNumber: null,
+ },
])
- const handleNameChange = (name, i) => {
- const ticks = [...tickets]
- ticks[i].name = name
- setTickets(ticks)
- }
-
- const handleCountChange = (count, i) => {
- const ticks = [...tickets]
- ticks[i].count = count
- setTickets(ticks)
- }
-
- const handlePriceChange = (price, i) => {
- const ticks = [...tickets]
- ticks[i].price = price
- setTickets(ticks)
- }
-
- const deleteTicket = (i) => {
- const ticks = [...tickets]
- ticks.splice(i, 1)
- setTickets(ticks)
- }
-
const addNewTicket = () => {
const ticks = [...tickets]
- ticks.push({ name: '', count: null, price: null })
- setTickets(ticks)
+ setTickets([
+ ...ticks,
+ {
+ name: '',
+ count: null,
+ price: null,
+ groupDiscount: null,
+ groupNumber: null,
+ },
+ ])
}
const submit = () => {
@@ -176,10 +247,17 @@ const TicketsModal = (props: { event: ClubEvent }): ReactElement => {
const quantities = tickets
.filter((ticket) => ticket.count != null)
.map((ticket) => {
+ const usingGroupPricing = ticket.groupDiscount && ticket.groupNumber
return {
type: ticket.name,
- count: parseInt(ticket.count || ''),
- price: parseFloat(ticket.price || ''),
+ count: parseInt(ticket.count ?? '0'),
+ price: parseFloat(ticket.price ?? '0'),
+ groupDiscount: usingGroupPricing
+ ? parseFloat(ticket.groupDiscount!)
+ : null,
+ groupNumber: usingGroupPricing
+ ? parseFloat(ticket.groupNumber!)
+ : null,
}
})
doApiRequest(`/events/${id}/tickets/?format=json`, {
@@ -191,6 +269,7 @@ const TicketsModal = (props: { event: ClubEvent }): ReactElement => {
if (res.ok) {
notify(<>Tickets Created!>, 'success')
setSubmitting(false)
+ onSuccessfulSubmit()
} else {
notify(<>Error creating tickets>, 'error')
setSubmitting(false)
@@ -207,7 +286,8 @@ const TicketsModal = (props: { event: ClubEvent }): ReactElement => {
parseInt(ticket.count || '0') < 0 ||
ticket.price === null ||
!Number.isFinite(parseFloat(ticket.price || '0')) ||
- parseFloat(ticket.price || '0') < 0,
+ parseFloat(ticket.price || '0') < 0 ||
+ (ticket.groupNumber != null && parseFloat(ticket.price || '0') < 0),
)
return (
@@ -228,13 +308,17 @@ const TicketsModal = (props: { event: ClubEvent }): ReactElement => {
{tickets.map((ticket, index) => (
1}
+ onChange={(newTicket) => {
+ setTickets((t) =>
+ t.map((t, i) => (i === index ? newTicket : t)),
+ )
+ }}
+ onDelete={() => {
+ setTickets((t) => t.filter((_, i) => i !== index))
+ }}
/>
))}
diff --git a/frontend/pages/events/[id].tsx b/frontend/pages/events/[id].tsx
index ce77c4f44..b0032b563 100644
--- a/frontend/pages/events/[id].tsx
+++ b/frontend/pages/events/[id].tsx
@@ -2,6 +2,7 @@ import { DateTime, Settings } from 'luxon'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import Link from 'next/link'
import React, { useState } from 'react'
+import { toast } from 'react-toastify'
import styled from 'styled-components'
import { BaseLayout } from '~/components/BaseLayout'
@@ -14,12 +15,18 @@ import {
Title,
} from '~/components/common'
import {
+ ALLBIRDS_GRAY,
+ BODY_FONT,
BORDER,
+ BORDER_RADIUS,
CLUBS_BLUE,
+ CLUBS_GREY,
CLUBS_LIGHT_BLUE,
+ FOCUS_GRAY,
mediaMaxWidth,
mediaMinWidth,
PHONE,
+ WHITE,
} from '~/constants'
import { Club, ClubEvent, TicketAvailability } from '~/types'
import { doApiRequest } from '~/utils'
@@ -118,6 +125,86 @@ const Divider = styled.hr`
margin: 20px 0;
`
+const Input = styled.input`
+ border: 1px solid ${ALLBIRDS_GRAY};
+ outline: none;
+ color: ${CLUBS_GREY};
+ flex: 0 0 auto;
+ font-size: 1em;
+ padding: 8px 10px;
+ margin: 0px 5px 0px 0px;
+ background: ${WHITE};
+ border-radius: ${BORDER_RADIUS};
+ min-width: 50px;
+ font-family: ${BODY_FONT};
+ &:hover,
+ &:active,
+ &:focus {
+ background: ${FOCUS_GRAY};
+ }
+`
+
+type Ticket = {
+ type: string
+ price: string
+ max: string
+ count: number | null
+}
+
+type TicketItemProps = {
+ ticket: Ticket
+ name: string
+ price: string
+ max: string
+ onCountChange: (newCount: number) => void
+}
+
+const TicketItem: React.FC = ({
+ ticket,
+ name,
+ price,
+ max,
+ onCountChange,
+}) => {
+ const [count, setCount] = useState(ticket.count)
+ const handleCountChange = (e: React.ChangeEvent) => {
+ // Round to nearest integer and clamp to min/max
+ const value = Math.max(
+ 0,
+ Math.min(Math.round(parseFloat(e.target.value)), parseInt(max, 10)),
+ )
+ setCount(value)
+ onCountChange(value)
+ }
+
+ return (
+
+
+
+ {name} - ${price}
+
+
+
+
+ )
+}
+
const EventPage: React.FC = ({
baseProps,
club,
@@ -136,10 +223,20 @@ const EventPage: React.FC = ({
total: cur.count,
available:
tickets.available.find((t) => t.type === cur.type)?.count ?? 0,
+ price: cur.price,
},
}),
{},
- ) as Record
+ ) as Record
+
+ const [order, setOrder] = useState(
+ Object.entries(ticketMap).map(([type, counts]) => ({
+ type,
+ price: counts.price.toString(),
+ max: counts.total.toString(),
+ count: 0,
+ })),
+ )
const totalAvailableTickets = Object.values(ticketMap)
.map((k) => k.available)
@@ -150,8 +247,47 @@ const EventPage: React.FC = ({
setShowTicketModal(false)}
+ marginBottom={false}
>
- Get Tickets
+ Get Tickets
+ {order.map((ticket, index) => (
+ {
+ const ticks = [...order]
+ ticks[index].count = count
+ setOrder(ticks)
+ }}
+ />
+ ))}
+
diff --git a/frontend/types.ts b/frontend/types.ts
index e3efd4c27..d994a6836 100644
--- a/frontend/types.ts
+++ b/frontend/types.ts
@@ -406,6 +406,7 @@ export type ApplicationResponse = {
export type TicketEntry = {
type: string
count: number
+ price: number
}
export type TicketAvailability = {
diff --git a/frontend/utils/branding.tsx b/frontend/utils/branding.tsx
index 06c9ed995..325688184 100644
--- a/frontend/utils/branding.tsx
+++ b/frontend/utils/branding.tsx
@@ -7,39 +7,39 @@ const { publicRuntimeConfig } = getConfig()
const site = publicRuntimeConfig.NEXT_PUBLIC_SITE_NAME
const sites = {
- clubs: {
- SITE_NAME: 'Penn Clubs',
- SCHOOL_NAME: 'University of Pennsylvania',
- SITE_SUBTITLE: 'Student Organizations at the University of Pennsylvania',
- DOMAIN: 'pennclubs.com',
-
- OBJECT_NAME_PLURAL: 'clubs',
- OBJECT_NAME_LONG_PLURAL: 'student organizations',
- OBJECT_NAME_SINGULAR: 'club',
-
- OBJECT_NAME_TITLE: 'Clubs',
- OBJECT_NAME_TITLE_SINGULAR: 'Club',
-
- SITE_LOGO: '/static/img/peoplelogo.png',
- LOGO_BACKGROUND_IMAGE: null,
- HEADER_BACKGROUND_IMAGE: null,
- HEADER_OVERLAY: null,
- SITE_FAVICON: '/static/favicon.ico',
- SITE_TAGLINE: 'Find your people!',
- OG_IMAGE:
- 'https://pennlabs-assets.s3.amazonaws.com/metadata-images/penn-clubs.png',
-
- APPROVAL_AUTHORITY: 'Office of Student Affairs',
- APPROVAL_AUTHORITY_URL: 'https://osa.vpul.upenn.edu/',
-
- FIELD_PARTICIPATION_LABEL: 'How to Get Involved',
-
- OBJECT_URL_SLUG: 'club',
- OBJECT_TAB_MEMBERSHIP_LABEL: 'Membership',
- OBJECT_TAB_RECRUITMENT_LABEL: 'Recruitment',
- OBJECT_TAB_ADMISSION_LABEL: 'Admission',
- OBJECT_TAB_FILES_DESCRIPTION:
- 'You can upload club constitutions here. Please upload your club constitution in pdf or docx format.',
+ clubs: {
+ SITE_NAME: 'Penn Clubs',
+ SCHOOL_NAME: 'University of Pennsylvania',
+ SITE_SUBTITLE: 'Student Organizations at the University of Pennsylvania',
+ DOMAIN: 'pennclubs.com',
+
+ OBJECT_NAME_PLURAL: 'clubs',
+ OBJECT_NAME_LONG_PLURAL: 'student organizations',
+ OBJECT_NAME_SINGULAR: 'club',
+
+ OBJECT_NAME_TITLE: 'Clubs',
+ OBJECT_NAME_TITLE_SINGULAR: 'Club',
+
+ SITE_LOGO: '/static/img/peoplelogo.png',
+ LOGO_BACKGROUND_IMAGE: null,
+ HEADER_BACKGROUND_IMAGE: null,
+ HEADER_OVERLAY: null,
+ SITE_FAVICON: '/static/favicon.ico',
+ SITE_TAGLINE: 'Find your people!',
+ OG_IMAGE:
+ 'https://pennlabs-assets.s3.amazonaws.com/metadata-images/penn-clubs.png',
+
+ APPROVAL_AUTHORITY: 'Office of Student Affairs',
+ APPROVAL_AUTHORITY_URL: 'https://osa.vpul.upenn.edu/',
+
+ FIELD_PARTICIPATION_LABEL: 'How to Get Involved',
+
+ OBJECT_URL_SLUG: 'club',
+ OBJECT_TAB_MEMBERSHIP_LABEL: 'Membership',
+ OBJECT_TAB_RECRUITMENT_LABEL: 'Recruitment',
+ OBJECT_TAB_ADMISSION_LABEL: 'Admission',
+ OBJECT_TAB_FILES_DESCRIPTION:
+ 'You can upload club constitutions here. Please upload your club constitution in pdf or docx format.',
CONTACT_EMAIL: 'contact@pennclubs.com',
SUPPORT_EMAIL: 'vpul-orgs@pobox.upenn.edu',
@@ -80,175 +80,175 @@ const sites = {
// show feedback icon on bottom right
SHOW_FEEDBACK: true,
- MEMBERSHIP_ROLE_NAMES: { 0: 'Owner', 10: 'Officer', 20: 'Member' },
- OBJECT_MEMBERSHIP_LABEL: 'Members',
- OBJECT_MEMBERSHIP_LABEL_LOWERCASE: "member's",
- OBJECT_INVITE_LABEL: 'Members',
- OBJECT_EVENT_TYPES: [
- ClubEventType.RECRUITMENT,
- ClubEventType.GBM,
- ClubEventType.SPEAKER,
- ClubEventType.FAIR,
- ClubEventType.OTHER,
- ],
-
- FORM_DESCRIPTION_EXAMPLES: 'Penn Labs',
- FORM_TAG_DESCRIPTION:
- 'You will need to at least specify either the Undergraduate or Graduate tag.',
- FORM_LOGO_DESCRIPTION:
- 'Changing this field will require reapproval from the Office of Student Affairs.',
- FORM_TARGET_DESCRIPTION: (
- <>
- Does your club restrict membership to certain student groups? If
- you are only looking for certain student groups during your recruitment
- process, please specify those groups here. Otherwise, we will assume
- that you are targeting the general student population.
- >
- ),
- OBJECT_MEMBERSHIP_DEFAULT_TITLE: 'Member',
- CLUB_EMPTY_STATE: (
- <>
- Looking for university resources? Check out{' '}
- Hub@Penn!
- >
- ),
-
- PARTNER_LOGOS: [
- {
- name: 'Student Activities Council',
- image: '/static/img/collaborators/sac.png',
- url: 'https://sacfunded.net/',
- },
- {
- name: 'Undergraduate Assembly',
- image: '/static/img/collaborators/ua.png',
- url: 'https://pennua.org/',
- height: 80,
- },
- {
- name: 'Office of Student Affairs',
- image: '/static/img/collaborators/osa.png',
- url: 'https://www.vpul.upenn.edu/osa/',
- className: 'mr-4',
- },
- {
- name: 'Engineering Student Activities Council',
- image: '/static/img/collaborators/esac.png',
- url: 'https://esac.squarespace.com/',
- height: 80,
- },
- ],
- GA_TRACKING_CODE: 'UA-21029575-14',
- FAIR_NAME: 'activities',
- FAIR_NAME_CAPITALIZED: 'Activities',
- },
- fyh: {
- SITE_NAME: 'Hub@Penn',
- SCHOOL_NAME: 'University of Pennsylvania',
- SITE_SUBTITLE: 'Student Resources at the University of Pennsylvania',
- DOMAIN: 'hub.provost.upenn.edu',
-
- OBJECT_NAME_PLURAL: 'resources',
- OBJECT_NAME_LONG_PLURAL: 'university resources',
- OBJECT_NAME_SINGULAR: 'resource',
-
- OBJECT_NAME_TITLE: 'Resources',
- OBJECT_NAME_TITLE_SINGULAR: 'Resource',
-
- SITE_LOGO: '/static/img/penn_shield.png',
- LOGO_BACKGROUND_IMAGE: '/static/img/penn_header_fade.png',
- HEADER_BACKGROUND_IMAGE: '/static/img/hub_banner.png',
- HEADER_OVERLAY: '/static/img/platform-start-point.png',
- SITE_FAVICON: '/static/penn_favicon.ico',
- SITE_TAGLINE:
- "Find the support resources you need on and around Penn's campus!",
- OG_IMAGE:
- 'https://pennlabs-assets.s3.amazonaws.com/metadata-images/hub-at-penn.png',
-
- APPROVAL_AUTHORITY: 'Hub@Penn administrators',
- APPROVAL_AUTHORITY_URL: '/faq',
-
- FIELD_PARTICIPATION_LABEL: 'Services Offered',
-
- OBJECT_URL_SLUG: 'org',
- OBJECT_TAB_MEMBERSHIP_LABEL: 'Admins',
- OBJECT_TAB_RECRUITMENT_LABEL: 'Mailing List',
- OBJECT_TAB_ADMISSION_LABEL: 'Usage',
- OBJECT_TAB_FILES_DESCRIPTION: null,
- OBJECT_EVENT_TYPES: [
- ClubEventType.SOCIAL,
- ClubEventType.CAREER,
- ClubEventType.SPEAKER,
- ClubEventType.FAIR,
- ClubEventType.OTHER,
- ],
+ MEMBERSHIP_ROLE_NAMES: { 0: 'Owner', 10: 'Officer', 20: 'Member' },
+ OBJECT_MEMBERSHIP_LABEL: 'Members',
+ OBJECT_MEMBERSHIP_LABEL_LOWERCASE: "member's",
+ OBJECT_INVITE_LABEL: 'Members',
+ OBJECT_EVENT_TYPES: [
+ ClubEventType.RECRUITMENT,
+ ClubEventType.GBM,
+ ClubEventType.SPEAKER,
+ ClubEventType.FAIR,
+ ClubEventType.OTHER,
+ ],
+
+ FORM_DESCRIPTION_EXAMPLES: 'Penn Labs',
+ FORM_TAG_DESCRIPTION:
+ 'You will need to at least specify either the Undergraduate or Graduate tag.',
+ FORM_LOGO_DESCRIPTION:
+ 'Changing this field will require reapproval from the Office of Student Affairs.',
+ FORM_TARGET_DESCRIPTION: (
+ <>
+ Does your club restrict membership to certain student groups? If
+ you are only looking for certain student groups during your recruitment
+ process, please specify those groups here. Otherwise, we will assume
+ that you are targeting the general student population.
+ >
+ ),
+ OBJECT_MEMBERSHIP_DEFAULT_TITLE: 'Member',
+ CLUB_EMPTY_STATE: (
+ <>
+ Looking for university resources? Check out{' '}
+ Hub@Penn!
+ >
+ ),
+
+ PARTNER_LOGOS: [
+ {
+ name: 'Student Activities Council',
+ image: '/static/img/collaborators/sac.png',
+ url: 'https://sacfunded.net/',
+ },
+ {
+ name: 'Undergraduate Assembly',
+ image: '/static/img/collaborators/ua.png',
+ url: 'https://pennua.org/',
+ height: 80,
+ },
+ {
+ name: 'Office of Student Affairs',
+ image: '/static/img/collaborators/osa.png',
+ url: 'https://www.vpul.upenn.edu/osa/',
+ className: 'mr-4',
+ },
+ {
+ name: 'Engineering Student Activities Council',
+ image: '/static/img/collaborators/esac.png',
+ url: 'https://esac.squarespace.com/',
+ height: 80,
+ },
+ ],
+ GA_TRACKING_CODE: 'UA-21029575-14',
+ FAIR_NAME: 'activities',
+ FAIR_NAME_CAPITALIZED: 'Activities',
+ },
+ fyh: {
+ SITE_NAME: 'Hub@Penn',
+ SCHOOL_NAME: 'University of Pennsylvania',
+ SITE_SUBTITLE: 'Student Resources at the University of Pennsylvania',
+ DOMAIN: 'hub.provost.upenn.edu',
+
+ OBJECT_NAME_PLURAL: 'resources',
+ OBJECT_NAME_LONG_PLURAL: 'university resources',
+ OBJECT_NAME_SINGULAR: 'resource',
+
+ OBJECT_NAME_TITLE: 'Resources',
+ OBJECT_NAME_TITLE_SINGULAR: 'Resource',
+
+ SITE_LOGO: '/static/img/penn_shield.png',
+ LOGO_BACKGROUND_IMAGE: '/static/img/penn_header_fade.png',
+ HEADER_BACKGROUND_IMAGE: '/static/img/hub_banner.png',
+ HEADER_OVERLAY: '/static/img/platform-start-point.png',
+ SITE_FAVICON: '/static/penn_favicon.ico',
+ SITE_TAGLINE:
+ "Find the support resources you need on and around Penn's campus!",
+ OG_IMAGE:
+ 'https://pennlabs-assets.s3.amazonaws.com/metadata-images/hub-at-penn.png',
+
+ APPROVAL_AUTHORITY: 'Hub@Penn administrators',
+ APPROVAL_AUTHORITY_URL: '/faq',
+
+ FIELD_PARTICIPATION_LABEL: 'Services Offered',
+
+ OBJECT_URL_SLUG: 'org',
+ OBJECT_TAB_MEMBERSHIP_LABEL: 'Admins',
+ OBJECT_TAB_RECRUITMENT_LABEL: 'Mailing List',
+ OBJECT_TAB_ADMISSION_LABEL: 'Usage',
+ OBJECT_TAB_FILES_DESCRIPTION: null,
+ OBJECT_EVENT_TYPES: [
+ ClubEventType.SOCIAL,
+ ClubEventType.CAREER,
+ ClubEventType.SPEAKER,
+ ClubEventType.FAIR,
+ ClubEventType.OTHER,
+ ],
CONTACT_EMAIL: 'hub.provost@upenn.edu',
SUPPORT_EMAIL: 'hubcommunications@lists.upenn.edu',
FEEDBACK_URL: 'https://airtable.com/shrv4RfYIddU1i9o6',
- CLUB_FIELDS: [
- 'appointment_needed',
- 'available_virtually',
- 'signature_events',
- 'student_types',
- 'target_schools',
- ],
- SHOW_MEMBERS: false,
- SHOW_MEMBERSHIP_REQUEST: false,
- SHOW_RANK_ALGORITHM: false,
- SHOW_ACCESSIBILITY: true,
- SHOW_ADDITIONAL_LINKS: false,
- SHOW_LEAVE_CONFIRMATION: false,
- SHOW_SEARCHBAR_TOP: true,
- SHOW_APPLICATIONS: false,
- SHOW_ORG_MANAGEMENT: false,
- SHOW_FEEDBACK: true,
-
- MEMBERSHIP_ROLE_NAMES: { 0: 'Owner', 10: 'Editor' },
- OBJECT_MEMBERSHIP_LABEL: 'Staff',
- OBJECT_MEMBERSHIP_LABEL_LOWERCASE: 'staff',
- OBJECT_INVITE_LABEL: 'Editor',
-
- FORM_DESCRIPTION_EXAMPLES:
- 'Office of New Student Orientation & Academic Initiative - NSOAI',
- FORM_TAG_DESCRIPTION:
- 'Tags will allow students to find your resource while filtering Hub@Penn. Select as many as apply.',
- FORM_LOGO_DESCRIPTION: 'Upload your approved Penn logo.',
- FORM_TARGET_DESCRIPTION: (
- <>
-
- Does your resource apply to all undergraduate, graduate, and
- professional Penn students?
- {' '}
- >
- ),
- OBJECT_MEMBERSHIP_DEFAULT_TITLE: '',
- CLUB_EMPTY_STATE: (
- <>
- Looking for student organizations? Check out{' '}
- Penn Clubs!
- >
- ),
-
- PARTNER_LOGOS: [
- {
- name: 'University Life',
- image: '/static/img/collaborators/vpul.png',
- url: 'https://home.vpul.upenn.edu/',
- className: 'mr-4 mb-4',
- },
- {
- name: 'New Student Orientation and Academic Initatives',
- image: '/static/img/collaborators/nsoai.png',
- url: 'https://www.nso.upenn.edu/',
- className: 'mr-4 mb-4',
- },
- ],
- GA_TRACKING_CODE: 'UA-21029575-19',
- FAIR_NAME: 'resource',
- FAIR_NAME_CAPITALIZED: 'Resource',
- },
+ CLUB_FIELDS: [
+ 'appointment_needed',
+ 'available_virtually',
+ 'signature_events',
+ 'student_types',
+ 'target_schools',
+ ],
+ SHOW_MEMBERS: false,
+ SHOW_MEMBERSHIP_REQUEST: false,
+ SHOW_RANK_ALGORITHM: false,
+ SHOW_ACCESSIBILITY: true,
+ SHOW_ADDITIONAL_LINKS: false,
+ SHOW_LEAVE_CONFIRMATION: false,
+ SHOW_SEARCHBAR_TOP: true,
+ SHOW_APPLICATIONS: false,
+ SHOW_ORG_MANAGEMENT: false,
+ SHOW_FEEDBACK: true,
+
+ MEMBERSHIP_ROLE_NAMES: { 0: 'Owner', 10: 'Editor' },
+ OBJECT_MEMBERSHIP_LABEL: 'Staff',
+ OBJECT_MEMBERSHIP_LABEL_LOWERCASE: 'staff',
+ OBJECT_INVITE_LABEL: 'Editor',
+
+ FORM_DESCRIPTION_EXAMPLES:
+ 'Office of New Student Orientation & Academic Initiative - NSOAI',
+ FORM_TAG_DESCRIPTION:
+ 'Tags will allow students to find your resource while filtering Hub@Penn. Select as many as apply.',
+ FORM_LOGO_DESCRIPTION: 'Upload your approved Penn logo.',
+ FORM_TARGET_DESCRIPTION: (
+ <>
+
+ Does your resource apply to all undergraduate, graduate, and
+ professional Penn students?
+ {' '}
+ >
+ ),
+ OBJECT_MEMBERSHIP_DEFAULT_TITLE: '',
+ CLUB_EMPTY_STATE: (
+ <>
+ Looking for student organizations? Check out{' '}
+ Penn Clubs!
+ >
+ ),
+
+ PARTNER_LOGOS: [
+ {
+ name: 'University Life',
+ image: '/static/img/collaborators/vpul.png',
+ url: 'https://home.vpul.upenn.edu/',
+ className: 'mr-4 mb-4',
+ },
+ {
+ name: 'New Student Orientation and Academic Initatives',
+ image: '/static/img/collaborators/nsoai.png',
+ url: 'https://www.nso.upenn.edu/',
+ className: 'mr-4 mb-4',
+ },
+ ],
+ GA_TRACKING_CODE: 'UA-21029575-19',
+ FAIR_NAME: 'resource',
+ FAIR_NAME_CAPITALIZED: 'Resource',
+ },
}
export const SITE_ID = site
@@ -281,18 +281,18 @@ export const HEADER_OVERLAY = sites[site].HEADER_OVERLAY
export const FIELD_PARTICIPATION_LABEL = sites[site].FIELD_PARTICIPATION_LABEL
export const OBJECT_URL_SLUG = sites[site].OBJECT_URL_SLUG
export const OBJECT_TAB_MEMBERSHIP_LABEL =
- sites[site].OBJECT_TAB_MEMBERSHIP_LABEL
+ sites[site].OBJECT_TAB_MEMBERSHIP_LABEL
export const OBJECT_TAB_RECRUITMENT_LABEL =
- sites[site].OBJECT_TAB_RECRUITMENT_LABEL
+ sites[site].OBJECT_TAB_RECRUITMENT_LABEL
export const OBJECT_TAB_ADMISSION_LABEL = sites[site].OBJECT_TAB_ADMISSION_LABEL
export const OBJECT_TAB_FILES_DESCRIPTION =
- sites[site].OBJECT_TAB_FILES_DESCRIPTION
+ sites[site].OBJECT_TAB_FILES_DESCRIPTION
export const SHOW_MEMBERS = sites[site].SHOW_MEMBERS
export const SHOW_MEMBERSHIP_REQUEST = sites[site].SHOW_MEMBERSHIP_REQUEST
export const SHOW_RANK_ALGORITHM = sites[site].SHOW_RANK_ALGORITHM
export const MEMBERSHIP_ROLE_NAMES: { [key: number]: string } =
- sites[site].MEMBERSHIP_ROLE_NAMES
+ sites[site].MEMBERSHIP_ROLE_NAMES
export const SHOW_ACCESSIBILITY = sites[site].SHOW_ACCESSIBILITY
export const SHOW_ADDITIONAL_LINKS = sites[site].SHOW_ADDITIONAL_LINKS
export const SHOW_LEAVE_CONFIRMATION = sites[site].SHOW_LEAVE_CONFIRMATION
@@ -303,9 +303,9 @@ export const SHOW_FEEDBACK = sites[site].SHOW_FEEDBACK
export const OBJECT_MEMBERSHIP_LABEL = sites[site].OBJECT_MEMBERSHIP_LABEL
export const OBJECT_MEMBERSHIP_LABEL_LOWERCASE =
- sites[site].OBJECT_MEMBERSHIP_LABEL_LOWERCASE
+ sites[site].OBJECT_MEMBERSHIP_LABEL_LOWERCASE
export const OBJECT_MEMBERSHIP_DEFAULT_TITLE =
- sites[site].OBJECT_MEMBERSHIP_DEFAULT_TITLE
+ sites[site].OBJECT_MEMBERSHIP_DEFAULT_TITLE
export const OBJECT_EVENT_TYPES = new Set(sites[site].OBJECT_EVENT_TYPES)
export const CLUB_EMPTY_STATE = sites[site].CLUB_EMPTY_STATE
@@ -313,9 +313,9 @@ export const PARTNER_LOGOS = sites[site].PARTNER_LOGOS
export const CLUB_FIELDS = new Set(sites[site].CLUB_FIELDS)
export const ALL_CLUB_FIELDS = new Set(
- Object.values(sites)
- .map(({ CLUB_FIELDS }) => CLUB_FIELDS)
- .flat(),
+ Object.values(sites)
+ .map(({ CLUB_FIELDS }) => CLUB_FIELDS)
+ .flat(),
)
export const GA_TRACKING_CODE = sites[site].GA_TRACKING_CODE
@@ -323,11 +323,11 @@ export const FAIR_NAME = sites[site].FAIR_NAME
export const FAIR_NAME_CAPITALIZED = sites[site].FAIR_NAME_CAPITALIZED
export const FORM_DESCRIPTION_EXAMPLES: ReactNode =
- sites[site].FORM_DESCRIPTION_EXAMPLES
+ sites[site].FORM_DESCRIPTION_EXAMPLES
export const FORM_TAG_DESCRIPTION: ReactNode = sites[site].FORM_TAG_DESCRIPTION
export const FORM_LOGO_DESCRIPTION: ReactNode =
- sites[site].FORM_LOGO_DESCRIPTION
+ sites[site].FORM_LOGO_DESCRIPTION
export const FORM_TARGET_DESCRIPTION: ReactNode =
- sites[site].FORM_TARGET_DESCRIPTION
+ sites[site].FORM_TARGET_DESCRIPTION
export const OBJECT_INVITE_LABEL = sites[site].OBJECT_INVITE_LABEL