|
|
@@ -0,0 +1,200 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import LocateSvg from '~/assets/icons/locate.svg'
|
|
|
+
|
|
|
+type PlaymateCard = {
|
|
|
+ id: number
|
|
|
+ name: string
|
|
|
+ age: number
|
|
|
+ gender: 0 | 1 | 2 // 0=未知,1=男,2=女
|
|
|
+ location: string
|
|
|
+ latency: string
|
|
|
+ rate: number
|
|
|
+ rating: number
|
|
|
+ bio: string
|
|
|
+ avatar: string
|
|
|
+ gallery: string[]
|
|
|
+}
|
|
|
+
|
|
|
+const assets = {
|
|
|
+ avatar: 'https://www.figma.com/api/mcp/asset/90a1b39b-5843-4d4a-b3cf-87bc6d1041a5',
|
|
|
+ galleryOne: 'https://www.figma.com/api/mcp/asset/57bca0f4-24ad-4c4f-8aeb-57bc2db6dbe2',
|
|
|
+ galleryTwo: 'https://www.figma.com/api/mcp/asset/90a34be7-3f84-4b53-abfb-e52f9b328407',
|
|
|
+ galleryThree: 'https://www.figma.com/api/mcp/asset/28911d37-523b-4b61-930b-84625ec26511',
|
|
|
+} as const
|
|
|
+
|
|
|
+const playmateCards: PlaymateCard[] = [
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ name: 'Super Beautiful',
|
|
|
+ age: 20,
|
|
|
+ gender: 2,
|
|
|
+ location: 'Jakarta',
|
|
|
+ latency: '15"',
|
|
|
+ rate: 1000,
|
|
|
+ rating: 4,
|
|
|
+ bio: 'Hello brother, multiple seasons of S, online technology, online awareness in ...',
|
|
|
+ avatar: assets.avatar,
|
|
|
+ gallery: [assets.galleryOne, assets.galleryTwo, assets.galleryThree],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: 'Super Beautiful',
|
|
|
+ age: 20,
|
|
|
+ gender: 2,
|
|
|
+ location: 'Timur',
|
|
|
+ latency: '15"',
|
|
|
+ rate: 1000,
|
|
|
+ rating: 4,
|
|
|
+ bio: 'Always ready for ranked matches, can guide team strategy and communication.',
|
|
|
+ avatar: assets.avatar,
|
|
|
+ gallery: [assets.galleryOne, assets.galleryTwo, assets.galleryThree],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ name: 'Super Beautiful',
|
|
|
+ age: 20,
|
|
|
+ gender: 1,
|
|
|
+ location: 'Timur',
|
|
|
+ latency: '15"',
|
|
|
+ rate: 1000,
|
|
|
+ rating: 4,
|
|
|
+ bio: 'Specialized in Mobile Legends jungle role, offering duo coaching service.',
|
|
|
+ avatar: assets.avatar,
|
|
|
+ gallery: [assets.galleryOne, assets.galleryTwo, assets.galleryThree],
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+const formatRate = (rate: number) => new Intl.NumberFormat().format(rate)
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <section class="flex flex-col gap-4 pb-10">
|
|
|
+ <article
|
|
|
+ v-for="card in playmateCards"
|
|
|
+ :key="card.id"
|
|
|
+ class="playmate-card p-3 overflow-hidden"
|
|
|
+ >
|
|
|
+ <div class="flex gap-3">
|
|
|
+ <div class="flex w-[76px] flex-col items-center">
|
|
|
+ <div class="avatar-box relative flex flex-col items-center">
|
|
|
+ <img
|
|
|
+ :src="card.avatar"
|
|
|
+ :alt="card.name"
|
|
|
+ class="avatar"
|
|
|
+ loading="lazy"
|
|
|
+ >
|
|
|
+ <div class="avatar-audio absolute bottom-0" />
|
|
|
+ </div>
|
|
|
+ <div class="flex items-center gap-1">
|
|
|
+ <div class="diamond-icon" />
|
|
|
+ <p class="text-xs">
|
|
|
+ <span class="font-title">{{ formatRate(card.rate) }}</span>
|
|
|
+ <span class="text-[#8e8e8e]">/h</span>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="flex-1">
|
|
|
+ <div class="flex items-start justify-between gap-3">
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
+ <h2 class="text-sm font-semibold">
|
|
|
+ {{ card.name }}
|
|
|
+ </h2>
|
|
|
+ <CommonGender
|
|
|
+ :gender="card.gender"
|
|
|
+ :age="card.age"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="flex items-center gap-1 text-xs text-text-secondary">
|
|
|
+ <LocateSvg />
|
|
|
+ <span>{{ card.location }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="mt-1">
|
|
|
+ <CommonStarRating
|
|
|
+ :model-value="card.rating"
|
|
|
+ mode="display"
|
|
|
+ :size="10"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="summary mt-2 flex items-center">
|
|
|
+ <div class="summary-triangle z-0" />
|
|
|
+ <div class="summary-bg z-0" />
|
|
|
+ <div class="summary-content z-10">
|
|
|
+ <p class="text-xs text-text-description">
|
|
|
+ {{ card.bio }}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="mt-2 flex gap-2">
|
|
|
+ <div
|
|
|
+ v-for="(image, index) in card.gallery"
|
|
|
+ :key="`${card.id}-gallery-${index}`"
|
|
|
+ class="h-[72px] w-[72px] overflow-hidden rounded-xl"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ :src="image"
|
|
|
+ :alt="`${card.name} gallery ${index + 1}`"
|
|
|
+ class="size-full object-cover"
|
|
|
+ loading="lazy"
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </article>
|
|
|
+ </section>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.playmate-card {
|
|
|
+ @include size(100%, auto);
|
|
|
+ flex-shrink: 0;
|
|
|
+ border-radius: 49px 12px 12px 12px;
|
|
|
+ background: #FFF;
|
|
|
+
|
|
|
+ .diamond-icon {
|
|
|
+ @include size(10px, 10px);
|
|
|
+ @include bg('~/assets/images/common/diamond.png');
|
|
|
+ }
|
|
|
+}
|
|
|
+.avatar-box {
|
|
|
+ .avatar {
|
|
|
+ @include size(76px, 76px);
|
|
|
+ border-radius: 50%;
|
|
|
+ }
|
|
|
+ .avatar-audio {
|
|
|
+ @include size(64px, 22px);
|
|
|
+ @include bg('~/assets/images/common/audio.png');
|
|
|
+ }
|
|
|
+}
|
|
|
+.summary {
|
|
|
+ @include size(100%, 38px);
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .summary-triangle {
|
|
|
+ position: absolute;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-style: solid;
|
|
|
+ border-width: 0 4px 4px 4px;
|
|
|
+ border-color: transparent transparent rgba(217, 255, 248, 0.70) transparent;
|
|
|
+ left: 12px;
|
|
|
+ top: -4px;
|
|
|
+ }
|
|
|
+ .summary-bg {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 12px;
|
|
|
+ background: linear-gradient(90deg, rgba(217, 255, 248, 0.70) 0%, rgba(249, 255, 242, 0.70) 99.53%);
|
|
|
+ }
|
|
|
+ .summary-content {
|
|
|
+ position: relative;
|
|
|
+ padding: 0 12px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|