merge: resolve ChannelView icon conflict, keep History + Search/Camera/ExternalLink/Link2
This commit is contained in:
+72
-17
@@ -49,7 +49,8 @@ export default function NewChannelPage() {
|
||||
const [name, setName] = useState('');
|
||||
const [niche, setNiche] = useState('');
|
||||
const [audience, setAudience] = useState('');
|
||||
const [goal, setGoal] = useState('educational');
|
||||
const [goals, setGoals] = useState(['educational']); // multi-select, отправляем как CSV
|
||||
const [customGoal, setCustomGoal] = useState(''); // поле для своей цели
|
||||
const [language, setLanguage] = useState('ru');
|
||||
|
||||
// Шаг 2 — стиль
|
||||
@@ -70,7 +71,7 @@ export default function NewChannelPage() {
|
||||
setBusy(true);
|
||||
setError('');
|
||||
const data = {
|
||||
name, niche, audience, goal, language, region: 'ru',
|
||||
name, niche, audience, goal: goals.join(','), language, region: 'ru',
|
||||
style: {
|
||||
tone, formality, humor,
|
||||
post_length: postLength,
|
||||
@@ -88,7 +89,16 @@ export default function NewChannelPage() {
|
||||
});
|
||||
const json = await res.json();
|
||||
setBusy(false);
|
||||
if (!res.ok) { setError(json.error || 'Ошибка'); return; }
|
||||
if (!res.ok) {
|
||||
if (json.code === 'CHANNEL_LIMIT_REACHED') {
|
||||
setError(`${json.error} → `);
|
||||
// Перенаправим на страницу тарифов через 2 сек
|
||||
setTimeout(() => router.push('/plans'), 2000);
|
||||
} else {
|
||||
setError(json.error || 'Ошибка');
|
||||
}
|
||||
return;
|
||||
}
|
||||
router.push(`/channels/${json.id}`);
|
||||
}
|
||||
|
||||
@@ -150,22 +160,67 @@ export default function NewChannelPage() {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="label">Цель канала</label>
|
||||
<label className="label">Цель канала <span className="text-gray-500 font-normal">(можно несколько)</span></label>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-5 gap-2">
|
||||
{GOALS.map(g => (
|
||||
<button
|
||||
key={g.v}
|
||||
type="button"
|
||||
onClick={() => setGoal(g.v)}
|
||||
className={`p-2.5 rounded-lg border text-left transition-colors ${
|
||||
goal === g.v ? 'border-accent bg-accent/10' : 'border-border bg-surface2 hover:border-gray-600'
|
||||
}`}
|
||||
>
|
||||
<div className="text-sm font-medium">{g.label}</div>
|
||||
<div className="text-xs text-gray-500 mt-0.5">{g.desc}</div>
|
||||
</button>
|
||||
))}
|
||||
{GOALS.map(g => {
|
||||
const on = goals.includes(g.v);
|
||||
return (
|
||||
<button
|
||||
key={g.v}
|
||||
type="button"
|
||||
onClick={() => setGoals(on ? goals.filter(x => x !== g.v) : [...goals, g.v])}
|
||||
className={`p-2.5 rounded-lg border text-left transition-colors ${
|
||||
on ? 'border-accent bg-accent/10' : 'border-border bg-surface2 hover:border-gray-600'
|
||||
}`}
|
||||
>
|
||||
<div className="text-sm font-medium">{g.label}</div>
|
||||
<div className="text-xs text-gray-500 mt-0.5">{g.desc}</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{/* Своя цель */}
|
||||
<div className="flex gap-2 mt-2">
|
||||
<input
|
||||
className="input text-sm flex-1"
|
||||
placeholder="Своя цель — введи и нажми +"
|
||||
value={customGoal}
|
||||
onChange={e => setCustomGoal(e.target.value)}
|
||||
onKeyDown={e => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const v = customGoal.trim();
|
||||
if (v && !goals.includes(v)) setGoals([...goals, v]);
|
||||
setCustomGoal('');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const v = customGoal.trim();
|
||||
if (v && !goals.includes(v)) setGoals([...goals, v]);
|
||||
setCustomGoal('');
|
||||
}}
|
||||
disabled={!customGoal.trim()}
|
||||
className="btn-primary px-3 disabled:opacity-40"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
{/* Выбранные кастомные цели — чипы */}
|
||||
{goals.filter(g => !GOALS.find(x => x.v === g)).length > 0 && (
|
||||
<div className="flex flex-wrap gap-1.5 mt-2">
|
||||
{goals.filter(g => !GOALS.find(x => x.v === g)).map(g => (
|
||||
<span key={g} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-accent/15 border border-accent/40 text-xs">
|
||||
{g}
|
||||
<button type="button" onClick={() => setGoals(goals.filter(x => x !== g))} className="hover:text-red-400">
|
||||
<X className="w-3 h-3" />
|
||||
</button>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<label className="label">Язык постов</label>
|
||||
|
||||
Reference in New Issue
Block a user