Skip to content

Commit

Permalink
Merge pull request #2853 from dev-protocol/feat-multiple-skins
Browse files Browse the repository at this point in the history
feat: support multiple skins in edit ui
  • Loading branch information
yashdesu authored Oct 28, 2024
2 parents c481eb8 + 27b5b1d commit f3270ff
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 163 deletions.
18 changes: 11 additions & 7 deletions src/components/Global/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ const { connectButton = 'hidden', pageTitle } = Astro.props
---

<header class="relative flex items-center justify-between px-6 py-4">
<a href="/">
<h1 class="flex items-center gap-4" class:list={passportClass('heading')}>
<Clubs />
{pageTitle && <span class="lg:text-xl font-bold">{pageTitle}</span>}
</h1>
</a>
<slot name="right:to:right" />
<div class="relative w-fit flex items-center justify-between gap-[18px]">
<a href="/">
<h1 class="flex items-center gap-4" class:list={passportClass('heading')}>
<Clubs />
{pageTitle && <span class="lg:text-xl font-bold">{pageTitle}</span>}
</h1>
</a>
<slot name="passport:profile:switcher" />
</div>

<slot name="right" />

{
connectButton === 'show' && (
<nav class="flex justify-between gap-10">
Expand Down
23 changes: 19 additions & 4 deletions src/pages/passport/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ import { passportClass } from '@fixtures/ui/passport'
import { ClubsPictogramAdaptable as Favicon } from '@devprotocol/clubs-core/images'
import '@devprotocol/clubs-core/styles'
import type { Skin } from '@pages/api/profile'
import Header from '@components/Global/Header.astro'
import { getPassportItemForPayload } from '@fixtures/api/passportItem'
import SkinSwitch from 'src/pages/passport/components/SkinSwitch.svelte'
type Props = {
eoa: string
skins: Skin[]
selectedSkinId: string
sTokenPayload?: string
theme?: 'light' | 'dark' | 'auto'
}
const { theme = 'dark', sTokenPayload } = Astro.props
const {
theme = 'dark',
sTokenPayload,
skins = [],
eoa = '',
selectedSkinId = '',
} = Astro.props
const name = 'Clubs'
const url = 'https://www.clubs.place/'
Expand Down Expand Up @@ -88,10 +98,15 @@ const passportSkinTheme = await whenDefined(sTokenPayload, (payload: string) =>
class:list={passportClass('main-container')}
>
<slot name="before-header" />

<Header connectButton="show" pageTitle="Passport">
<SkinSwitch client:load slot="right:to:right"
>Main Passport (Mystic Horizon)</SkinSwitch
>
<SkinSwitch
client:load
slot="passport:profile:switcher"
skins={skins ?? []}
eoa={eoa ?? ''}
selectedSkinId={selectedSkinId ?? skins?.at(0)?.id ?? ''}
/>
</Header>

<div class:list={passportClass('main-content')}>
Expand Down
14 changes: 12 additions & 2 deletions src/pages/passport/[eoa]/[...ids]/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ const passportSpotlight = await whenDefined(
)
---

<Layout theme="auto" sTokenPayload={profile?.skins?.at(0)?.theme}>
<Layout
theme="auto"
sTokenPayload={skin?.theme}
skins={profile?.skins ?? []}
eoa={eoa ?? ''}
selectedSkinId={skin?.id ?? ''}
>
<div class="grid gap-24 clear-right">
<section class:list={passportClass('account-container')}>
<span
Expand Down Expand Up @@ -163,7 +169,8 @@ const passportSpotlight = await whenDefined(

<UserProfileEditButton
client:only="svelte"
id={eoa}
address={eoa}
skinId={skin?.id ?? ''}
additionalClasses={passportClass('edit-button')}
/>
</span>
Expand Down Expand Up @@ -285,6 +292,7 @@ const passportSpotlight = await whenDefined(
<div class:list={passportClass('spotlight-container')}>
<div class:list={passportClass('spotlight-container')}>
<PassportClips
skinSection="spotlight"
client:only="vue"
clips={passportSpotlight}
id={id}
Expand All @@ -293,11 +301,13 @@ const passportSpotlight = await whenDefined(
</div>
)
}

{
passportSkinClips?.length && (
<div class:list={passportClass('clips-container')}>
<div class:list={passportClass('clips-content')}>
<PassportClips
skinSection="clips"
client:only="vue"
clips={passportSkinClips}
id={id}
Expand Down
12 changes: 11 additions & 1 deletion src/pages/passport/[id]/edit.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import UserProfileEdit from '../components/UserProfileEdit.svelte'
const { id } = Astro.params
const isEOA = isAddress(id)
const skinId = Astro.url.searchParams.get('skinId') || ''
const isLocal =
Astro.url.hostname.includes('localhost') ||
Expand All @@ -30,6 +31,15 @@ const isLocal =
</svg>
Profile
</a>
{isEOA && <UserProfileEdit client:load id={id ?? ''} isLocal={isLocal} />}
{
isEOA && (
<UserProfileEdit
client:load
id={id ?? ''}
skinId={skinId ?? ''}
isLocal={isLocal}
/>
)
}
</div>
</Layout>
52 changes: 28 additions & 24 deletions src/pages/passport/components/PassportClip.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
<script lang="ts" setup>
import { always } from 'ramda'
import { decodeTokenURI } from '@fixtures/nft'
import { computed, onMounted, ref } from 'vue'
import { whenDefined } from '@devprotocol/util-ts'
import Skeleton from '@components/Global/Skeleton.vue'
import type { AssetDocument } from '@fixtures/api/assets/schema'
import { decode, markdownToHtml } from '@devprotocol/clubs-core'
import { itemToHash } from '@fixtures/router/passportItem'
import ImageCard from './ImageCard.vue'
import { loadImage, ABI_NFT } from '../utils'
import type { ImageData, PassportClip } from '../types'
import type { PassportClip } from '../types'
const props = defineProps<{
skinSection: 'spotlight' | 'clips'
item: PassportClip
id: string
index: number
truncate?: boolean
classes?: string
Expand Down Expand Up @@ -55,15 +51,17 @@ const shareClip = () => {
// please replace the title and text with the actual values
title: 'Check out this clip!',
text: props.item.description,
url: window.location.href + `#${itemToHash(`clips`, props.index)}`,
url:
window.location.href.split('#').at(0) +
`#${itemToHash(props.skinSection ?? 'clips', props.index)}`,
})
}
onMounted(async () => {
const clubApiPri = await fetchClub(`/${API_PATH}`)
const clubApi = clubApiPri ? clubApiPri : await fetchClub(clubApiAlt.value)
clubConfig.value = clubApi?.content ?? undefined
const _elementId = itemToHash('clips', props.index)
const _elementId = itemToHash(props.skinSection ?? 'clips', props.index)
elementId.value = _elementId instanceof Error ? '' : (_elementId ?? '')
})
</script>
Expand All @@ -87,61 +85,67 @@ onMounted(async () => {
:type="item.itemAssetType"
:frame-color-hex="item.frameColorHex"
/>

<article
v-if="description"
v-html="description"
:class="{ 'overflow-hidden': props.truncate ?? true }"
></article>
<a v-if="clubName" :href="props.item.clubsUrl">{{ clubName }}</a>
<button
@click="shareClip"
class="flex items-center justify-end w-full h-12 bg-primary-500 text-white rounded-md"
>
<div
class="flex items-center justify-center w-10 h-10 rounded-full bg-gray-800"
>

<div class="flex w-full max-w-full items-center justify-between">
<a v-if="clubName" :href="props.item.clubsUrl">{{ clubName }}</a>
<button @click="shareClip" class="w-6 h-6 rounded-full">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
stroke-width="1.5"
width="24"
height="24"
class="text-white"
stroke="currentColor"
>
<circle
cx="19.64"
cy="4.36"
r="2.86"
class="fill-none stroke-current stroke-miterlimit-10"
class="stroke-miterlimit-10"
stroke="currentColor"
fill="currentColor"
></circle>
<circle
cx="4.36"
cy="12"
r="2.86"
class="fill-none stroke-current stroke-miterlimit-10"
class="stroke-miterlimit-10"
stroke="currentColor"
fill="currentColor"
></circle>
<circle
cx="19.64"
cy="19.64"
r="2.86"
class="fill-none stroke-current stroke-miterlimit-10"
class="stroke-miterlimit-10"
stroke="currentColor"
fill="currentColor"
></circle>
<line
x1="17.08"
y1="5.64"
x2="6.92"
y2="10.72"
class="fill-none stroke-current stroke-miterlimit-10"
class="stroke-miterlimit-10"
stroke="currentColor"
></line>
<line
x1="17.08"
y1="18.36"
x2="6.92"
y2="13.28"
class="fill-none stroke-current stroke-miterlimit-10"
class="stroke-miterlimit-10"
stroke="currentColor"
></line>
</svg>
</div>
</button>
</button>
</div>
</div>
</template>

Expand Down
17 changes: 13 additions & 4 deletions src/pages/passport/components/PassportClips.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { onMounted, ref } from 'vue'
import { i18nFactory } from '@devprotocol/clubs-core'
import { Strings } from '../i18n'
import ImageCard from './ImageCard.vue'
import type { PassportClip } from '../types'
import PassportClipCard from './PassportClip.vue'
import Modal from '@pages/passport/components/Modal.vue'
const props = defineProps<{
skinSection: 'spotlight' | 'clips'
clips: PassportClip[]
id: string
}>()
Expand All @@ -18,14 +18,20 @@ const i18nBase = i18nFactory(Strings)
const i18n = ref<ReturnType<typeof i18nBase>>(i18nBase(['en']))
const modalVisible = ref(false)
const modalItem = ref<PassportClip>()
const modalItemIndex = ref<number>()
const handleOnClick = (item: PassportClip) => {
const handleOnClick = (item: PassportClip, index: number) => {
modalVisible.value = true
modalItem.value = item
modalItemIndex.value = index
}
const modalClose = () => {
modalVisible.value = false
modalItem.value = {} as PassportClip
modalItemIndex.value = -1
}
onMounted(async () => {
i18n.value = i18nBase(navigator.languages)
})
Expand All @@ -43,26 +49,29 @@ onMounted(async () => {
class="empty:hidden"
>
<PassportClipCard
:skinSection="skinSection"
:item="clip"
:truncate="true"
:id="id"
:index="index"
class="h-full"
@click="
() => {
handleOnClick(clip)
handleOnClick(clip, index)
}
"
/>
</li>
</ul>
</section>

<Modal
v-if="modalVisible"
:is-visible="modalVisible"
:modal-content="PassportClipCard"
:handle-modal-close="modalClose"
:attrs="{
item: modalItem,
index: modalItemIndex,
truncate: false,
classes: 'max-w-screen-md',
}"
Expand Down
Loading

0 comments on commit f3270ff

Please sign in to comment.