sms-extension-1777874553/client/src/components/RegisterBusinessModal.jsx

140 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from 'react';
import apiClient from '../api/client';
import {
getBusinessDomain,
getBusinessImage,
getBusinessName,
getBusinessTagline,
} from '../utils/businessProfile';
export default function RegisterBusinessModal({ onClose }) {
const [url, setUrl] = useState('');
const [status, setStatus] = useState('idle');
const [createdBusiness, setCreatedBusiness] = useState(null);
const [error, setError] = useState('');
async function handleSubmit(e) {
e.preventDefault();
if (!url.trim()) return;
setStatus('loading');
setError('');
try {
const res = await apiClient.post('/api/businesses', {
websiteUrl: url.trim(),
});
setCreatedBusiness(res.data);
setStatus('success');
} catch (err) {
setError(err.response?.data?.error || 'Something went wrong. Please try again.');
setStatus('error');
}
}
const successName = getBusinessName(createdBusiness);
const successDomain = getBusinessDomain(createdBusiness);
const successTagline = getBusinessTagline(createdBusiness);
const successImage = getBusinessImage(createdBusiness);
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-gray-900/50 backdrop-blur-sm">
<div className="bg-white border border-gray-200 rounded-xl p-8 w-full max-w-md shadow-xl">
{status === 'success' && (
<div className="text-center">
<div className="w-14 h-14 rounded-full bg-green-50 text-green-600 flex items-center justify-center mx-auto mb-4 text-2xl"></div>
<h2 className="text-xl font-bold text-gray-900 mb-2">Business Added!</h2>
<p className="text-gray-500 text-sm mb-4 font-medium">Brand detected and ready for onboarding.</p>
<div className="rounded-2xl border border-gray-200 bg-gray-50 p-4 mb-6 text-left">
<div className="flex items-start gap-4">
<div className="w-16 h-16 rounded-2xl overflow-hidden bg-white border border-gray-200 shadow-sm shrink-0 flex items-center justify-center">
{successImage ? (
<img src={successImage} alt={successName} className="w-full h-full object-cover" />
) : (
<span className="text-xl font-bold text-indigo-600">
{successName?.[0]?.toUpperCase() || 'B'}
</span>
)}
</div>
<div className="min-w-0">
<p className="text-indigo-600 font-bold text-lg tracking-tight truncate">{successName}</p>
{successDomain && (
<p className="text-sm text-gray-500 font-medium truncate mt-0.5">{successDomain}</p>
)}
{successTagline && (
<p className="text-sm text-gray-700 mt-2 leading-relaxed line-clamp-2">{successTagline}</p>
)}
</div>
</div>
</div>
<button
onClick={onClose}
className="w-full py-2.5 rounded-lg bg-indigo-600 hover:bg-indigo-700 shadow-sm text-white font-medium transition"
>
Done
</button>
</div>
)}
{(status === 'idle' || status === 'loading' || status === 'error') && (
<>
<div className="mb-6">
<h2 className="text-xl font-bold text-gray-900 mb-2 tracking-tight">Add a Business</h2>
<p className="text-gray-500 text-sm leading-relaxed">
Enter the storefront website URL and we&apos;ll scrape it to detect the brand, images, and copy you need for onboarding.
</p>
</div>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-semibold text-gray-700 mb-1.5 tracking-wide">Website URL</label>
<input
type="url"
value={url}
onChange={(e) => setUrl(e.target.value)}
placeholder="https://yourstore.com"
disabled={status === 'loading'}
className="w-full px-4 py-2.5 rounded-lg bg-white border border-gray-300 text-gray-900 placeholder-gray-400 font-medium focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent transition disabled:opacity-50 text-sm shadow-sm"
required
/>
</div>
{status === 'error' && (
<p className="text-sm text-red-600 font-medium bg-red-50 border border-red-200 rounded-lg px-3 py-2">{error}</p>
)}
<div className="flex gap-3 pt-2">
<button
type="button"
onClick={onClose}
disabled={status === 'loading'}
className="flex-[0.8] py-2.5 rounded-lg border border-gray-300 text-gray-700 hover:bg-gray-50 text-sm font-medium transition disabled:opacity-50"
>
Cancel
</button>
<button
type="submit"
disabled={status === 'loading' || !url.trim()}
className="flex-[1.2] py-2.5 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-medium transition shadow-sm disabled:opacity-50 flex items-center justify-center gap-2"
>
{status === 'loading' ? (
<><span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" /> Analysing</>
) : 'Add Business'}
</button>
</div>
{status === 'loading' && (
<p className="text-xs text-gray-500 font-medium text-center pt-2">
Fetching the website context and extracting brand details. This may take 2030 seconds.
</p>
)}
</form>
</>
)}
</div>
</div>
);
}