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:
@@ -1,20 +1,49 @@
|
||||
<script>
|
||||
/** @typedef {{ text: string, highlight: boolean }} OrderMessageSegment */
|
||||
|
||||
let {
|
||||
plainText = '',
|
||||
segments = /** @type {OrderMessageSegment[]} */ ([])
|
||||
enPlainText = '',
|
||||
koPlainText = ''
|
||||
} = $props();
|
||||
|
||||
/** @type {'ko' | 'en'} */
|
||||
let activeLang = $state('ko');
|
||||
let textEn = $state('');
|
||||
let textKo = $state('');
|
||||
let seeded = $state(false);
|
||||
let copied = $state(false);
|
||||
|
||||
const hasMessage = $derived(Boolean(plainText?.trim()));
|
||||
$effect(() => {
|
||||
if (!seeded && (enPlainText || koPlainText)) {
|
||||
textEn = enPlainText;
|
||||
textKo = koPlainText;
|
||||
seeded = true;
|
||||
}
|
||||
});
|
||||
|
||||
const activeText = $derived(activeLang === 'ko' ? textKo : textEn);
|
||||
const hasMessage = $derived(
|
||||
Boolean(activeText?.trim()) || Boolean(textEn?.trim()) || Boolean(textKo?.trim())
|
||||
);
|
||||
|
||||
/** @param {Event & { currentTarget: HTMLTextAreaElement }} event */
|
||||
function handleInput(event) {
|
||||
const value = event.currentTarget.value;
|
||||
if (activeLang === 'ko') {
|
||||
textKo = value;
|
||||
} else {
|
||||
textEn = value;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {'ko' | 'en'} lang */
|
||||
function setLanguage(lang) {
|
||||
activeLang = lang;
|
||||
}
|
||||
|
||||
async function handleCopy() {
|
||||
if (!hasMessage) return;
|
||||
if (!activeText.trim()) return;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(plainText);
|
||||
await navigator.clipboard.writeText(activeText);
|
||||
copied = true;
|
||||
setTimeout(() => {
|
||||
copied = false;
|
||||
@@ -25,29 +54,50 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="flex items-start gap-3">
|
||||
{#if hasMessage}
|
||||
<p class="min-w-0 flex-1 text-sm leading-relaxed text-muted">
|
||||
{#each segments as segment, index (index)}
|
||||
{#if segment.highlight}
|
||||
<span class="text-pill">{'{'}</span><span class="font-medium text-ink"
|
||||
>{segment.text}</span
|
||||
><span class="text-pill">{'}'}</span>
|
||||
{:else}
|
||||
{segment.text}
|
||||
{/if}
|
||||
{/each}
|
||||
</p>
|
||||
<textarea
|
||||
class="min-h-[5.5rem] min-w-0 flex-1 resize-y rounded border border-line bg-transparent px-3 py-2 text-sm leading-relaxed text-muted focus:border-line-strong focus:outline-none"
|
||||
rows={4}
|
||||
value={activeText}
|
||||
oninput={handleInput}
|
||||
aria-label={activeLang === 'ko' ? '꽃집 주문 멘트 (한국어)' : 'Florist order message (English)'}
|
||||
></textarea>
|
||||
{:else}
|
||||
<p class="text-sm text-muted">Complete the flow to generate your order message.</p>
|
||||
<p class="min-w-0 flex-1 text-sm text-muted">Complete the flow to generate your order message.</p>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
disabled={!hasMessage}
|
||||
onclick={handleCopy}
|
||||
class="shrink-0 rounded bg-pill px-3 py-1.5 text-xs text-surface disabled:opacity-40"
|
||||
>
|
||||
{copied ? 'Copied!' : 'Copy'}
|
||||
</button>
|
||||
<div class="flex shrink-0 flex-col items-stretch gap-2">
|
||||
<button
|
||||
type="button"
|
||||
disabled={!hasMessage}
|
||||
onclick={handleCopy}
|
||||
class="rounded bg-pill px-3 py-1.5 text-xs text-surface disabled:opacity-40"
|
||||
>
|
||||
{copied ? 'Copied!' : 'Copy'}
|
||||
</button>
|
||||
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
type="button"
|
||||
disabled={!hasMessage}
|
||||
onclick={() => setLanguage('ko')}
|
||||
class="flex-1 rounded border px-2 py-1.5 text-xs disabled:opacity-40 {activeLang === 'ko'
|
||||
? 'border-pill bg-pill text-surface'
|
||||
: 'border-line text-muted hover:border-line-strong'}"
|
||||
>
|
||||
Kor
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
disabled={!hasMessage}
|
||||
onclick={() => setLanguage('en')}
|
||||
class="flex-1 rounded border px-2 py-1.5 text-xs disabled:opacity-40 {activeLang === 'en'
|
||||
? 'border-pill bg-pill text-surface'
|
||||
: 'border-line text-muted hover:border-line-strong'}"
|
||||
>
|
||||
Eng
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
mock = false,
|
||||
fitBounds = false,
|
||||
orderPlainText = '',
|
||||
orderSegments = [],
|
||||
orderKoPlainText = '',
|
||||
onrefresh
|
||||
} = $props();
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
</header>
|
||||
|
||||
<div class="shrink-0 px-6 pb-4 md:px-10 lg:px-12">
|
||||
<FloristOrderMessage plainText={orderPlainText} segments={orderSegments} />
|
||||
<FloristOrderMessage enPlainText={orderPlainText} koPlainText={orderKoPlainText} />
|
||||
</div>
|
||||
|
||||
{#if error}
|
||||
|
||||
Reference in New Issue
Block a user