feat: move runtime selection to Step 0, hide source code for WordPress
- Move Application Type (Node.js/Laravel/WordPress) cards from Step 1 to Step 0 (Basic Info) - Hide source code upload/git section when WordPress is selected - Show WordPress info box explaining official Docker image usage - Rename Step 1 heading to 'Versions & Database' - Update Review step to show 'WordPress (Official Image)' as source - Hide git branch/token review lines for WordPress
This commit is contained in:
@@ -9,7 +9,7 @@ import { toast } from 'react-toastify';
|
|||||||
import type { CreateApplicationDto, ClusterPublic, ClusterPoolPublic } from '@/types';
|
import type { CreateApplicationDto, ClusterPublic, ClusterPoolPublic } from '@/types';
|
||||||
import { Hexagon, FolderUp, Link as LinkIcon, CheckCircle, Package, Server, Scale, Home, Target, BarChart3, RotateCw, KeyRound, Rocket, Clock, Upload, XCircle, Database, Eye, EyeOff, RefreshCw } from 'lucide-react';
|
import { Hexagon, FolderUp, Link as LinkIcon, CheckCircle, Package, Server, Scale, Home, Target, BarChart3, RotateCw, KeyRound, Rocket, Clock, Upload, XCircle, Database, Eye, EyeOff, RefreshCw } from 'lucide-react';
|
||||||
|
|
||||||
const steps = ['Basic Info', 'Runtime & Database', 'Resources', 'Review'];
|
const steps = ['Basic Info', 'Versions & Database', 'Resources', 'Review'];
|
||||||
|
|
||||||
export default function DeployPage() {
|
export default function DeployPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -157,8 +157,11 @@ export default function DeployPage() {
|
|||||||
const canNext = () => {
|
const canNext = () => {
|
||||||
if (step === 0) {
|
if (step === 0) {
|
||||||
if (form.name.length < 2) return false;
|
if (form.name.length < 2) return false;
|
||||||
|
// WordPress doesn't require source code
|
||||||
|
if (form.runtime !== 'wordpress') {
|
||||||
if (sourceMethod === 'upload' && !zipFile) return false;
|
if (sourceMethod === 'upload' && !zipFile) return false;
|
||||||
if (sourceMethod === 'git' && !form.gitUrl) return false;
|
if (sourceMethod === 'git' && !form.gitUrl) return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -226,7 +229,39 @@ export default function DeployPage() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Source Code Method */}
|
{/* Application Runtime */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-3">Application Type</label>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||||
|
{[
|
||||||
|
{ value: 'nodejs', label: 'Node.js', icon: <Hexagon className="w-6 h-6 text-green-500" />, desc: 'Express, NestJS, Fastify...' },
|
||||||
|
{ value: 'laravel', label: 'Laravel', icon: <Hexagon className="w-6 h-6 text-orange-500" />, desc: 'PHP, Composer, Artisan' },
|
||||||
|
{ value: 'wordpress', label: 'WordPress', icon: <Hexagon className="w-6 h-6 text-blue-600" />, desc: 'Official image, wp-content' },
|
||||||
|
].map((opt) => (
|
||||||
|
<button
|
||||||
|
key={opt.value}
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
const updates: any = { runtime: opt.value as any, phpVersion: '' };
|
||||||
|
if (opt.value === 'nodejs') { updates.port = 3000; updates.runtimeVersion = '20'; }
|
||||||
|
else if (opt.value === 'laravel') { updates.port = 8000; updates.runtimeVersion = ''; updates.phpVersion = '8.3'; }
|
||||||
|
else if (opt.value === 'wordpress') { updates.port = 80; updates.databaseType = 'mysql'; updates.runtimeVersion = '6.7'; updates.phpVersion = '8.3'; }
|
||||||
|
setForm({ ...form, ...updates });
|
||||||
|
}}
|
||||||
|
className={`p-4 rounded-xl border-2 text-left transition-colors ${
|
||||||
|
form.runtime === opt.value ? 'border-primary-500 bg-primary-50' : 'border-gray-200 hover:border-gray-300'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{opt.icon}
|
||||||
|
<p className="mt-2 font-semibold text-gray-900">{opt.label}</p>
|
||||||
|
<p className="text-xs text-gray-500">{opt.desc}</p>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Source Code Method — hidden for WordPress */}
|
||||||
|
{form.runtime !== 'wordpress' && (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-3">Source Code</label>
|
<label className="block text-sm font-medium text-gray-700 mb-3">Source Code</label>
|
||||||
<div className="grid grid-cols-2 gap-3 mb-4">
|
<div className="grid grid-cols-2 gap-3 mb-4">
|
||||||
@@ -357,42 +392,28 @@ export default function DeployPage() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* WordPress info — shown when WordPress is selected */}
|
||||||
|
{form.runtime === 'wordpress' && (
|
||||||
|
<div className="p-4 bg-blue-50/50 border border-blue-200 rounded-xl">
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
<Hexagon className="w-5 h-5 text-blue-600" />
|
||||||
|
<h3 className="text-sm font-semibold text-gray-800">WordPress (Official Image)</h3>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-gray-500">
|
||||||
|
وردپرس از ایمیج رسمی Docker استفاده میکند و نیازی به آپلود سورسکد ندارد.
|
||||||
|
قالبها و افزونهها از طریق پنل مدیریت وردپرس نصب میشوند.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Step 1: Runtime & Database */}
|
{/* Step 1: Versions & Database */}
|
||||||
{step === 1 && (
|
{step === 1 && (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<h2 className="text-lg font-semibold text-gray-900">Runtime & Database</h2>
|
<h2 className="text-lg font-semibold text-gray-900">Versions & Database</h2>
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-3">Application Runtime</label>
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
|
||||||
{[
|
|
||||||
{ value: 'nodejs', label: 'Node.js', icon: <Hexagon className="w-6 h-6 text-green-500" />, desc: 'Express, NestJS, Fastify...' },
|
|
||||||
{ value: 'laravel', label: 'Laravel', icon: <Hexagon className="w-6 h-6 text-orange-500" />, desc: 'PHP, Composer, Artisan' },
|
|
||||||
{ value: 'wordpress', label: 'WordPress', icon: <Hexagon className="w-6 h-6 text-blue-600" />, desc: 'PHP, Apache, wp-content' },
|
|
||||||
].map((opt) => (
|
|
||||||
<button
|
|
||||||
key={opt.value}
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
const updates: any = { runtime: opt.value as any, phpVersion: '' };
|
|
||||||
if (opt.value === 'nodejs') { updates.port = 3000; updates.runtimeVersion = '20'; }
|
|
||||||
else if (opt.value === 'laravel') { updates.port = 8000; updates.runtimeVersion = ''; updates.phpVersion = '8.3'; }
|
|
||||||
else if (opt.value === 'wordpress') { updates.port = 80; updates.databaseType = 'mysql'; updates.runtimeVersion = '6.7'; updates.phpVersion = '8.3'; }
|
|
||||||
setForm({ ...form, ...updates });
|
|
||||||
}}
|
|
||||||
className={`p-4 rounded-xl border-2 text-left transition-colors ${
|
|
||||||
form.runtime === opt.value ? 'border-primary-500 bg-primary-50' : 'border-gray-200 hover:border-gray-300'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{opt.icon}
|
|
||||||
<p className="mt-2 font-semibold text-gray-900">{opt.label}</p>
|
|
||||||
<p className="text-xs text-gray-500">{opt.desc}</p>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Runtime Version Selectors */}
|
{/* Runtime Version Selectors */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
@@ -954,20 +975,22 @@ export default function DeployPage() {
|
|||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span className="text-sm text-gray-500">Source</span>
|
<span className="text-sm text-gray-500">Source</span>
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
{sourceMethod === 'upload'
|
{form.runtime === 'wordpress'
|
||||||
|
? 'WordPress (Official Image)'
|
||||||
|
: sourceMethod === 'upload'
|
||||||
? zipFile
|
? zipFile
|
||||||
? zipFile.name
|
? zipFile.name
|
||||||
: '—'
|
: '—'
|
||||||
: form.gitUrl || '—'}
|
: form.gitUrl || '—'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{sourceMethod === 'git' && form.gitBranch && (
|
{form.runtime !== 'wordpress' && sourceMethod === 'git' && form.gitBranch && (
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span className="text-sm text-gray-500">Branch</span>
|
<span className="text-sm text-gray-500">Branch</span>
|
||||||
<span className="text-sm font-medium">{form.gitBranch}</span>
|
<span className="text-sm font-medium">{form.gitBranch}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{sourceMethod === 'git' && form.gitToken && (
|
{form.runtime !== 'wordpress' && sourceMethod === 'git' && form.gitToken && (
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span className="text-sm text-gray-500">Auth</span>
|
<span className="text-sm text-gray-500">Auth</span>
|
||||||
<span className="text-sm font-medium text-green-600">Token provided</span>
|
<span className="text-sm font-medium text-green-600">Token provided</span>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user