Files
aigen/components/StudioKindCards.vue
T

193 lines
7.3 KiB
Vue

<template>
<div class="mb-4 grid grid-cols-3 gap-3">
<div
class="overflow-hidden rounded-3xl border transition"
:class="current === 'video' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
>
<button
type="button"
class="w-full px-4 pb-3 pt-4 text-left transition"
:class="current === 'video' ? '' : 'hover:text-zinc-200'"
@click="emit('select', 'video')"
>
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
<rect x="4" y="10" width="24" height="20" rx="3" stroke="currentColor" stroke-width="2" />
<path d="M28 16 36 12v16l-8-4V16Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
<circle cx="12" cy="20" r="2" fill="currentColor" />
</svg>
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Video</span>
</button>
<div v-if="ltxEnabled" class="grid grid-cols-2 border-t border-white/10">
<button
type="button"
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'video' && videoEngine === 'minimax')"
@click="pickVideo('minimax')"
>
<span class="block font-semibold">MiniMax</span>
<span class="text-xs opacity-80">H3</span>
</button>
<button
type="button"
class="px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'video' && videoEngine === 'ltx')"
@click="pickVideo('ltx')"
>
<span class="block font-semibold">LTX</span>
<span class="text-xs opacity-80">2.3</span>
</button>
</div>
<p v-else class="border-t border-white/10 px-4 py-2 text-xs text-zinc-500">MiniMax H3</p>
<div class="grid grid-cols-2 border-t border-white/10">
<button
type="button"
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'video' && videoStart === 'still')"
@click="pickStart('still')"
>
<span class="block font-semibold">Still</span>
<span class="text-xs opacity-80">Image to video</span>
</button>
<button
type="button"
class="px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'video' && videoStart === 'text')"
@click="pickStart('text')"
>
<span class="block font-semibold">Text</span>
<span class="text-xs opacity-80">No start still</span>
</button>
</div>
</div>
<div
class="overflow-hidden rounded-3xl border transition"
:class="current === 'image' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
>
<button
type="button"
class="w-full px-4 pb-3 pt-4 text-left transition"
:class="current === 'image' ? '' : 'hover:text-zinc-200'"
@click="emit('select', 'image')"
>
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
<rect x="6" y="8" width="28" height="24" rx="3" stroke="currentColor" stroke-width="2" />
<path d="m10 26 7-8 6 7 3-3 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="15" cy="15" r="2.5" fill="currentColor" />
</svg>
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Image</span>
</button>
<div class="grid grid-cols-2 border-t border-white/10">
<button
type="button"
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'image' && imageEngine === 'flux')"
@click="pickImage('flux')"
>
<span class="block font-semibold">Flux</span>
<span class="text-xs opacity-80">Klein 9B</span>
</button>
<button
type="button"
class="px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'image' && imageEngine === 'krea')"
@click="pickImage('krea')"
>
<span class="block font-semibold">Krea</span>
<span class="text-xs opacity-80">2 Turbo</span>
</button>
</div>
</div>
<div
class="overflow-hidden rounded-3xl border transition"
:class="current === 'music' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
>
<NuxtLink
to="/music"
class="block w-full px-4 pb-3 pt-4 text-left transition"
:class="current === 'music' ? '' : 'hover:text-zinc-200'"
>
<svg class="h-10 w-10" viewBox="0 0 40 40" fill="none" aria-hidden="true">
<circle cx="20" cy="20" r="12" stroke="currentColor" stroke-width="2" />
<path d="M18 14v12l10-4V12l-10 2Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
</svg>
<span class="mt-3 block font-display text-lg font-bold text-zinc-100">Music</span>
</NuxtLink>
<div class="grid grid-cols-2 border-t border-white/10">
<button
type="button"
class="border-r border-white/10 px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'music' && musicEngine === 'ace')"
@click="pickMusic('ace')"
>
<span class="block font-semibold">ACE</span>
<span class="text-xs opacity-80">Step</span>
</button>
<button
type="button"
class="px-3 py-2.5 text-left text-sm transition"
:class="engineBtnClass(current === 'music' && musicEngine === 'yue')"
@click="pickMusic('yue')"
>
<span class="block font-semibold">YuE</span>
<span class="text-xs opacity-80">Lyrics</span>
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = withDefaults(defineProps<{
current: 'video' | 'image' | 'music'
ltxEnabled?: boolean
videoEngine?: 'minimax' | 'ltx'
videoStart?: 'still' | 'text'
imageEngine?: 'flux' | 'krea'
musicEngine?: 'ace' | 'yue'
}>(), {
ltxEnabled: false,
videoEngine: 'minimax',
videoStart: 'still',
imageEngine: 'flux',
musicEngine: 'ace'
})
const emit = defineEmits<{
select: [kind: 'video' | 'image']
'video-engine': [engine: 'minimax' | 'ltx']
'video-start': [start: 'still' | 'text']
'image-engine': [engine: 'flux' | 'krea']
'music-engine': [engine: 'ace' | 'yue']
}>()
function engineBtnClass(active: boolean) {
if (active) return 'bg-amber-400/15 text-amber-100'
return 'text-zinc-400 hover:bg-white/5 hover:text-zinc-200'
}
function pickVideo(engine: 'minimax' | 'ltx') {
emit('video-engine', engine)
if (props.current !== 'video') emit('select', 'video')
}
function pickStart(start: 'still' | 'text') {
emit('video-start', start)
if (props.current !== 'video') emit('select', 'video')
}
function pickImage(engine: 'flux' | 'krea') {
emit('image-engine', engine)
if (props.current !== 'image') emit('select', 'image')
}
function pickMusic(engine: 'ace' | 'yue') {
if (props.current === 'music') {
emit('music-engine', engine)
return
}
void navigateTo({ path: '/music', query: { engine } })
}
</script>