Skip to content

Commit

Permalink
Merge branch 'master' into feat/ownership-requests
Browse files Browse the repository at this point in the history
  • Loading branch information
gabeweng authored Nov 1, 2024
2 parents d5e4b6c + 63c7a7d commit c78c410
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 395 deletions.
51 changes: 50 additions & 1 deletion backend/clubs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6758,6 +6758,52 @@ def remove_clubs_from_exception(self, *args, **kwargs):
)
return Response([])

@action(detail=True, methods=["GET"])
def club_applications(self, *args, **kwargs):
"""
Retrieve club applications for given cycle
---
requestBody:
content: {}
responses:
"200":
content:
application/json:
schema:
type: array
items:
type: object
properties:
name:
type: string
id:
type: integer
application_end_time:
type: string
format: date-time
application_end_time_exception:
type: string
club__name:
type: string
club__code:
type: string
---
"""
cycle = self.get_object()

return Response(
ClubApplication.objects.filter(application_cycle=cycle)
.select_related("club")
.values(
"name",
"id",
"application_end_time",
"application_end_time_exception",
"club__name",
"club__code",
)
)

@action(detail=True, methods=["GET"])
def applications(self, *args, **kwargs):
"""
Expand All @@ -6766,7 +6812,10 @@ def applications(self, *args, **kwargs):
requestBody: {}
responses:
"200":
content: {}
content:
text/csv:
schema:
type: string
---
"""
cycle = self.get_object()
Expand Down
4 changes: 3 additions & 1 deletion frontend/components/ClubCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ const ClubCard = ({ club, fullWidth }: ClubCardProps): ReactElement => {
const { name, active, approved, subtitle, tags, enables_subscription, code } =
club
const img = club.image_url
const textDescription = shorten(subtitle || 'This club has no description.')
const textDescription = shorten(
subtitle || 'This club has not provided a mission statement.',
)

return (
<CardWrapper className={fullWidth ? '' : 'column is-half-desktop'}>
Expand Down
59 changes: 57 additions & 2 deletions frontend/components/ClubEditPage/ClubEditCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ import {
SITE_ID,
SITE_NAME,
} from '../../utils/branding'
import { ModalContent } from '../ClubPage/Actions'
import { LiveBanner, LiveSub, LiveTitle } from '../ClubPage/LiveEventsDialog'
import { Checkbox, CheckboxLabel, Contact, Text } from '../common'
import { Checkbox, CheckboxLabel, Contact, Modal, Text } from '../common'
import {
CheckboxField,
CheckboxTextField,
Expand Down Expand Up @@ -189,6 +190,7 @@ export default function ClubEditCard({
isEdit,
onSubmit = () => Promise.resolve(undefined),
}: ClubEditCardProps): ReactElement {
const [showRankModal, setShowRankModal] = useState<boolean>(false)
const [showTargetFields, setShowTargetFields] = useState<boolean>(
!!(
club.target_majors?.length ||
Expand Down Expand Up @@ -397,6 +399,58 @@ export default function ClubEditCard({
{
name: 'General',
type: 'group',
description: (
<div className="mb-4">
<a onClick={() => setShowRankModal(true)}>
How does filling out this information affect your club?
</a>
<Modal
show={showRankModal}
closeModal={() => setShowRankModal(false)}
marginBottom={false}
width="80%"
>
<ModalContent className="content mb-4">
<h2>How we calculate club rankings</h2>
<hr />
<h5>
The following positively affects your club's ranking in homepage
search results:
</h5>
<ul>
<li>
Upcoming events with filled out name, description, and image
</li>
<li>Upcoming, open applications for membership</li>
<li>
Having at least 3 active officers, plus a bonus for any
additional non-officer member on the platform
</li>
<li>
Having between 3 and 7 useful tags (please email <Contact />{' '}
if none apply)
</li>
<li>
Posting a public (non-personal) contact email and 2 or more
social links
</li>
<li>
Having a club logo image uploaded and subtitle filled out
</li>
<li>
Filling out a club mission with images and detail (rewarded up
to 1000 words)
</li>
<li>Displaying 3 or more student testimonials (experiences)</li>
<li>Filling out the {FIELD_PARTICIPATION_LABEL} section</li>
<li>
Updating the club listing recently (within the last 8 months)
</li>
</ul>
</ModalContent>
</Modal>
</div>
),
fields: [
{
name: 'name',
Expand Down Expand Up @@ -446,8 +500,9 @@ export default function ClubEditCard({
},
{
name: 'description',
label: 'Club Mission',
required: true,
placeholder: `Type your ${OBJECT_NAME_SINGULAR} description here!`,
placeholder: `Type your ${OBJECT_NAME_SINGULAR} mission here!`,
type: 'html',
hidden: !REAPPROVAL_QUEUE_ENABLED,
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/ClubPage/Description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Props = {
const Description = ({ club }: Props): ReactElement => (
<Wrapper>
<div style={{ width: '100%' }}>
<StrongText>Description</StrongText>
<StrongText>Club Mission</StrongText>
<div
className="content"
dangerouslySetInnerHTML={{
Expand Down
5 changes: 2 additions & 3 deletions frontend/components/EmbedOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,8 @@ const EmbedOption = (props: Props): ReactElement => {
<h1>Embed Content</h1>
<p>
You can use this tool to embed multimedia content into your club
description. If you run into any issues using the tool, please
contact <Contact />. Here are examples of some of the things you can
embed.
mission. If you run into any issues using the tool, please contact{' '}
<Contact />. Here are examples of some of the things you can embed.
</p>
<div className="content mb-3">
<ul>
Expand Down
81 changes: 61 additions & 20 deletions frontend/components/Settings/WhartonApplicationCycles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import ModelForm from '../ModelForm'

const fields = (
<>
<Field name="name" as={TextField} />
<Field name="start_date" as={DateTimeField} />
<Field name="end_date" as={DateTimeField} />
<Field name="release_date" as={DateTimeField} />
<Field name="name" as={TextField} required />
<Field name="start_date" as={DateTimeField} required />
<Field name="end_date" as={DateTimeField} required />
<Field name="release_date" as={DateTimeField} required />
</>
)

type Cycle = {
name: string
id: number | null
endDate: Date
}

type ClubOption = {
Expand All @@ -35,7 +36,8 @@ type ExtensionOption = {
clubName: string
endDate: Date
exception?: boolean
changed: boolean
originalEndDate: Date
originalException: boolean
}

const ScrollWrapper = styled.div`
Expand All @@ -44,17 +46,24 @@ const ScrollWrapper = styled.div`
height: 40vh;
`

type ClubApplicationWithClub = ClubApplication & {
club__name: string
club__code: number
}

const WhartonApplicationCycles = (): ReactElement => {
const [editMembership, setEditMembership] = useState(false)
const [membershipCycle, setMembershipCycle] = useState<Cycle>({
name: '',
id: null,
endDate: new Date(),
})

const [editExtensions, setEditExtensions] = useState(false)
const [extensionsCycle, setExtensionsCycle] = useState<Cycle>({
name: '',
id: null,
endDate: new Date(),
})

const [clubsSelectedMembership, setClubsSelectedMembership] = useState<
Expand All @@ -81,7 +90,10 @@ const WhartonApplicationCycles = (): ReactElement => {
const closeExtensionsModal = (): void => {
setEditExtensions(false)
// calculate clubs that have changed
const clubsToUpdate = clubsExtensions.filter((x) => x.changed)
const clubsToUpdate = clubsExtensions.filter(
(x) =>
x.originalEndDate !== x.endDate || x.originalException !== x.exception,
)
// split into clubs with exceptions and clubs without
const clubsExceptions = clubsToUpdate.filter((x) => x.exception)
const clubsNoExceptions = clubsToUpdate.filter((x) => !x.exception)
Expand Down Expand Up @@ -147,18 +159,23 @@ const WhartonApplicationCycles = (): ReactElement => {

useEffect(() => {
if (extensionsCycle && extensionsCycle.id != null) {
doApiRequest(`/cycles/${extensionsCycle.id}/clubs?format=json`)
doApiRequest(
`/cycles/${extensionsCycle.id}/club_applications?format=json`,
)
.then((resp) => resp.json())
.then((data) => {
const initialOptions = data.map((club: ClubApplication) => {
return {
id: club.id,
clubName: club.name,
endDate: new Date(club.application_end_time),
exception: club.application_end_time_exception,
changed: false,
}
})
const initialOptions = data.map(
(application: ClubApplicationWithClub) => {
return {
id: application.id,
clubName: application.club__name,
endDate: new Date(application.application_end_time),
exception: application.application_end_time_exception,
originalEndDate: new Date(application.application_end_time),
originalException: application.application_end_time_exception,
}
},
)
setClubsExtensions(initialOptions)
})
}
Expand Down Expand Up @@ -190,7 +207,11 @@ const WhartonApplicationCycles = (): ReactElement => {
<button
className="button is-info is-small"
onClick={() => {
setMembershipCycle({ name: object.name, id: object.id })
setMembershipCycle({
name: object.name,
id: object.id,
endDate: new Date(object.end_date),
})
setEditMembership(true)
setEditExtensions(false)
}}
Expand All @@ -200,7 +221,11 @@ const WhartonApplicationCycles = (): ReactElement => {
<button
className="button is-info is-small"
onClick={() => {
setExtensionsCycle({ name: object.name, id: object.id })
setExtensionsCycle({
name: object.name,
id: object.id,
endDate: new Date(object.end_date),
})
setEditExtensions(true)
setEditMembership(false)
}}
Expand Down Expand Up @@ -290,7 +315,6 @@ const WhartonApplicationCycles = (): ReactElement => {
selected={club.endDate}
onChange={(date) => {
club.endDate = date
club.changed = true
setClubsExtensions([...clubsExtensions])
}}
/>
Expand All @@ -299,7 +323,6 @@ const WhartonApplicationCycles = (): ReactElement => {
<Checkbox
onChange={(e) => {
club.exception = e.target.checked
club.changed = true
setClubsExtensions([...clubsExtensions])
}}
checked={
Expand All @@ -320,9 +343,27 @@ const WhartonApplicationCycles = (): ReactElement => {
className="button is-primary"
style={{ position: 'absolute', bottom: 10, right: 10 }}
onClick={closeExtensionsModal}
disabled={clubsExtensions.some(
(x) =>
// For the case where we change end date without giving an exception to a club without one
!x.exception &&
!x.originalException &&
x.endDate.getTime() !== extensionsCycle.endDate.getTime(),
)}
>
Submit
</button>
{clubsExtensions.some(
(x) =>
!x.exception &&
!x.originalException &&
x.endDate.getTime() !== extensionsCycle.endDate.getTime(),
) && (
<p className="is-danger">
To change the end date for a club, you must also check its
exception box.
</p>
)}
</>
)}
</Modal>
Expand Down
2 changes: 1 addition & 1 deletion frontend/pages/club/[club]/renew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ const RenewPage = (props: RenewPageProps): ReactElement => {
name: 'University Affiliation',
content: (
<div>
The club description must clearly state that the group is a student
The club mission must clearly state that the group is a student
organization at the University.
</div>
),
Expand Down
Loading

0 comments on commit c78c410

Please sign in to comment.