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 { 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() {
|
||||
const router = useRouter();
|
||||
@@ -157,8 +157,11 @@ export default function DeployPage() {
|
||||
const canNext = () => {
|
||||
if (step === 0) {
|
||||
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 === 'git' && !form.gitUrl) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
@@ -226,7 +229,39 @@ export default function DeployPage() {
|
||||
/>
|
||||
</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>
|
||||
<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">
|
||||
@@ -357,42 +392,28 @@ export default function DeployPage() {
|
||||
</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>
|
||||
)}
|
||||
|
||||
{/* Step 1: Runtime & Database */}
|
||||
{/* Step 1: Versions & Database */}
|
||||
{step === 1 && (
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-lg font-semibold text-gray-900">Runtime & 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>
|
||||
<h2 className="text-lg font-semibold text-gray-900">Versions & Database</h2>
|
||||
|
||||
{/* Runtime Version Selectors */}
|
||||
<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">
|
||||
<span className="text-sm text-gray-500">Source</span>
|
||||
<span className="text-sm font-medium">
|
||||
{sourceMethod === 'upload'
|
||||
{form.runtime === 'wordpress'
|
||||
? 'WordPress (Official Image)'
|
||||
: sourceMethod === 'upload'
|
||||
? zipFile
|
||||
? zipFile.name
|
||||
: '—'
|
||||
: form.gitUrl || '—'}
|
||||
</span>
|
||||
</div>
|
||||
{sourceMethod === 'git' && form.gitBranch && (
|
||||
{form.runtime !== 'wordpress' && sourceMethod === 'git' && form.gitBranch && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-500">Branch</span>
|
||||
<span className="text-sm font-medium">{form.gitBranch}</span>
|
||||
</div>
|
||||
)}
|
||||
{sourceMethod === 'git' && form.gitToken && (
|
||||
{form.runtime !== 'wordpress' && sourceMethod === 'git' && form.gitToken && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-500">Auth</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