feat: add generating image page, artwork, and map translation

* feat: add options/map flow, dev seed, and artwork fixes

Options page, Kakao map with florist order message, dev tooling, and
create/message dummy gating — without secrets in .env.example.

Co-authored-by: Cursor <cursoragent@cursor.com>

* with generating page + art work

---------

Co-authored-by: 이지은 <ijieun@ijieun-ui-MacBookPro.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Chaewon Lee
2026-06-14 09:43:35 +09:00
committed by GitHub
parent 921dfd55f4
commit 80b84bd2ed
25 changed files with 851 additions and 110 deletions

View File

@@ -2,33 +2,50 @@
// The exhibited artwork — always shown on the left, acting like a step indicator.
import Vase from './Vase.svelte';
import DescriptionCard from './DescriptionCard.svelte';
import ComingSoonTape from './ComingSoonTape.svelte';
let {
title = 'Title',
description = 'Description Description Description',
/** options Continue 이후 확정된 꽃다발만 전달 (그 전에는 null → Vase) */
imageSrc = null
/** @type {import('./artworkVariants.js').ArtworkVariant} */
variant = 'create1',
/** edit Continue 이후 확정된 꽃다발만 전달 (그 전에는 null → Vase) */
imageSrc = null,
/** generating 단계: 작품 중앙 Coming Soon 밴드 */
comingSoon = false
} = $props();
</script>
<section
class="flex w-full shrink-0 flex-col border-b border-line lg:min-h-0 lg:w-[44%] lg:shrink-0 lg:overflow-y-auto lg:border-r lg:border-b-0"
class="relative flex w-full shrink-0 flex-col border-b border-line lg:min-h-0 lg:h-full lg:w-[44%] lg:shrink-0 lg:overflow-y-auto lg:border-r lg:border-b-0"
>
<!-- mobile: compact row · desktop: centered column -->
<!--
mobile: row · desktop: 꽃 슬롯 높이 고정 → 설명 카드 길이와 무관하게 Y·크기 유지
-->
<div
class="mx-auto flex w-full max-w-100 flex-row items-center gap-12 px-6 py-5 lg:flex-1 lg:flex-col lg:items-center lg:justify-center lg:gap-10 lg:px-6 lg:py-12"
class="mx-auto flex min-h-0 w-full max-w-100 flex-1 flex-row items-start gap-8 px-6 py-6 lg:flex-col lg:items-center lg:justify-start lg:gap-4 lg:px-6 lg:pb-8 lg:pt-[calc(50%-5rem)]"
>
{#if imageSrc}
<div class="mx-auto w-full max-w-24 shrink-0 overflow-hidden sm:max-w-28 lg:max-w-75">
<img
src={imageSrc}
alt="Selected bouquet"
class="aspect-[3/4] h-auto w-full object-cover"
/>
</div>
{:else}
<Vase />
{/if}
<DescriptionCard {title} {description} />
<div
class="flex h-[11rem] shrink-0 items-end justify-center sm:h-[13rem] lg:h-[min(24rem,36vh)] lg:w-full"
>
{#if imageSrc}
<div class="mx-auto w-full max-w-24 shrink-0 overflow-hidden sm:max-w-28 lg:max-w-75">
<img
src={imageSrc}
alt="Selected bouquet"
class="aspect-[3/4] h-auto w-full object-cover"
/>
</div>
{:else}
<Vase {variant} />
{/if}
</div>
<div class="min-w-0 shrink-0 lg:w-full lg:flex lg:justify-center">
<DescriptionCard {title} {description} />
</div>
</div>
{#if comingSoon}
<ComingSoonTape />
{/if}
</section>

View File

@@ -0,0 +1,11 @@
<!-- generating: 왼쪽 섹션 전체 가로 + blur, vase 높이 중앙 -->
<div
class="pointer-events-none absolute inset-x-0 top-[calc(50%-1.25rem)] z-30 -translate-y-1/2"
aria-hidden="true"
>
<div
class="w-full border-y border-subtle/30 bg-muted/45 py-2.5 text-center backdrop-blur-md lg:py-3"
>
<p class="text-sm font-light tracking-wide text-ink lg:text-base">Coming Soon</p>
</div>
</div>

View File

@@ -1,11 +1,16 @@
<script>
import vaseIllustration from '$lib/assets/vase-illustration.svg';
import { getArtworkSrc } from './artworkVariants.js';
/** @type {import('./artworkVariants.js').ArtworkVariant} */
let { variant = 'create1' } = $props();
const src = $derived(getArtworkSrc(variant));
</script>
<img
src={vaseIllustration}
{src}
alt=""
class="mx-auto h-auto w-full max-w-24 shrink-0 sm:max-w-28 lg:max-w-75"
width="320"
height="452"
width="328"
height="443"
/>

View File

@@ -0,0 +1,32 @@
import create1 from '$lib/assets/artwork/1.create1.svg';
import create2 from '$lib/assets/artwork/2.create2.svg';
import upload1 from '$lib/assets/artwork/3.upload1.svg';
import upload2 from '$lib/assets/artwork/4.upload2.svg';
import message1 from '$lib/assets/artwork/5.message1.svg';
import generated from '$lib/assets/artwork/6.generated.svg';
/** @typedef {'create1' | 'create2' | 'upload1' | 'upload2' | 'message1' | 'generated'} ArtworkVariant */
/** @type {Record<ArtworkVariant, string>} */
export const ARTWORK_SRC = {
create1,
create2,
upload1,
upload2,
message1,
generated
};
/** generating 페이지 순환 프레임 */
export const GENERATING_ARTWORK_CYCLE = /** @type {const} */ ([
'create2',
'upload1',
'upload2',
'message1',
'generated'
]);
/** @param {ArtworkVariant} [variant='create1'] */
export function getArtworkSrc(variant = 'create1') {
return ARTWORK_SRC[variant] ?? ARTWORK_SRC.create1;
}