mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-04 16:23:22 +00:00
FIX - complete CityMarkt sharing and browser flows
This commit is contained in:
@@ -2739,6 +2739,17 @@ const defaultLocales: LocaleTree = {
|
||||
cityMarktShare: 'Share to Local Pages',
|
||||
cityMarktShared: 'Shared to Local Pages.',
|
||||
cityMarktShareHint: 'One CityMarkt share per day',
|
||||
cityMarktAlreadyShared: 'Already published',
|
||||
cityMarktOpenSharedHint: 'Open the Local Pages post',
|
||||
cityMarktAppMissing: 'Local Pages is not installed',
|
||||
cityMarktInstallHint: 'Install Local Pages to share this listing',
|
||||
cityMarktAccountMissing: 'Local Pages profile required',
|
||||
cityMarktAccountHint: 'Create a Local Pages profile before sharing',
|
||||
cityMarktComposeTitle: 'Share CityMarkt listing',
|
||||
cityMarktComposeNavTitle: 'Share listing',
|
||||
cityMarktComposeHint:
|
||||
'Review the listing and publish it when you are ready.',
|
||||
cityMarktPhotosHint: 'The CityMarkt listing photos will be included.',
|
||||
authErrors: {
|
||||
invalid_email: 'Enter a valid 3–32 character iFruit address.',
|
||||
invalid_password: 'Use a password between 6 and 64 characters.',
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Camera,
|
||||
CarFront,
|
||||
ChevronRight,
|
||||
CircleCheck,
|
||||
CirclePlus,
|
||||
Gift,
|
||||
Hammer,
|
||||
@@ -34,7 +35,6 @@ import {
|
||||
import {
|
||||
kBadge,
|
||||
kButton,
|
||||
kFab,
|
||||
kGlass,
|
||||
kIcon,
|
||||
kNavbar,
|
||||
@@ -51,6 +51,7 @@ import CityMarktSelect from '@/components/citymarkt/CityMarktSelect.vue'
|
||||
import CityMarktGallery from '@/components/citymarkt/CityMarktGallery.vue'
|
||||
import CityMarktOfferCard from '@/components/citymarkt/CityMarktOfferCard.vue'
|
||||
import { useAccountStore } from '@/stores/account'
|
||||
import { useAppStoreStore } from '@/stores/app-store'
|
||||
import { useEasyShareStore } from '@/stores/easyshare'
|
||||
import { useMarketplaceStore } from '@/stores/marketplace'
|
||||
import { useMessageMediaStore } from '@/stores/messageMedia'
|
||||
@@ -71,12 +72,6 @@ import type {
|
||||
} from '@/types/marketplace'
|
||||
import type { PhoneMedia } from '@/types/media'
|
||||
|
||||
const glassActionColors = {
|
||||
bgIos: 'bg-ios-light-glass/75 dark:bg-ios-dark-glass/75',
|
||||
activeBgIos: 'active:bg-white/90 dark:active:bg-white/20',
|
||||
textIos: 'text-black/80 dark:text-white/80',
|
||||
}
|
||||
|
||||
type Tab = 'discover' | 'search' | 'sell' | 'inbox' | 'profile'
|
||||
type Screen = 'main' | 'detail' | 'sell' | 'chat' | 'report'
|
||||
type ChatTimelineItem =
|
||||
@@ -113,9 +108,14 @@ type MediaContext = {
|
||||
type ProfileMediaContext = { draft: MarketplaceProfileDraft }
|
||||
|
||||
const phone = usePhoneStore()
|
||||
const detailActionColors = computed(() => ({
|
||||
bgIos: phone.isDarkMode ? 'bg-ios-dark-glass' : 'bg-ios-light-glass',
|
||||
shadowIos: phone.isDarkMode ? 'shadow-ios-dark-glass' : 'shadow-ios-light-glass',
|
||||
}))
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const account = useAccountStore()
|
||||
const appStore = useAppStoreStore()
|
||||
const easyShare = useEasyShareStore()
|
||||
const marketplace = useMarketplaceStore()
|
||||
const messageMedia = useMessageMediaStore()
|
||||
@@ -141,7 +141,6 @@ const offerAmount = ref('')
|
||||
const offerPanelOpen = ref(false)
|
||||
const offerSubmitting = ref(false)
|
||||
const feedback = ref('')
|
||||
const pagesSharePendingId = ref<string | null>(null)
|
||||
const sellStep = ref(1)
|
||||
const submitting = ref(false)
|
||||
const selectedPhotoIds = ref<string[]>([])
|
||||
@@ -241,6 +240,11 @@ const tabs = [
|
||||
] as const
|
||||
|
||||
const isAuthenticated = computed(() => account.email !== '')
|
||||
const localPagesInstalled = computed(
|
||||
() =>
|
||||
appStore.isInstalled('local-pages') &&
|
||||
!appStore.homeLayout.hidden.includes('local-pages'),
|
||||
)
|
||||
const canSaveProfile = computed(() => {
|
||||
const nameLength = profileDraft.value.displayName.trim().length
|
||||
return nameLength >= 2 && nameLength <= 40 && profileDraft.value.bio.trim().length <= 160
|
||||
@@ -371,21 +375,65 @@ function setFeedback(key: string): void {
|
||||
|
||||
async function shareToLocalPages(listingId?: string): Promise<void> {
|
||||
const id = listingId ?? selectedListing.value?.id
|
||||
if (!id || pagesSharePendingId.value) return
|
||||
pagesSharePendingId.value = id
|
||||
const response = await pages.shareCityMarkt(id)
|
||||
pagesSharePendingId.value = null
|
||||
if (response.success && response.data?.id) {
|
||||
if (!id) return
|
||||
if (!localPagesInstalled.value) {
|
||||
setFeedback('Apps.localPages.cityMarktAppMissing')
|
||||
return
|
||||
}
|
||||
if (!pages.profile?.exists) {
|
||||
setFeedback('Apps.localPages.cityMarktAccountMissing')
|
||||
return
|
||||
}
|
||||
const existingPost = pages.ownItems.find(
|
||||
(item) => item.citymarkt_listing_id === id,
|
||||
)
|
||||
if (existingPost) {
|
||||
await router.push({
|
||||
path: '/apps/local-pages',
|
||||
query: {
|
||||
easyShareId: response.data.id,
|
||||
easyShareId: existingPost.id,
|
||||
easyShareKind: 'post',
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
setFeedback(`Apps.localPages.errors.${response.error ?? 'default'}`)
|
||||
await router.push({
|
||||
path: '/apps/local-pages',
|
||||
query: {
|
||||
cityMarktListingId: id,
|
||||
compose: '1',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function localPagesShareLabel(listingId: string): string {
|
||||
if (!localPagesInstalled.value)
|
||||
return phone.t('Apps.localPages.cityMarktAppMissing')
|
||||
if (!pages.profile?.exists)
|
||||
return phone.t('Apps.localPages.cityMarktAccountMissing')
|
||||
return phone.t(
|
||||
hasLocalPagesPost(listingId)
|
||||
? 'Apps.localPages.cityMarktAlreadyShared'
|
||||
: 'Apps.localPages.cityMarktShare',
|
||||
)
|
||||
}
|
||||
|
||||
function localPagesShareHint(listingId: string): string {
|
||||
if (!localPagesInstalled.value)
|
||||
return phone.t('Apps.localPages.cityMarktInstallHint')
|
||||
if (!pages.profile?.exists)
|
||||
return phone.t('Apps.localPages.cityMarktAccountHint')
|
||||
return phone.t(
|
||||
hasLocalPagesPost(listingId)
|
||||
? 'Apps.localPages.cityMarktOpenSharedHint'
|
||||
: 'Apps.localPages.cityMarktShareHint',
|
||||
)
|
||||
}
|
||||
|
||||
function hasLocalPagesPost(listingId: string): boolean {
|
||||
return pages.ownItems.some(
|
||||
(item) => item.citymarkt_listing_id === listingId,
|
||||
)
|
||||
}
|
||||
|
||||
function shareListing(): void {
|
||||
@@ -870,7 +918,10 @@ onMounted(async () => {
|
||||
screen.value = 'sell'
|
||||
}
|
||||
if (isAuthenticated.value) {
|
||||
await marketplace.loadProfile()
|
||||
await Promise.all([
|
||||
marketplace.loadProfile(),
|
||||
localPagesInstalled.value ? pages.loadProfile() : Promise.resolve(false),
|
||||
])
|
||||
if (!marketplace.profile?.exists) {
|
||||
if (!profileSelection) syncProfileDraft()
|
||||
profileEditing.value = true
|
||||
@@ -1196,9 +1247,11 @@ onMounted(async () => {
|
||||
v-if="profileMode === 'own' && (item.status === 'active' || item.status === 'reserved')"
|
||||
class="citymarkt-profile-listing__share"
|
||||
type="button"
|
||||
:disabled="pagesSharePendingId !== null"
|
||||
@click="shareToLocalPages(item.id)"
|
||||
><Share2 :size="15" />{{ phone.t('Apps.localPages.cityMarktShare') }}</button
|
||||
><CircleCheck
|
||||
v-if="hasLocalPagesPost(item.id)"
|
||||
:size="15"
|
||||
/><Share2 v-else :size="15" />{{ localPagesShareLabel(item.id) }}</button
|
||||
></k-glass>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1211,39 +1264,40 @@ onMounted(async () => {
|
||||
class="citymarkt__detail"
|
||||
>
|
||||
<div class="citymarkt__glass-actions">
|
||||
<k-fab
|
||||
<k-glass
|
||||
component="button"
|
||||
type="button"
|
||||
:colors="glassActionColors"
|
||||
class="citymarkt-detail-action"
|
||||
:colors="detailActionColors"
|
||||
:aria-label="phone.t('Common.back')"
|
||||
@click="screen = 'main'"
|
||||
><template #icon><ArrowLeft :size="19" /></template
|
||||
></k-fab>
|
||||
><ArrowLeft :size="19" /></k-glass
|
||||
>
|
||||
<div>
|
||||
<k-fab
|
||||
<k-glass
|
||||
v-if="!selectedListing.is_owner"
|
||||
component="button"
|
||||
type="button"
|
||||
:colors="glassActionColors"
|
||||
class="citymarkt-detail-action"
|
||||
:colors="detailActionColors"
|
||||
:class="{ active: selectedListing.is_favorite }"
|
||||
:aria-label="phone.t(selectedListing.is_favorite ? 'Apps.citymarkt.removeFavorite' : 'Apps.citymarkt.addFavorite')"
|
||||
@click="toggleListingFavorite(selectedListing)"
|
||||
><template #icon
|
||||
><Heart
|
||||
:size="19"
|
||||
:fill="
|
||||
selectedListing.is_favorite ? 'currentColor' : 'none'
|
||||
" /></template
|
||||
></k-fab>
|
||||
<k-fab
|
||||
><Heart
|
||||
:size="19"
|
||||
:fill="selectedListing.is_favorite ? 'currentColor' : 'none'"
|
||||
/></k-glass
|
||||
>
|
||||
<k-glass
|
||||
v-if="!selectedListing.is_owner"
|
||||
component="button"
|
||||
type="button"
|
||||
:colors="glassActionColors"
|
||||
class="citymarkt-detail-action"
|
||||
:colors="detailActionColors"
|
||||
:aria-label="phone.t('Apps.citymarkt.reportListing')"
|
||||
@click="screen = 'report'"
|
||||
><template #icon><MoreHorizontal :size="20" /></template
|
||||
></k-fab>
|
||||
><MoreHorizontal :size="20" /></k-glass
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<CityMarktGallery
|
||||
@@ -1306,14 +1360,14 @@ onMounted(async () => {
|
||||
"
|
||||
class="citymarkt__pages-share"
|
||||
type="button"
|
||||
:disabled="pagesSharePendingId !== null"
|
||||
@click="shareToLocalPages()"
|
||||
>
|
||||
<Share2 :size="17" /><span
|
||||
><strong>{{ phone.t('Apps.localPages.cityMarktShare') }}</strong
|
||||
><small>{{
|
||||
phone.t('Apps.localPages.cityMarktShareHint')
|
||||
}}</small></span
|
||||
<CircleCheck
|
||||
v-if="hasLocalPagesPost(selectedListing.id)"
|
||||
:size="17"
|
||||
/><Share2 v-else :size="17" /><span
|
||||
><strong>{{ localPagesShareLabel(selectedListing.id) }}</strong
|
||||
><small>{{ localPagesShareHint(selectedListing.id) }}</small></span
|
||||
>
|
||||
</button>
|
||||
<div class="citymarkt__owner-actions">
|
||||
@@ -1922,10 +1976,17 @@ onMounted(async () => {
|
||||
gap: 6px;
|
||||
}
|
||||
.citymarkt-detail-action {
|
||||
box-shadow:
|
||||
inset 0 0 0 0.5px #ffffff26,
|
||||
inset 0 1px 0 #ffffff1a,
|
||||
0 6px 16px #0007 !important;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.citymarkt-detail-action.active {
|
||||
color: var(--yellow);
|
||||
}
|
||||
.citymarkt__glass-list > .k-glass {
|
||||
width: 100%;
|
||||
@@ -1975,8 +2036,10 @@ onMounted(async () => {
|
||||
color: inherit;
|
||||
}
|
||||
.citymarkt-listing-card {
|
||||
isolation: isolate;
|
||||
min-width: 0;
|
||||
border-radius: 16px;
|
||||
display: grid !important;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
filter 0.18s ease,
|
||||
@@ -1987,6 +2050,7 @@ onMounted(async () => {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.citymarkt-listing-card > .citymarkt-listing-card__open {
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
@@ -1997,25 +2061,35 @@ onMounted(async () => {
|
||||
text-align: left;
|
||||
}
|
||||
.citymarkt-listing-card__favorite {
|
||||
position: absolute;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
grid-area: 1 / 1;
|
||||
align-self: start;
|
||||
justify-self: end;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 7px;
|
||||
padding: 0;
|
||||
border: 1px solid #ffffff12;
|
||||
border-radius: 50%;
|
||||
display: grid;
|
||||
display: grid !important;
|
||||
place-items: center;
|
||||
background: #161714d9;
|
||||
color: #d0d1cb;
|
||||
color: #f8f8f4;
|
||||
box-shadow: 0 3px 10px #0005;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
pointer-events: auto !important;
|
||||
transition:
|
||||
color 0.16s ease,
|
||||
background 0.16s ease,
|
||||
transform 0.16s ease;
|
||||
}
|
||||
.citymarkt-listing-card__favorite > svg {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
.citymarkt-listing-card__favorite:hover {
|
||||
background: #242520e6;
|
||||
color: #f5f5ef;
|
||||
@@ -2081,6 +2155,10 @@ onMounted(async () => {
|
||||
width: 116px;
|
||||
height: 116px;
|
||||
}
|
||||
.citymarkt__grid--wide .citymarkt-listing-card__favorite {
|
||||
justify-self: start;
|
||||
margin-left: 79px;
|
||||
}
|
||||
.citymarkt__grid--wide .citymarkt-listing-card__body {
|
||||
min-height: 116px;
|
||||
padding: 12px;
|
||||
|
||||
@@ -40,8 +40,10 @@ import CityMarktGallery from '@/components/citymarkt/CityMarktGallery.vue'
|
||||
import { useAccountStore } from '@/stores/account'
|
||||
import { useMessageMediaStore } from '@/stores/messageMedia'
|
||||
import { useEasyShareStore } from '@/stores/easyshare'
|
||||
import { useMarketplaceStore } from '@/stores/marketplace'
|
||||
import { usePagesStore } from '@/stores/pages'
|
||||
import { usePhoneStore } from '@/stores/phone'
|
||||
import type { MarketplaceListing } from '@/types/marketplace'
|
||||
import type { PagesCategory, PagesPost, PagesProfileDraft } from '@/types/pages'
|
||||
import type { PhoneMedia } from '@/types/media'
|
||||
import {
|
||||
@@ -68,6 +70,7 @@ const phone = usePhoneStore()
|
||||
const account = useAccountStore()
|
||||
const messageMedia = useMessageMediaStore()
|
||||
const easyShare = useEasyShareStore()
|
||||
const marketplace = useMarketplaceStore()
|
||||
const pages = usePagesStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -91,6 +94,8 @@ const profilePending = ref(false)
|
||||
const profileDraft = ref<PagesProfileDraft>({ avatarMediaId: 0, bio: '', handle: '' })
|
||||
const selectedProfilePhoto = ref<PhoneMedia | null>(null)
|
||||
const pickedPhotos = ref<SelectedPhoto[]>([])
|
||||
const cityMarktListing = ref<MarketplaceListing | null>(null)
|
||||
const cityMarktListingId = ref<string | null>(null)
|
||||
const draft = ref<ComposeDraft>({
|
||||
body: '',
|
||||
category: 'recommendation' as Exclude<PagesCategory, 'citymarkt'>,
|
||||
@@ -274,7 +279,14 @@ function syncProfileDraft(): void {
|
||||
|
||||
function ensureBrowserProfile(): void {
|
||||
const onboardingScenario = new URLSearchParams(window.location.search).get('testScenario')
|
||||
if (!import.meta.env.DEV || onboardingScenario === 'local-pages-onboarding' || pages.profile) return
|
||||
if (
|
||||
!import.meta.env.DEV ||
|
||||
['local-pages-onboarding', 'citymarkt-local-pages-account-missing'].includes(
|
||||
onboardingScenario ?? '',
|
||||
) ||
|
||||
pages.profile
|
||||
)
|
||||
return
|
||||
const handle = account.email.split('@')[0].toLowerCase()
|
||||
pages.profile = {
|
||||
avatar_media_id: null,
|
||||
@@ -387,24 +399,45 @@ async function publish(): Promise<void> {
|
||||
showFeedback('Apps.localPages.errors.invalid_post')
|
||||
return
|
||||
}
|
||||
const response = await pages.create({
|
||||
body: draft.value.body.trim(),
|
||||
category: draft.value.category,
|
||||
district: draft.value.district,
|
||||
images: draft.value.images.map((id) => ({ id })),
|
||||
title: draft.value.title.trim(),
|
||||
})
|
||||
const response = cityMarktListingId.value
|
||||
? await pages.shareCityMarkt(cityMarktListingId.value)
|
||||
: await pages.create({
|
||||
body: draft.value.body.trim(),
|
||||
category: draft.value.category,
|
||||
district: draft.value.district,
|
||||
images: draft.value.images.map((id) => ({ id })),
|
||||
title: draft.value.title.trim(),
|
||||
})
|
||||
if (!response.success) {
|
||||
showFeedback(`Apps.localPages.errors.${response.error ?? 'default'}`)
|
||||
return
|
||||
}
|
||||
draft.value = { body: '', category: 'recommendation', district: 'los_santos', images: [], title: '' }
|
||||
pickedPhotos.value = []
|
||||
cityMarktListing.value = null
|
||||
cityMarktListingId.value = null
|
||||
tab.value = 'feed'
|
||||
screen.value = 'main'
|
||||
await router.replace('/apps/local-pages')
|
||||
await Promise.all([pages.load(), pages.loadProfile()])
|
||||
showFeedback('Apps.localPages.published')
|
||||
}
|
||||
|
||||
function closeCompose(): void {
|
||||
draft.value = {
|
||||
body: '',
|
||||
category: 'recommendation',
|
||||
district: 'los_santos',
|
||||
images: [],
|
||||
title: '',
|
||||
}
|
||||
pickedPhotos.value = []
|
||||
cityMarktListing.value = null
|
||||
cityMarktListingId.value = null
|
||||
screen.value = 'main'
|
||||
void router.replace('/apps/local-pages')
|
||||
}
|
||||
|
||||
async function react(kind: 'like' | 'save'): Promise<void> {
|
||||
if (!selected.value || !isAuthenticated.value) {
|
||||
showFeedback('Apps.localPages.errors.not_authenticated')
|
||||
@@ -511,7 +544,34 @@ onMounted(async () => {
|
||||
screen.value = 'main'
|
||||
}
|
||||
onboardingReady.value = true
|
||||
if (route.query.compose === '1' && pages.profile?.exists) screen.value = 'compose'
|
||||
if (route.query.compose === '1' && pages.profile?.exists) {
|
||||
const listingId = String(route.query.cityMarktListingId ?? '')
|
||||
if (listingId) {
|
||||
const response = await marketplace.get(listingId)
|
||||
if (
|
||||
response.success &&
|
||||
response.data?.is_owner &&
|
||||
['active', 'reserved'].includes(response.data.status)
|
||||
) {
|
||||
cityMarktListing.value = response.data
|
||||
cityMarktListingId.value = response.data.id
|
||||
draft.value = {
|
||||
body: response.data.description,
|
||||
category: 'recommendation',
|
||||
district: response.data.district ?? 'los_santos',
|
||||
images: response.data.images.map((image) => image.media_id),
|
||||
title: response.data.title,
|
||||
}
|
||||
pickedPhotos.value = response.data.images.map((image) => ({
|
||||
background: image.gradient,
|
||||
id: image.media_id,
|
||||
}))
|
||||
} else {
|
||||
showFeedback('Apps.localPages.errors.citymarkt_not_found')
|
||||
}
|
||||
}
|
||||
if (!listingId || cityMarktListingId.value) screen.value = 'compose'
|
||||
}
|
||||
const easyShareId = String(route.query.easyShareId ?? '')
|
||||
if (pages.profile?.exists && easyShareId && route.query.easyShareKind === 'post') {
|
||||
const response = await pages.get(easyShareId)
|
||||
@@ -752,18 +812,22 @@ onMounted(async () => {
|
||||
</k-glass>
|
||||
</section>
|
||||
|
||||
<section v-else class="pages__compose">
|
||||
<section
|
||||
v-else
|
||||
class="pages__compose"
|
||||
:class="{ 'pages__compose--citymarkt': cityMarktListing }"
|
||||
>
|
||||
<k-navbar
|
||||
class="pages-create-navbar"
|
||||
center-title
|
||||
left-class="pages-create-action pages-create-action--close !w-11 !min-w-11 !max-w-11 !h-11 !p-0 !rounded-full"
|
||||
left-class="pages-create-action pages-create-action--close !min-w-[58px] !h-11 !p-0 !rounded-full"
|
||||
right-class="pages-create-action pages-create-action--publish !min-w-[58px] !h-11 !p-0 !rounded-full"
|
||||
:title="phone.t('Apps.localPages.shareWithCity')"
|
||||
:subtitle="phone.t('Apps.localPages.newPost')"
|
||||
:title="phone.t(cityMarktListing ? 'Apps.localPages.cityMarktComposeNavTitle' : 'Apps.localPages.shareWithCity')"
|
||||
:subtitle="phone.t(cityMarktListing ? 'Apps.localPages.categories.citymarkt' : 'Apps.localPages.newPost')"
|
||||
>
|
||||
<template #left>
|
||||
<button class="pages-create-close" type="button" :aria-label="phone.t('Common.close')" @click="screen = 'main'">
|
||||
<X :size="20" />
|
||||
<button class="pages-create-close" type="button" :aria-label="phone.t('Common.close')" @click="closeCompose">
|
||||
{{ phone.t('Common.close') }}
|
||||
</button>
|
||||
</template>
|
||||
<template #right>
|
||||
@@ -773,13 +837,20 @@ onMounted(async () => {
|
||||
</template>
|
||||
</k-navbar>
|
||||
<div class="pages__compose-scroll">
|
||||
<k-glass v-if="cityMarktListing" class="pages__citymarkt-source">
|
||||
<Store :size="19" />
|
||||
<span
|
||||
><strong>{{ phone.t('Apps.localPages.cityMarktComposeTitle') }}</strong
|
||||
><small>{{ phone.t('Apps.localPages.cityMarktComposeHint') }}</small></span
|
||||
>
|
||||
</k-glass>
|
||||
<label>{{ phone.t('Apps.localPages.title') }} <span :class="{ valid: draft.title.trim().length >= 5 }">{{ draft.title.trim().length }}/80 · {{ phone.t('Apps.citymarkt.minimumCharacters', { minimum: '5' }) }}</span><k-glass class="pages__field-glass"><input v-model="draft.title" maxlength="80" :placeholder="phone.t('Apps.localPages.titlePlaceholder')" /></k-glass></label>
|
||||
<label>{{ phone.t('Apps.localPages.body') }} <span :class="{ valid: draft.body.trim().length >= 10 }">{{ draft.body.trim().length }}/1500 · {{ phone.t('Apps.citymarkt.minimumCharacters', { minimum: '10' }) }}</span><k-glass class="pages__field-glass pages__field-glass--textarea"><textarea v-model="draft.body" maxlength="1500" :placeholder="phone.t('Apps.localPages.bodyPlaceholder')" /></k-glass></label>
|
||||
<div class="pages__form-row"><label>{{ phone.t('Apps.localPages.category') }}<CityMarktSelect :model-value="draft.category" :options="composeCategoryOptions" @change="(value) => draft.category = value as typeof draft.category" /></label><label>{{ phone.t('Apps.localPages.location') }}<CityMarktSelect :model-value="draft.district" :options="districtOptions" @change="(value) => draft.district = value" /></label></div>
|
||||
<section class="pages__photos">
|
||||
<ImagePlus :size="30" />
|
||||
<h2>{{ phone.t('Apps.citymarkt.addPhotos') }}</h2>
|
||||
<p>{{ phone.t('Apps.citymarkt.addPhotosBody') }}</p>
|
||||
<p>{{ phone.t(cityMarktListing ? 'Apps.localPages.cityMarktPhotosHint' : 'Apps.citymarkt.addPhotosBody') }}</p>
|
||||
<div class="pages__photo-actions">
|
||||
<k-glass><button type="button" @click="openMediaApp('photos')">
|
||||
<span><Images :size="20" /></span>
|
||||
@@ -981,9 +1052,7 @@ onMounted(async () => {
|
||||
height: 44px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
.pages-create-action--close {
|
||||
width: 44px;
|
||||
}
|
||||
.pages-create-action--close,
|
||||
.pages-create-action--publish {
|
||||
min-width: 58px;
|
||||
}
|
||||
@@ -997,10 +1066,7 @@ onMounted(async () => {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.pages-create-close {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.pages-create-close,
|
||||
.pages-create-publish {
|
||||
min-width: 58px;
|
||||
padding: 0 13px;
|
||||
@@ -1021,6 +1087,43 @@ onMounted(async () => {
|
||||
height: auto;
|
||||
padding-bottom: 35px;
|
||||
}
|
||||
.pages__citymarkt-source {
|
||||
margin-bottom: 14px;
|
||||
padding: 11px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
border-radius: 13px;
|
||||
color: var(--yellow);
|
||||
}
|
||||
.pages__citymarkt-source span {
|
||||
min-width: 0;
|
||||
}
|
||||
.pages__citymarkt-source strong,
|
||||
.pages__citymarkt-source small {
|
||||
display: block;
|
||||
}
|
||||
.pages__citymarkt-source strong {
|
||||
font-size: 12px;
|
||||
}
|
||||
.pages__citymarkt-source small {
|
||||
margin-top: 2px;
|
||||
color: var(--muted);
|
||||
font-size: 10px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.pages__compose--citymarkt .pages__compose-scroll > label input,
|
||||
.pages__compose--citymarkt .pages__compose-scroll > label textarea {
|
||||
pointer-events: none;
|
||||
}
|
||||
.pages__compose--citymarkt .pages__form-row {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
.pages__compose--citymarkt .pages__form-row > label:first-child,
|
||||
.pages__compose--citymarkt .pages__photo-actions,
|
||||
.pages__compose--citymarkt .pages__selected-strip {
|
||||
display: none;
|
||||
}
|
||||
.pages__field-glass {
|
||||
min-height: 44px;
|
||||
margin-top: 5px;
|
||||
|
||||
Reference in New Issue
Block a user