Skip to content

Commit 4f8d76f

Browse files
committed
Add description below profile images
1 parent bf4acc0 commit 4f8d76f

File tree

6 files changed

+172
-145
lines changed

6 files changed

+172
-145
lines changed

backend/supabase/profiles.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ CREATE TABLE IF NOT EXISTS profiles (
2525
has_kids INTEGER,
2626
height_in_inches INTEGER,
2727
id BIGINT GENERATED ALWAYS AS IDENTITY NOT NULL,
28+
image_descriptions jsonb,
2829
is_smoker BOOLEAN,
2930
diet TEXT[],
3031
last_modification_time TIMESTAMPTZ DEFAULT now() NOT NULL,

common/src/api/zod-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const optionalProfilesSchema = z.object({
103103
twitter: z.string().optional().nullable(),
104104
university: z.string().optional().nullable(),
105105
website: z.string().optional().nullable(),
106+
image_descriptions: z.any().optional().nullable(),
106107
})
107108

108109
export const combinedProfileSchema =

common/src/supabase/schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ export type Database = {
758758
has_kids: number | null
759759
height_in_inches: number | null
760760
id: number
761+
image_descriptions: Json | null
761762
is_smoker: boolean | null
762763
languages: string[] | null
763764
last_modification_time: string
@@ -812,6 +813,7 @@ export type Database = {
812813
has_kids?: number | null
813814
height_in_inches?: number | null
814815
id?: number
816+
image_descriptions?: Json | null
815817
is_smoker?: boolean | null
816818
languages?: string[] | null
817819
last_modification_time?: string
@@ -866,6 +868,7 @@ export type Database = {
866868
has_kids?: number | null
867869
height_in_inches?: number | null
868870
id?: number
871+
image_descriptions?: Json | null
869872
is_smoker?: boolean | null
870873
languages?: string[] | null
871874
last_modification_time?: string

web/components/optional-profile-form.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,13 @@ export const OptionalProfileUserForm = (props: {
694694
pinned_url={profile.pinned_url}
695695
setPhotoUrls={(urls) => setProfile('photo_urls', urls)}
696696
setPinnedUrl={(url) => setProfile('pinned_url', url)}
697+
setDescription={(url, description) =>
698+
setProfile("image_descriptions", {
699+
...(profile?.image_descriptions as Record<string, string> ?? {}),
700+
[url]: description,
701+
})
702+
}
703+
image_descriptions={profile.image_descriptions as Record<string, string>}
697704
/>
698705
</Col>
699706

Lines changed: 127 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
11
import {useState} from 'react'
2-
import clsx from 'clsx'
32
import Image from 'next/image'
43
import {buildArray} from 'common/util/array'
54
import {Carousel} from 'web/components/widgets/carousel'
6-
import {Modal, MODAL_CLASS} from 'web/components/layout/modal'
5+
import {Modal} from 'web/components/layout/modal'
76
import {Col} from 'web/components/layout/col'
87
import {SignUpButton} from './nav/sidebar'
98
import {Profile} from 'common/profiles/profile'
10-
import {Button} from 'web/components/buttons/button'
11-
import {updateProfile} from 'web/lib/api'
12-
import {Row} from 'web/components/layout/row'
139
import {useUser} from 'web/hooks/use-user'
14-
import {PlusIcon} from '@heroicons/react/solid'
15-
import {EditablePhotoGrid} from './widgets/editable-photo-grid'
16-
import {AddPhotosWidget} from './widgets/add-photos'
1710

1811
export default function ProfileCarousel(props: {
1912
profile: Profile,
2013
refreshProfile: () => void,
2114
}) {
22-
const {profile, refreshProfile} = props
15+
const {profile} = props
2316
const photoNums = profile.photo_urls ? profile.photo_urls.length : 0
2417

2518
const [lightboxUrl, setLightboxUrl] = useState('')
2619
const [lightboxOpen, setLightboxOpen] = useState(false)
27-
const [isEditMode, setIsEditMode] = useState(false)
28-
const [addPhotosOpen, setAddPhotosOpen] = useState(false)
20+
// const [isEditMode, setIsEditMode] = useState(false)
21+
// const [addPhotosOpen, setAddPhotosOpen] = useState(false)
2922

30-
const [pinnedUrl, setPinnedUrl] = useState<string | null>(profile.pinned_url)
31-
const [photoUrls, setPhotoUrls] = useState<string[]>(profile.photo_urls ?? [])
23+
// const [pinnedUrl, setPinnedUrl] = useState<string | null>(profile.pinned_url)
24+
// const [photoUrls, setPhotoUrls] = useState<string[]>(profile.photo_urls ?? [])
3225

3326
const currentUser = useUser()
34-
const isCurrentUser = currentUser?.id === profile.user_id
27+
// const isCurrentUser = currentUser?.id === profile.user_id
3528

36-
const handleSaveChanges = async () => {
37-
await updateProfile({
38-
pinned_url: pinnedUrl ?? undefined,
39-
photo_urls: photoUrls,
40-
})
41-
setIsEditMode(false)
42-
refreshProfile()
43-
}
29+
// const handleSaveChanges = async () => {
30+
// await updateProfile({
31+
// pinned_url: pinnedUrl ?? undefined,
32+
// photo_urls: photoUrls,
33+
// })
34+
// setIsEditMode(false)
35+
// refreshProfile()
36+
// }
4437

4538
if (!currentUser && profile.visibility !== 'public') {
4639
return (
@@ -78,82 +71,83 @@ export default function ProfileCarousel(props: {
7871

7972
return (
8073
<>
81-
<div className="flex gap-2 self-end">
82-
{isCurrentUser && !isEditMode && (
83-
<Button
84-
onClick={() => setIsEditMode(true)}
85-
color="gray-outline"
86-
size="sm"
87-
>
88-
Edit photos
89-
</Button>
90-
)}
91-
{isCurrentUser && isEditMode && (
92-
<Row className="gap-2">
93-
<Button
94-
onClick={() => {
95-
// TODO this is stale if you've saved
96-
setPhotoUrls(profile.photo_urls ?? [])
97-
setPinnedUrl(profile.pinned_url)
98-
setIsEditMode(false)
99-
}}
100-
color="gray-outline"
101-
size="sm"
102-
>
103-
Cancel
104-
</Button>
105-
<Button onClick={handleSaveChanges} size="sm">
106-
Save changes
107-
</Button>
108-
</Row>
109-
)}
110-
</div>
74+
{/*<div className="flex gap-2 self-end">*/}
75+
{/* {isCurrentUser && !isEditMode && (*/}
76+
{/* <Button*/}
77+
{/* onClick={() => setIsEditMode(true)}*/}
78+
{/* color="gray-outline"*/}
79+
{/* size="sm"*/}
80+
{/* >*/}
81+
{/* Edit photos*/}
82+
{/* </Button>*/}
83+
{/* )}*/}
84+
{/* {isCurrentUser && isEditMode && (*/}
85+
{/* <Row className="gap-2">*/}
86+
{/* <Button*/}
87+
{/* onClick={() => {*/}
88+
{/* // TODO this is stale if you've saved*/}
89+
{/* setPhotoUrls(profile.photo_urls ?? [])*/}
90+
{/* setPinnedUrl(profile.pinned_url)*/}
91+
{/* setIsEditMode(false)*/}
92+
{/* }}*/}
93+
{/* color="gray-outline"*/}
94+
{/* size="sm"*/}
95+
{/* >*/}
96+
{/* Cancel*/}
97+
{/* </Button>*/}
98+
{/* <Button onClick={handleSaveChanges} size="sm">*/}
99+
{/* Save changes*/}
100+
{/* </Button>*/}
101+
{/* </Row>*/}
102+
{/* )}*/}
103+
{/*</div>*/}
111104

112-
{isEditMode ? (
113-
<Col className="gap-4">
114-
<EditablePhotoGrid
115-
photos={buildArray(pinnedUrl, photoUrls)}
116-
onReorder={(newOrder) => {
117-
const newPinnedUrl = newOrder[0]
118-
const newPhotoUrls = newOrder.filter(
119-
(url) => url !== newPinnedUrl
120-
)
121-
setPinnedUrl(newPinnedUrl)
122-
setPhotoUrls(newPhotoUrls)
123-
}}
124-
onDelete={(url) => {
125-
if (url === pinnedUrl) {
126-
const newPhotos = photoUrls.filter((u) => u !== url)
127-
setPinnedUrl(newPhotos[0] ?? null)
128-
setPhotoUrls(newPhotos.slice(1))
129-
} else {
130-
setPhotoUrls(photoUrls.filter((u) => u !== url))
131-
}
132-
}}
133-
onSetProfilePic={(url) => {
134-
if (url === pinnedUrl) return
135-
setPinnedUrl(url)
136-
setPhotoUrls(
137-
[...photoUrls.filter((u) => u !== url), pinnedUrl].filter(
138-
Boolean
139-
) as string[]
140-
)
141-
}}
142-
/>
143-
<Button
144-
onClick={() => setAddPhotosOpen(true)}
145-
color="gray-outline"
146-
size="sm"
147-
className="self-start"
148-
>
149-
<PlusIcon className="mr-1 h-5 w-5"/>
150-
Add photos
151-
</Button>
152-
</Col>
153-
) : (
154-
<Carousel>
155-
{buildArray(profile.pinned_url, profile.photo_urls).map((url, i) => (
156-
<div key={url} className="h-[300px] w-[300px] flex-none snap-start">
105+
{/*{isEditMode ? (*/}
106+
{/* <Col className="gap-4">*/}
107+
{/* <EditablePhotoGrid*/}
108+
{/* photos={buildArray(pinnedUrl, photoUrls)}*/}
109+
{/* onReorder={(newOrder) => {*/}
110+
{/* const newPinnedUrl = newOrder[0]*/}
111+
{/* const newPhotoUrls = newOrder.filter(*/}
112+
{/* (url) => url !== newPinnedUrl*/}
113+
{/* )*/}
114+
{/* setPinnedUrl(newPinnedUrl)*/}
115+
{/* setPhotoUrls(newPhotoUrls)*/}
116+
{/* }}*/}
117+
{/* onDelete={(url) => {*/}
118+
{/* if (url === pinnedUrl) {*/}
119+
{/* const newPhotos = photoUrls.filter((u) => u !== url)*/}
120+
{/* setPinnedUrl(newPhotos[0] ?? null)*/}
121+
{/* setPhotoUrls(newPhotos.slice(1))*/}
122+
{/* } else {*/}
123+
{/* setPhotoUrls(photoUrls.filter((u) => u !== url))*/}
124+
{/* }*/}
125+
{/* }}*/}
126+
{/* onSetProfilePic={(url) => {*/}
127+
{/* if (url === pinnedUrl) return*/}
128+
{/* setPinnedUrl(url)*/}
129+
{/* setPhotoUrls(*/}
130+
{/* [...photoUrls.filter((u) => u !== url), pinnedUrl].filter(*/}
131+
{/* Boolean*/}
132+
{/* ) as string[]*/}
133+
{/* )*/}
134+
{/* }}*/}
135+
{/* />*/}
136+
{/* <Button*/}
137+
{/* onClick={() => setAddPhotosOpen(true)}*/}
138+
{/* color="gray-outline"*/}
139+
{/* size="sm"*/}
140+
{/* className="self-start"*/}
141+
{/* >*/}
142+
{/* <PlusIcon className="mr-1 h-5 w-5"/>*/}
143+
{/* Add photos*/}
144+
{/* </Button>*/}
145+
{/* </Col>*/}
146+
{/*) : (*/}
147+
<Carousel>
148+
{buildArray(profile.pinned_url, profile.photo_urls).map((url, i) => (
149+
<Col key={url}>
150+
<div className="h-[300px] w-[300px] flex-none snap-start">
157151
<Image
158152
priority={i < 3}
159153
src={url}
@@ -168,43 +162,47 @@ export default function ProfileCarousel(props: {
168162
}}
169163
/>
170164
</div>
171-
))}
172-
{isCurrentUser && (profile.photo_urls?.length ?? 0) > 1 && (
173-
<button
174-
className="bg-ink-200 text-ink-0 group flex h-[300px] w-[300px] flex-none cursor-pointer snap-start items-center justify-center rounded ease-in-out"
175-
onClick={() => setAddPhotosOpen(true)}
176-
>
177-
<PlusIcon className="w-20 transition-all group-hover:w-24"/>
178-
</button>
179-
)}
180-
</Carousel>
181-
)}
165+
<p className="mt-2 px-4 py-1 text-sm w-[300px] whitespace-pre-wrap">
166+
{(profile.image_descriptions as Record<string, string>)?.[url]}
167+
</p>
168+
</Col>
169+
))}
170+
{/*{isCurrentUser && (profile.photo_urls?.length ?? 0) > 1 && (*/}
171+
{/* <button*/}
172+
{/* className="bg-ink-200 text-ink-0 group flex h-[300px] w-[300px] flex-none cursor-pointer snap-start items-center justify-center rounded ease-in-out"*/}
173+
{/* onClick={() => setAddPhotosOpen(true)}*/}
174+
{/* >*/}
175+
{/* <PlusIcon className="w-20 transition-all group-hover:w-24"/>*/}
176+
{/* </button>*/}
177+
{/*)}*/}
178+
</Carousel>
179+
{/* )}*/}
182180

183181
<Modal open={lightboxOpen} setOpen={setLightboxOpen}>
184182
<Image src={lightboxUrl} width={1000} height={1000} alt=""/>
185183
</Modal>
186184

187-
{isCurrentUser && (
188-
<Modal open={addPhotosOpen} setOpen={setAddPhotosOpen}>
189-
<Col className={clsx(MODAL_CLASS)}>
190-
<AddPhotosWidget
191-
user={currentUser}
192-
photo_urls={photoUrls}
193-
pinned_url={pinnedUrl}
194-
setPhotoUrls={setPhotoUrls}
195-
setPinnedUrl={setPinnedUrl}
196-
/>
197-
<Row className="gap-4 self-end">
198-
<Button
199-
color="gray-outline"
200-
onClick={() => setAddPhotosOpen(false)}
201-
>
202-
Done
203-
</Button>
204-
</Row>
205-
</Col>
206-
</Modal>
207-
)}
185+
{/*{isCurrentUser && (*/}
186+
{/* <Modal open={addPhotosOpen} setOpen={setAddPhotosOpen}>*/}
187+
{/* <Col className={clsx(MODAL_CLASS)}>*/}
188+
{/* <AddPhotosWidget*/}
189+
{/* user={currentUser}*/}
190+
{/* photo_urls={photoUrls}*/}
191+
{/* pinned_url={pinnedUrl}*/}
192+
{/* setPhotoUrls={setPhotoUrls}*/}
193+
{/* setPinnedUrl={setPinnedUrl}*/}
194+
{/* />*/}
195+
{/* <Row className="gap-4 self-end">*/}
196+
{/* <Button*/}
197+
{/* color="gray-outline"*/}
198+
{/* onClick={() => setAddPhotosOpen(false)}*/}
199+
{/* >*/}
200+
{/* Done*/}
201+
{/* </Button>*/}
202+
{/* </Row>*/}
203+
{/* </Col>*/}
204+
{/* </Modal>*/}
205+
{/*)}*/}
208206
</>
209207
)
210208
}

0 commit comments

Comments
 (0)