Skip to content

Commit 2a4ad5a

Browse files
authored
[PE-6015] Update the remix contest drawer on mobile (#11926)
1 parent afd52b2 commit 2a4ad5a

File tree

3 files changed

+182
-125
lines changed

3 files changed

+182
-125
lines changed

packages/common/src/messages/remixes.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,29 @@ export const remixMessages = {
55
submissions: 'Submission',
66
coSigned: 'Co-Signs',
77
contestEntries: 'Contest Entries',
8-
originalTrack: 'Original Track'
8+
originalTrack: 'Original Track',
9+
10+
// Modal Messages
11+
modalTitle: 'Host Remix Contest',
12+
modalDescription:
13+
'Turn your track into a remix challenge and co-sign your favorite submissions.',
14+
descriptionLabel: 'Contest Description*',
15+
descriptionPlaceholder:
16+
'Write your contest description here. Include clear rules, guidelines, and any other important details you want your fans to know about your contest.',
17+
descriptionError: 'Contest description is required',
18+
prizeInfoLabel: 'Prizes',
19+
prizeInfoPlaceholder:
20+
'Describe what winners will receive. Be clear about how many winners there will be, and what each prize includes (e.g. cash, reposts, feedback, collaborations, etc.)',
21+
deadlineLabel: 'Submission Deadline*',
22+
endDateLabel: 'Last day to submit to contest',
23+
endDateError: 'Contest end date must be in the future within 90 days',
24+
timeLabel: 'Time',
25+
timePlaceholder: '12:00',
26+
timeError: 'Invalid time',
27+
meridianLabel: 'Meridian',
28+
meridianPlaceholder: 'AM',
29+
contestHostingLabel: 'Learn how to host a successful remix contest',
30+
startContest: 'Start Contest',
31+
save: 'Save',
32+
turnOff: 'Turn Off Contest'
933
}

packages/mobile/src/components/host-remix-contest-drawer/HostRemixContestDrawer.tsx

Lines changed: 136 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,30 @@ import {
88
useDeleteEvent,
99
useRemixes
1010
} from '@audius/common/api'
11+
import { remixMessages } from '@audius/common/messages'
1112
import { useHostRemixContestModal } from '@audius/common/store'
1213
import { EventEntityTypeEnum, EventEventTypeEnum } from '@audius/sdk'
1314
import dayjs from 'dayjs'
15+
import { Platform, ScrollView } from 'react-native'
1416

1517
import {
1618
Flex,
1719
Text,
1820
IconTrophy,
19-
Hint,
2021
IconCalendarMonth,
21-
Button
22+
Button,
23+
TextLink
2224
} from '@audius/harmony-native'
25+
import { makeStyles } from 'app/styles'
2326

24-
import { DateTimeInput } from '../core'
27+
import { DateTimeInput, TextInput } from '../core'
2528
import { AppDrawer } from '../drawer'
2629

2730
const MODAL_NAME = 'HostRemixContest'
2831

29-
const messages = {
30-
modalTitle: 'Host Remix Contest',
31-
description:
32-
'Turn your track into a remix challenge and co-sign your favorite submissions.',
33-
endDateTitle: 'Submission Deadline',
34-
hint: 'You can host one contest per song and adjust the submission deadline anytime within 90 days of the contest start.',
35-
dateLabel: 'Last day to submit to contest',
36-
timeLabel: 'Time',
37-
startContestError: 'Contest end date must be in the future within 90 days',
38-
startContest: 'Start Contest',
39-
save: 'Save',
40-
turnOff: 'Turn Off Contest'
41-
}
32+
const maxDescriptionLength = 1000
33+
const maxPrizeInfoLength = 1000
34+
const hostContestUrl = 'https://help.audius.co/artists/hosting-a-remix-contest'
4235

4336
const mergeDateTime = (day: string, time: string) => {
4437
const truncatedReleaseDate = dayjs(day).startOf('day')
@@ -53,11 +46,27 @@ const mergeDateTime = (day: string, time: string) => {
5346
return combinedDateTime
5447
}
5548

49+
const useStyles = makeStyles(({ typography }) => ({
50+
input: {
51+
height: 144,
52+
textAlignVertical: 'top',
53+
fontSize: typography.fontSize.large,
54+
lineHeight:
55+
Platform.OS === 'ios' ? typography.fontSize.xl : typography.fontSize.large
56+
},
57+
labelText: {
58+
fontSize: typography.fontSize.large,
59+
fontFamily: typography.fontByWeight.demiBold,
60+
top: 4
61+
}
62+
}))
63+
5664
export const HostRemixContestDrawer = () => {
5765
const { data, onClose } = useHostRemixContestModal()
5866
const { mutate: createEvent } = useCreateEvent()
5967
const { mutate: deleteEvent } = useDeleteEvent()
6068
const { mutate: updateEvent } = useUpdateEvent()
69+
const styles = useStyles()
6170
const { data: userId } = useCurrentUserId()
6271
const { trackId } = data
6372
const { data: remixContest } = useRemixContest(trackId)
@@ -69,6 +78,16 @@ export const HostRemixContestDrawer = () => {
6978
const hasContestEntries = remixesLoading || remixes?.length
7079
const displayTurnOffButton = !hasContestEntries && isEdit
7180

81+
const remixContestData = remixContest?.eventData
82+
83+
// Form State
84+
const [description, setDescription] = useState(
85+
remixContestData ? remixContestData.description : ''
86+
)
87+
const [descriptionError, setDescriptionError] = useState<boolean>(false)
88+
const [prizeInfo, setPrizeInfo] = useState(
89+
remixContestData ? remixContestData.prizeInfo : ''
90+
)
7291
const [endDate, setEndDate] = useState(
7392
remixContest ? dayjs(remixContest.endDate) : null
7493
)
@@ -104,12 +123,20 @@ export const HostRemixContestDrawer = () => {
104123
)
105124

106125
const handleSubmit = useCallback(() => {
107-
if (endDateError || !trackId || !userId || !endDate) return
126+
setDescriptionError(description.length === 0)
127+
128+
if (endDateError || descriptionError || !trackId || !userId || !endDate) {
129+
return
130+
}
108131

109132
if (isEdit) {
110133
updateEvent({
111134
eventId: remixContest.eventId,
112135
endDate: endDate.toISOString(),
136+
eventData: {
137+
description,
138+
prizeInfo
139+
},
113140
userId
114141
})
115142
} else {
@@ -118,20 +145,27 @@ export const HostRemixContestDrawer = () => {
118145
entityType: EventEntityTypeEnum.Track,
119146
entityId: trackId,
120147
endDate: endDate.toISOString(),
121-
userId
148+
userId,
149+
eventData: {
150+
description,
151+
prizeInfo
152+
}
122153
})
123154
}
124155

125156
onClose()
126157
}, [
158+
description,
127159
endDateError,
160+
descriptionError,
128161
trackId,
129162
userId,
163+
endDate,
130164
isEdit,
131165
onClose,
132166
updateEvent,
133167
remixContest?.eventId,
134-
endDate,
168+
prizeInfo,
135169
createEvent
136170
])
137171

@@ -146,59 +180,95 @@ export const HostRemixContestDrawer = () => {
146180
modalName={MODAL_NAME}
147181
isFullscreen
148182
onClose={onClose}
149-
title={messages.modalTitle}
183+
isGestureSupported={false}
184+
title={remixMessages.modalTitle}
150185
titleIcon={IconTrophy}
151186
>
152-
<Flex h='100%' justifyContent='space-between'>
153-
<Flex pv='xl' ph='l' gap='xl'>
154-
<Text variant='body'>{messages.description}</Text>
155-
<Flex gap='l'>
156-
<Text variant='title' size='l'>
157-
{messages.endDateTitle}
158-
</Text>
159-
<DateTimeInput
160-
mode='date'
161-
date={endDate?.toString() ?? ''}
162-
onChange={handleDateChange}
163-
dateTimeProps={{
164-
minimumDate: new Date(),
165-
maximumDate: dayjs().add(90, 'days').toDate()
166-
}}
167-
inputProps={{
168-
label: messages.dateLabel,
169-
startIcon: IconCalendarMonth,
170-
error: !!endDateError,
171-
helperText: endDateError ? messages.startContestError : ''
172-
}}
173-
/>
174-
<DateTimeInput
175-
mode='time'
176-
date={endDate?.toString() ?? ''}
177-
onChange={handleTimeChange}
178-
inputProps={{ label: messages.timeLabel }}
179-
/>
180-
<Hint>
181-
<Text variant='body' color='subdued'>
182-
{messages.hint}
187+
<ScrollView>
188+
<Flex h='100%' justifyContent='space-between'>
189+
<Flex pv='xl' ph='l' gap='xl'>
190+
<Text variant='body'>{remixMessages.modalDescription}</Text>
191+
<Flex column gap='l'>
192+
<Text variant='title' size='l'>
193+
{remixMessages.descriptionLabel}
183194
</Text>
184-
</Hint>
195+
<TextInput
196+
value={description}
197+
onChangeText={setDescription}
198+
placeholder={remixMessages.descriptionPlaceholder}
199+
multiline
200+
numberOfLines={5}
201+
error={descriptionError}
202+
styles={{
203+
input: styles.input,
204+
labelText: styles.labelText
205+
}}
206+
maxLength={maxDescriptionLength}
207+
/>
208+
<TextLink url={hostContestUrl} variant='visible'>
209+
{remixMessages.contestHostingLabel}
210+
</TextLink>
211+
</Flex>
212+
<Flex column gap='l'>
213+
<Text variant='title' size='l'>
214+
{remixMessages.prizeInfoLabel}
215+
</Text>
216+
<TextInput
217+
value={prizeInfo}
218+
onChangeText={setPrizeInfo}
219+
placeholder={remixMessages.prizeInfoPlaceholder}
220+
multiline
221+
numberOfLines={5}
222+
styles={{
223+
input: styles.input,
224+
labelText: styles.labelText
225+
}}
226+
maxLength={maxPrizeInfoLength}
227+
/>
228+
</Flex>
229+
<Flex column gap='l'>
230+
<Text variant='title' size='l'>
231+
{remixMessages.endDateLabel}
232+
</Text>
233+
<DateTimeInput
234+
mode='date'
235+
date={endDate?.toString() ?? ''}
236+
onChange={handleDateChange}
237+
dateTimeProps={{
238+
minimumDate: new Date(),
239+
maximumDate: dayjs().add(90, 'days').toDate()
240+
}}
241+
inputProps={{
242+
label: remixMessages.endDateLabel,
243+
startIcon: IconCalendarMonth,
244+
error: !!endDateError,
245+
helperText: endDateError ? remixMessages.endDateError : ''
246+
}}
247+
/>
248+
<DateTimeInput
249+
mode='time'
250+
date={endDate?.toString() ?? ''}
251+
onChange={handleTimeChange}
252+
inputProps={{ label: remixMessages.timeLabel }}
253+
/>
254+
</Flex>
185255
</Flex>
186256
</Flex>
187-
<Flex direction='column' gap='l' p='l' pb='3xl' borderTop='strong'>
188-
<Button
189-
disabled={!endDate || endDateError}
190-
variant='primary'
191-
fullWidth
192-
onPress={handleSubmit}
193-
>
194-
{isEdit ? messages.save : messages.startContest}
257+
</ScrollView>
258+
<Flex direction='column' gap='l' p='l' pb='3xl' borderTop='strong'>
259+
<Button
260+
disabled={!endDate || !description || endDateError}
261+
variant='primary'
262+
fullWidth
263+
onPress={handleSubmit}
264+
>
265+
{isEdit ? remixMessages.save : remixMessages.startContest}
266+
</Button>
267+
{displayTurnOffButton ? (
268+
<Button variant='secondary' fullWidth onPress={handleDeleteEvent}>
269+
{remixMessages.turnOff}
195270
</Button>
196-
{displayTurnOffButton ? (
197-
<Button variant='secondary' fullWidth onPress={handleDeleteEvent}>
198-
{messages.turnOff}
199-
</Button>
200-
) : null}
201-
</Flex>
271+
) : null}
202272
</Flex>
203273
</AppDrawer>
204274
)

0 commit comments

Comments
 (0)