import React, { useState, useEffect } from 'react'; import { Toast } from './Toast'; import { TemplatePreview } from './TemplatePreview'; export const DomainSetupForm = ({ defaultSubdomain }) => { // Deployment type and app selections const [deploymentType, setDeploymentType] = useState('app'); const [appType, setAppType] = useState('wordpress'); const [sampleWebAppType, setSampleWebAppType] = useState('developer'); // New state for sample web app type const [sourceType, setSourceType] = useState('public'); const [repoUrl, setRepoUrl] = useState(''); const [deploymentKey, setDeploymentKey] = useState(''); const [fileName, setFileName] = useState(''); // Domain configuration const [useSubdomain, setUseSubdomain] = useState(true); const [useCustomDomain, setUseCustomDomain] = useState(false); const [customDomain, setCustomDomain] = useState(''); const [customSubdomain, setCustomSubdomain] = useState(''); const [domainType, setDomainType] = useState('domain'); // 'domain' or 'subdomain' // Domain validation states const [isValidating, setIsValidating] = useState(false); const [isValidDomain, setIsValidDomain] = useState(false); const [validationMessage, setValidationMessage] = useState(''); // DNS configuration const [dnsMethod, setDnsMethod] = useState('cname'); const [showDnsConfig, setShowDnsConfig] = useState(false); const [dnsVerified, setDnsVerified] = useState({ cname: false, ns: false, a: false, ip: false }); // Form validation const [formValid, setFormValid] = useState(true); // Toast notification const [toast, setToast] = useState({ visible: false, message: '' }); // File upload reference const fileInputRef = React.useRef(null); // Effect for handling domain type changes useEffect(() => { if (!useCustomDomain) { setShowDnsConfig(false); setIsValidDomain(false); setValidationMessage(''); setIsValidating(false); } validateForm(); }, [useCustomDomain, dnsVerified.cname, dnsVerified.ns, dnsVerified.ns, domainType, dnsMethod]); // Show toast notification const showToast = (message) => { setToast({ visible: true, message }); setTimeout(() => setToast({ visible: false, message: '' }), 3000); }; // Handle deployment type change const handleDeploymentTypeChange = (e) => { setDeploymentType(e.target.value); }; // Handle source type change const handleSourceTypeChange = (e) => { setSourceType(e.target.value); }; // Handle file upload const handleFileChange = (e) => { if (e.target.files.length > 0) { setFileName(e.target.files[0].name); } else { setFileName(''); } }; // Handle domain checkbox changes const handleUseSubdomainChange = (e) => { setUseSubdomain(e.target.checked); // If CNAME record is selected, SiliconPin subdomain must be enabled if (useCustomDomain && dnsMethod === 'cname' && !e.target.checked) { setUseCustomDomain(false); } validateForm(); }; const handleUseCustomDomainChange = (e) => { setUseCustomDomain(e.target.checked); if (!e.target.checked) { setShowDnsConfig(false); setIsValidDomain(false); setValidationMessage(''); setIsValidating(false); setDnsVerified({ cname: false, ns: false, a: false, ip: false }); } else { // Force SiliconPin subdomain to be checked if custom domain is checked setUseSubdomain(true); } validateForm(); }; // Handle domain type change const handleDomainTypeChange = (e) => { setDomainType(e.target.value); // Reset validation when changing domain type setIsValidDomain(false); setValidationMessage(''); setDnsVerified({ cname: false, ns: false, a: false }); validateForm(); }; // Handle domain and subdomain input changes const handleDomainChange = (e) => { const cleanedValue = e.target.value.replace(/^(https?:\/\/)?(www\.)?/i, '').replace(/\/+$/, '').trim(); setCustomDomain(cleanedValue); }; const handleSubdomainChange = (e) => { const cleanedValue = e.target.value.replace(/^(https?:\/\/)?/i, '').replace(/\/+$/, '').trim(); setCustomSubdomain(cleanedValue); }; // Handle DNS method change const handleDnsMethodChange = (e) => { setDnsMethod(e.target.value); // If changing to CNAME, ensure SiliconPin subdomain is enabled if (e.target.value === 'cname') { setUseSubdomain(true); } // Reset DNS verification setDnsVerified(prev => ({ ...prev, [e.target.value]: false })); validateForm(); }; // Validate domain const validateDomain = () => { const domain = domainType === 'domain' ? customDomain : customSubdomain; if (!domain) { setValidationMessage('Please enter a domain name.'); setIsValidDomain(false); return; } // Initial validation: check format with regex const validFormat = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/.test(domain); if (!validFormat) { setValidationMessage('Domain format is invalid. Please check your entry.'); setIsValidDomain(false); return; } setIsValidating(true); setValidationMessage(''); setShowDnsConfig(false); // Simulate an API call to validate the domain setTimeout(() => { // Simulate a real domain check - in a real app this would be an API call // call /host-api/v1/domains/validate/?domain=domain.com const checkResult = true; // Assume domain is valid for demo setIsValidating(false); setIsValidDomain(checkResult); if (checkResult) { setValidationMessage('Domain is valid and registered.'); setShowDnsConfig(true); } else { setValidationMessage('Domain appears to be unregistered or unavailable.'); } validateForm(); }, 500); }; // Check DNS configuration const checkSubDomainCname = () => { const domainToCheck = customDomain || customSubdomain; fetch('http://localhost:2058/host-api/v1/check-c-name/', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `domain=${encodeURIComponent(domainToCheck)}` }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.status === 'success') { checkDnsConfig('cname'); showToast(`Checking ${type}... (This would verify DNS in a real app)`); console.log('CNAME record:', data.cname); // Handle success - update UI } else { console.error('Error:', data.message); // Handle error } }) .catch(error => { console.error('Fetch error:', error); // Show error to user }); }; const checkDnsConfig = (type) => { showToast(`Checking ${type}... (This would verify DNS in a real app)`); // Simulate DNS check setTimeout(() => { setDnsVerified(prev => ({ ...prev, [type]: true })); showToast(`${type} verified successfully!`); validateForm(); }, 1500); }; // Copy to clipboard const copyToClipboard = (text) => { navigator.clipboard.writeText(text) .then(() => { showToast('Copied to clipboard!'); }) .catch(err => { showToast('Failed to copy: ' + err); }); }; // Validate form const validateForm = () => { // For custom domain, require DNS verification if (useCustomDomain) { if (dnsMethod === 'cname' && !dnsVerified.cname) { setFormValid(false); return; } if (dnsMethod === 'ns' && !dnsVerified.ns) { setFormValid(false); return; } if (dnsMethod === 'ip' && !dnsVerified.ip) { setFormValid(false); return; } } setFormValid(true); }; // Handle form submission const handleSubmit = (e) => { e.preventDefault(); if (!formValid) { showToast('Please complete DNS verification before deploying.'); return; } // In a real app, this would submit the form data to the server console.log([{ deploymentType, appType, sampleWebAppType, sourceType, repoUrl, deploymentKey, useSubdomain, useCustomDomain, customDomain, customSubdomain, domainType, dnsMethod}]); showToast('Form submitted successfully!'); }; return (
{/* Deployment Type Selection */}
{/* App Options */} {deploymentType === 'app' && (
)} {/* Sample Web App Options */} {deploymentType === 'sample-web-app' && (
â„šī¸

Deploy a ready-to-use template that you can customize. We'll set up the basic structure and you can modify it to fit your needs.

{/* Template Preview */}
)} {/* Source Options */} {deploymentType === 'source' && (
setRepoUrl(e.target.value)} placeholder="https://github.com/username/repository" className="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]" />
{sourceType === 'private' && (