Skip to content

Commit 5d94b1f

Browse files
authored
[C-2914] USDC purchase options for new upload UI (web) (#3888)
1 parent 30cc8f1 commit 5d94b1f

File tree

11 files changed

+289
-70
lines changed

11 files changed

+289
-70
lines changed

packages/common/src/models/Track.ts

+1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ export type TrackMetadata = {
199199
category: StemCategory
200200
}
201201
remix_of: Nullable<RemixOf>
202+
preview_start_seconds?: number
202203

203204
// Added fields
204205
dateListened?: string

packages/common/src/models/TrackAvailabilityType.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum TrackAvailabilityType {
22
PUBLIC = 'PUBLIC',
3+
USDC_PURCHASE = 'USDC_PURCHASE',
34
SPECIAL_ACCESS = 'SPECIAL_ACCESS',
45
COLLECTIBLE_GATED = 'COLLECTIBLE_GATED',
56
HIDDEN = 'HIDDEN'

packages/web/src/components/data-entry/InputV2.module.css

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
align-items: center;
44
gap: var(--unit-2);
55
width: 100%;
6-
padding-right: var(--unit-4);
6+
padding: 0 var(--unit-4);
77
border: 1px solid var(--neutral-light-8);
88
border-radius: var(--unit-1);
99
background-color: var(--neutral-light-10);
@@ -59,7 +59,6 @@
5959
.textInput {
6060
width: 100%;
6161
height: 100%;
62-
padding-left: var(--unit-4);
6362
outline: 0;
6463
border: 0;
6564
background: none;
@@ -73,6 +72,11 @@
7372
font-weight: var(--font-medium);
7473
}
7574

75+
.inputRow {
76+
width: 100%;
77+
justify-content: space-between;
78+
}
79+
7680
/**
7781
* Flex container so that the absolutely positioned elevated placeholder
7882
* starts out centered vertically
@@ -92,7 +96,7 @@
9296
}
9397

9498
/** Push the input down a bit to make room for the elevated placeholder **/
95-
.elevatedLabel .textInput {
99+
.elevatedLabel .inputRow {
96100
padding-top: calc(var(--font-xs));
97101
}
98102

@@ -101,7 +105,6 @@
101105
position: absolute;
102106
z-index: 2;
103107
transition: all 0.3s ease;
104-
left: var(--unit-4);
105108
}
106109

107110
/** Move the elevated label to the top left if focused or has text **/

packages/web/src/components/data-entry/InputV2.tsx

+40-15
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { ComponentPropsWithoutRef, MutableRefObject, RefCallback } from 'react'
22

33
import cn from 'classnames'
44

5+
import layoutStyles from 'components/layout/layout.module.css'
6+
import { Text } from 'components/typography'
7+
58
import { HelperText } from './HelperText'
69
import styles from './InputV2.module.css'
710
import { useFocusState } from './useFocusState'
8-
911
export enum InputV2Size {
1012
SMALL,
1113
MEDIUM,
@@ -29,6 +31,8 @@ export type InputV2Props = Omit<ComponentPropsWithoutRef<'input'>, 'size'> & {
2931
inputClassName?: string
3032
label?: string
3133
helperText?: string
34+
startAdornment?: string
35+
endAdornment?: string
3236
}
3337

3438
export const InputV2 = (props: InputV2Props) => {
@@ -51,10 +55,12 @@ export const InputV2 = (props: InputV2Props) => {
5155
onBlur: onBlurProp,
5256
placeholder,
5357
helperText,
58+
startAdornment,
59+
endAdornment,
5460
...other
5561
} = props
5662

57-
const characterCount = value ? `${value}`.length : 0
63+
const characterCount = value !== undefined ? `${value}`.length : 0
5864
const nearCharacterLimit = maxLength && characterCount >= 0.9 * maxLength
5965
const elevatePlaceholder = variant === InputV2Variant.ELEVATED_PLACEHOLDER
6066
const label = required ? `${labelProp} *` : labelProp
@@ -80,18 +86,36 @@ export const InputV2 = (props: InputV2Props) => {
8086
}
8187

8288
const input = (
83-
<input
84-
onFocus={handleFocus}
85-
onBlur={handleBlur}
86-
ref={inputRef}
87-
required={required}
88-
className={cn(styles.textInput, inputClassName)}
89-
value={value}
90-
maxLength={maxLength}
91-
disabled={disabled}
92-
placeholder={isFocused ? placeholder : undefined}
93-
{...other}
94-
/>
89+
<div className={cn(styles.inputRow, layoutStyles.row)}>
90+
<div className={layoutStyles.row}>
91+
{startAdornment ? (
92+
<Text variant='label' size='large' color='--neutral-light-2'>
93+
{startAdornment}
94+
</Text>
95+
) : null}
96+
<input
97+
onFocus={handleFocus}
98+
onBlur={handleBlur}
99+
ref={inputRef}
100+
required={required}
101+
className={cn(styles.textInput, inputClassName)}
102+
value={value}
103+
maxLength={maxLength}
104+
disabled={disabled}
105+
placeholder={
106+
isFocused || startAdornment || endAdornment
107+
? placeholder
108+
: undefined
109+
}
110+
{...other}
111+
/>
112+
</div>
113+
{endAdornment ? (
114+
<Text variant='label' size='large' color='--neutral-light-2'>
115+
{endAdornment}
116+
</Text>
117+
) : null}
118+
</div>
95119
)
96120

97121
return (
@@ -101,7 +125,8 @@ export const InputV2 = (props: InputV2Props) => {
101125
<label className={styles.elevatedLabel}>
102126
<span
103127
className={cn(styles.label, {
104-
[styles.hasValue]: characterCount > 0
128+
[styles.hasValue]:
129+
characterCount > 0 || startAdornment || endAdornment
105130
})}
106131
>
107132
{label}

packages/web/src/components/modal-radio/ModalRadioItem.module.css

+3-19
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
}
55

66
.root {
7-
display: flex;
8-
gap: var(--unit-2);
97
padding: var(--unit-6) 0;
108
border-top: 1px solid var(--neutral-light-7);
119
cursor: pointer;
@@ -18,13 +16,6 @@
1816
flex: 0 0 auto;
1917
}
2018

21-
.labelContent {
22-
flex: 1;
23-
display: flex;
24-
flex-direction: column;
25-
gap: var(--unit-2);
26-
}
27-
2819
.optionTitle {
2920
display: flex;
3021
align-items: center;
@@ -39,16 +30,6 @@
3930
opacity: 0.5;
4031
}
4132

42-
.optionDescription {
43-
display: flex;
44-
flex-direction: column;
45-
gap: var(--unit-2);
46-
margin-left: var(--unit-2);
47-
font-weight: var(--font-medium);
48-
font-size: var(--font-l);
49-
line-height: 140%;
50-
}
51-
5233
.root:has(.input:checked) .optionTitle {
5334
color: var(--secondary);
5435
}
@@ -64,3 +45,6 @@
6445
overflow: visible hidden;
6546
transition: height var(--quick);
6647
}
48+
.collapsibleContainer.collapsed {
49+
display: none;
50+
}

packages/web/src/components/modal-radio/ModalRadioItem.tsx

+27-22
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import { ResizeObserver } from '@juggle/resize-observer'
55
import cn from 'classnames'
66
import useMeasure from 'react-use-measure'
77

8+
import layoutStyles from 'components/layout/layout.module.css'
9+
import { Text } from 'components/typography'
10+
811
import styles from './ModalRadioItem.module.css'
912

1013
type ModalRadioItemProps = {
1114
label: string
1215
title?: ReactNode
13-
description: ReactNode
16+
description?: ReactNode
1417
value: any
1518
disabled?: boolean
1619
icon?: ReactNode
@@ -38,32 +41,34 @@ export const ModalRadioItem = (props: ModalRadioItemProps) => {
3841
}, [radioGroup, isCollapsed, value, setIsCollapsed])
3942

4043
return (
41-
<label className={cn(styles.root)}>
42-
<RadioButton
43-
className={styles.radio}
44-
inputClassName={styles.input}
45-
aria-label={label}
46-
value={value}
47-
disabled={disabled}
48-
/>
49-
<div className={styles.labelContent}>
44+
<label className={cn(styles.root, layoutStyles.col, layoutStyles.gap2)}>
45+
<div className={cn(layoutStyles.row)}>
46+
<RadioButton
47+
className={styles.radio}
48+
inputClassName={styles.input}
49+
aria-label={label}
50+
value={value}
51+
disabled={disabled}
52+
/>
5053
<div className={styles.optionTitle}>
5154
{icon}
5255
<span>{title ?? label}</span>
5356
</div>
54-
<div className={styles.optionDescription}>{description}</div>
55-
{checkedContent ? (
56-
<div
57-
className={styles.collapsibleContainer}
58-
style={{ height: isCollapsed ? 0 : bounds.height }}
59-
aria-hidden={isCollapsed}
60-
>
61-
<div ref={ref} className={styles.checkedContent}>
62-
{checkedContent}
63-
</div>
64-
</div>
65-
) : null}
6657
</div>
58+
{checkedContent || description ? (
59+
<div
60+
className={cn(styles.collapsibleContainer, {
61+
[styles.collapsed]: isCollapsed
62+
})}
63+
style={{ height: isCollapsed ? 0 : bounds.height }}
64+
aria-hidden={isCollapsed}
65+
>
66+
<div ref={ref} className={cn(layoutStyles.col, layoutStyles.gap4)}>
67+
<Text size='medium'>{description}</Text>
68+
{checkedContent}
69+
</div>
70+
</div>
71+
) : null}
6772
</label>
6873
)
6974
}

packages/web/src/components/track-availability-modal/TrackAvailabilityModal.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,12 @@ const TrackAvailabilityModal = ({
283283
)
284284

285285
return (
286-
<Modal isOpen={isOpen} onClose={onClose} bodyClassName={styles.modalBody}>
286+
<Modal
287+
isOpen={isOpen}
288+
onClose={onClose}
289+
bodyClassName={styles.modalBody}
290+
size='medium'
291+
>
287292
<ModalHeader
288293
className={styles.modalHeader}
289294
onClose={onClose}

packages/web/src/pages/upload-page/components/EditPageNew.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ const TrackEditForm = (props: FormikProps<TrackEditFormValues>) => {
218218
{isMultiTrack ? <MultiTrackHeader /> : null}
219219
<div className={styles.trackEditForm}>
220220
<TrackMetadataFields />
221-
<div className={styles.additionalFields}>
221+
<div className={cn(layoutStyles.col, layoutStyles.gap4)}>
222222
<ReleaseDateField />
223223
<RemixSettingsField />
224224
<SourceFilesField />

0 commit comments

Comments
 (0)