feat: restructure into XFlow monorepo with Nuxt 4, Modular Onion Monolith, Android client, and Desktop CLI

This commit is contained in:
2026-09-28 10:39:19 +05:00
parent edcd30c829
commit be68f5e130
204 changed files with 24616 additions and 39 deletions
@@ -0,0 +1,266 @@
<template>
<Teleport to="body">
<div v-if="show" class="fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 backdrop-blur-sm p-4 font-sans">
<div class="bg-slate-900 border border-slate-700 rounded-2xl w-full max-w-2xl max-h-[90vh] flex flex-col shadow-2xl overflow-hidden">
<!-- Modal Header -->
<div class="px-6 py-4 border-b border-slate-800 flex justify-between items-center bg-slate-900/50">
<h2 class="text-base font-bold text-slate-200 flex items-center gap-2">
<span>🧙‍♂️</span> Коуч-Ассистент: Конструктор SMART & GROW
</h2>
<button @click="$emit('close')" class="text-slate-400 hover:text-white transition">✕</button>
</div>
<!-- Tabs -->
<div class="flex border-b border-slate-800 bg-slate-950/40">
<button
@click="wizardType = 'smart'"
:class="['flex-1 py-3 text-xs font-bold uppercase tracking-wider transition border-b-2', wizardType === 'smart' ? 'text-indigo-400 border-indigo-500 bg-indigo-950/10' : 'text-slate-400 border-transparent hover:bg-slate-800/40']"
>
🎯 SMART Цель
</button>
<button
@click="wizardType = 'grow'"
:class="['flex-1 py-3 text-xs font-bold uppercase tracking-wider transition border-b-2', wizardType === 'grow' ? 'text-teal-400 border-teal-500 bg-teal-950/10' : 'text-slate-400 border-transparent hover:bg-slate-800/40']"
>
🌱 GROW Сессия
</button>
<button
@click="wizardType = 'dilts'"
:class="['flex-1 py-3 text-xs font-bold uppercase tracking-wider transition border-b-2', wizardType === 'dilts' ? 'text-violet-400 border-violet-500 bg-violet-950/10' : 'text-slate-400 border-transparent hover:bg-slate-800/40']"
>
📐 Пирамида Дилтса
</button>
<button
@click="wizardType = 'eisenhower'"
:class="['flex-1 py-3 text-xs font-bold uppercase tracking-wider transition border-b-2', wizardType === 'eisenhower' ? 'text-amber-400 border-amber-500 bg-amber-950/10' : 'text-slate-400 border-transparent hover:bg-slate-800/40']"
>
📊 Матрица Эйзенхауэра
</button>
</div>
<!-- Modal Body (Forms) -->
<div class="p-6 overflow-y-auto flex-1 space-y-4">
<!-- S.M.A.R.T Form -->
<div v-if="wizardType === 'smart'" class="space-y-4">
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">S (Specific) — Какая конкретная задача?</label>
<textarea v-model="smartForm.specific" rows="2" placeholder="Что именно вы хотите сделать? (например: Разработать модуль экспорта canvas)" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">M (Measurable) — Как вы измерите успех?</label>
<textarea v-model="smartForm.measurable" rows="2" placeholder="Укажите критерии готовности (каждую метрику с новой строки)" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">A (Achievable) — За счет чего цель достижима?</label>
<textarea v-model="smartForm.achievable" rows="2" placeholder="Какими ресурсами и навыками вы располагаете?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">R (Relevant) — Почему эта цель важна?</label>
<textarea v-model="smartForm.relevant" rows="2" placeholder="Какую пользу принесет выполнение этой цели общему проекту?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">T (Time-bound) — Каков дедлайн?</label>
<input v-model="smartForm.deadline" type="datetime-local" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none" />
</div>
</div>
<!-- G.R.O.W Form -->
<div v-if="wizardType === 'grow'" class="space-y-4">
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">G (Goal) — Цель</label>
<textarea v-model="growForm.goal" rows="3" placeholder="Какой именно цели я хочу достичь?&#10;Какой результат я хочу получить?&#10;Почему достижение этой цели важно?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-teal-500 focus:ring-1 focus:ring-teal-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">O (Options) — Варианты</label>
<textarea v-model="growForm.options" rows="4" placeholder="Что именно я могу изменить?&#10;Какие ресурсы мне нужны?&#10;Кто мне может помочь?&#10;А что еще?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-teal-500 focus:ring-1 focus:ring-teal-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">R (Reality) — Реальность</label>
<textarea v-model="growForm.reality" rows="4" placeholder="Какова текущая ситуация?&#10;Какие препятствия я вижу?&#10;Что мне мешает начать?&#10;Какие у меня уже есть ресурсы?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-teal-500 focus:ring-1 focus:ring-teal-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">W (Way Forward) — План</label>
<textarea v-model="growForm.wayForward" rows="3" placeholder="Какие самые важные действия необходимо предпринять?&#10;Что я сделаю в первую очередь? Какие сроки?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-teal-500 focus:ring-1 focus:ring-teal-500 outline-none resize-none"></textarea>
</div>
</div>
<!-- Dilts Form -->
<div v-if="wizardType === 'dilts'" class="space-y-4">
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🌟 Миссия — Ради кого? Кому еще это важно? (БЫТЬ)</label>
<textarea v-model="diltsForm.mission" rows="2" placeholder="Ради кого? Кому еще это важно? (БЫТЬ)" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">👤 Я — Кто я?</label>
<textarea v-model="diltsForm.identity" rows="2" placeholder="Кто я?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">💎 Ценности — Почему это важно?</label>
<textarea v-model="diltsForm.values" rows="2" placeholder="Почему это важно?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🧠 Навыки — Как? Каким образом?</label>
<textarea v-model="diltsForm.skills" rows="2" placeholder="Как? Каким образом?" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🎬 Действия — Что делать? (ДЕЛАТЬ)</label>
<textarea v-model="diltsForm.actions" rows="2" placeholder="Что делать? (ДЕЛАТЬ)" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🌍 Окружение — Где? Когда? С кем? (ИМЕТЬ)</label>
<textarea v-model="diltsForm.environment" rows="2" placeholder="Где? Когда? С кем? (ИМЕТЬ)" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none resize-none"></textarea>
</div>
</div>
<!-- Eisenhower Form -->
<div v-if="wizardType === 'eisenhower'" class="space-y-4">
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🔥 Квадрант I: Важно и Срочно (Сделать сейчас)</label>
<textarea v-model="eisenhowerForm.q1" rows="2" placeholder="Кризисы, горящие дедлайны, важные неотложные задачи" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-amber-500 focus:ring-1 focus:ring-amber-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">⚡ Квадрант II: Важно, но Несрочно (Запланировать)</label>
<textarea v-model="eisenhowerForm.q2" rows="2" placeholder="Долгосрочное планирование, здоровье, обучение, стратегические цели" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-amber-500 focus:ring-1 focus:ring-amber-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">🧊 Квадрант III: Неважно, но Срочно (Делегировать)</label>
<textarea v-model="eisenhowerForm.q3" rows="2" placeholder="Входящие рутинные звонки/письма, мелкие поручения, задачи, которые можно перепоручить" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-amber-500 focus:ring-1 focus:ring-amber-500 outline-none resize-none"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-400 block mb-1">💤 Квадрант IV: Неважно и Несрочно (Отложить/Удалить)</label>
<textarea v-model="eisenhowerForm.q4" rows="2" placeholder="Пожиратели времени, мелкие развлечения, неважная рутина" class="w-full bg-slate-950 border border-slate-800 rounded-lg p-2.5 text-xs text-slate-200 focus:border-amber-500 focus:ring-1 focus:ring-amber-500 outline-none resize-none"></textarea>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="px-6 py-4 border-t border-slate-800 bg-slate-900/50 flex justify-end gap-3">
<button @click="$emit('close')" class="px-4 py-2 border border-slate-700 hover:bg-slate-800 text-slate-300 rounded-lg text-xs transition">
Отмена
</button>
<button
@click="submitManual"
:disabled="isSubmitting"
class="px-4 py-2 bg-slate-800 hover:bg-slate-700 border border-slate-700 text-white rounded-lg text-xs transition"
>
Создать вручную
</button>
<button
@click="submitAI"
:disabled="isSubmitting"
class="px-4 py-2 bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white rounded-lg text-xs font-bold transition flex items-center gap-1.5"
>
<span v-if="isSubmitting" class="animate-spin text-xs">🌀</span>
<span v-else>✨</span>
Оптимизировать через AI
</button>
</div>
</div>
</div>
</Teleport>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
show: { type: Boolean, default: false },
isSubmitting: { type: Boolean, default: false }
})
const emit = defineEmits([
'close',
'submit-smart-manual',
'submit-smart-ai',
'submit-grow-manual',
'submit-grow-ai',
'submit-dilts-manual',
'submit-dilts-ai',
'submit-eisenhower-manual',
'submit-eisenhower-ai'
])
const wizardType = ref('smart')
const smartForm = ref({
specific: '',
measurable: '',
achievable: '',
relevant: '',
deadline: ''
})
const growForm = ref({
goal: '',
reality: '',
options: '',
wayForward: ''
})
const diltsForm = ref({
mission: '',
identity: '',
values: '',
skills: '',
actions: '',
environment: ''
})
const eisenhowerForm = ref({
q1: '',
q2: '',
q3: '',
q4: ''
})
const resetForms = () => {
smartForm.value = { specific: '', measurable: '', achievable: '', relevant: '', deadline: '' }
growForm.value = { goal: '', reality: '', options: '', wayForward: '' }
diltsForm.value = { mission: '', identity: '', values: '', skills: '', actions: '', environment: '' }
eisenhowerForm.value = { q1: '', q2: '', q3: '', q4: '' }
}
const submitManual = () => {
if (wizardType.value === 'smart') {
emit('submit-smart-manual', { ...smartForm.value })
} else if (wizardType.value === 'grow') {
emit('submit-grow-manual', { ...growForm.value })
} else if (wizardType.value === 'dilts') {
emit('submit-dilts-manual', { ...diltsForm.value })
} else if (wizardType.value === 'eisenhower') {
emit('submit-eisenhower-manual', { ...eisenhowerForm.value })
}
resetForms()
}
const submitAI = () => {
if (wizardType.value === 'smart') {
if (!smartForm.value.specific.trim()) {
alert('Пожалуйста, введите хотя бы описание цели!')
return
}
emit('submit-smart-ai', { ...smartForm.value })
} else if (wizardType.value === 'grow') {
if (!growForm.value.goal.trim()) {
alert('Пожалуйста, введите хотя бы цель (Goal)!')
return
}
emit('submit-grow-ai', { ...growForm.value })
} else if (wizardType.value === 'dilts') {
if (!diltsForm.value.mission.trim()) {
alert('Пожалуйста, введите хотя бы описание миссии!')
return
}
emit('submit-dilts-ai', { ...diltsForm.value })
} else if (wizardType.value === 'eisenhower') {
if (!eisenhowerForm.value.q1.trim() && !eisenhowerForm.value.q2.trim() && !eisenhowerForm.value.q3.trim() && !eisenhowerForm.value.q4.trim()) {
alert('Пожалуйста, введите задачи хотя бы в один из квадрантов!')
return
}
emit('submit-eisenhower-ai', { ...eisenhowerForm.value })
}
}
// Expose reset in case parent wants to reset from outside
defineExpose({ resetForms })
</script>