Przeglądaj źródła

feat: translate OnboardingContent component with full multilingual support #69

Claude 5 miesięcy temu
rodzic
commit
b2af8c5a81

+ 57 - 74
shopcall.ai-main/src/components/OnboardingContent.tsx

@@ -20,6 +20,7 @@ import {
   Globe,
   Globe,
   Loader2
   Loader2
 } from "lucide-react";
 } from "lucide-react";
+import { useTranslation } from "react-i18next";
 
 
 interface PhoneNumber {
 interface PhoneNumber {
   id: string;
   id: string;
@@ -31,58 +32,8 @@ interface PhoneNumber {
   is_available: boolean;
   is_available: boolean;
 }
 }
 
 
-const packages = [
-  {
-    id: "free-trial",
-    name: "Free Trial",
-    price: "$0",
-    period: "14 days",
-    description: "Perfect for testing our AI assistant",
-    features: [
-      "50 minutes of calls",
-      "Basic AI responses",
-      "Email support",
-      "Dashboard access"
-    ],
-    badge: "Most Popular",
-    badgeColor: "bg-green-500"
-  },
-  {
-    id: "starter",
-    name: "Starter",
-    price: "$29",
-    period: "per month",
-    description: "Great for small businesses",
-    features: [
-      "500 minutes of calls",
-      "Advanced AI responses",
-      "Priority support",
-      "Analytics dashboard",
-      "Custom greetings"
-    ],
-    badge: null,
-    badgeColor: ""
-  },
-  {
-    id: "professional",
-    name: "Professional",
-    price: "$99",
-    period: "per month",
-    description: "For growing businesses",
-    features: [
-      "2,000 minutes of calls",
-      "Premium AI voices",
-      "24/7 support",
-      "Advanced analytics",
-      "Custom integrations",
-      "Multiple phone numbers"
-    ],
-    badge: "Best Value",
-    badgeColor: "bg-purple-500"
-  }
-];
-
 export function OnboardingContent() {
 export function OnboardingContent() {
+  const { t } = useTranslation();
   const [currentStep, setCurrentStep] = useState(1);
   const [currentStep, setCurrentStep] = useState(1);
   const [shopifyUrl, setShopifyUrl] = useState("");
   const [shopifyUrl, setShopifyUrl] = useState("");
   const [selectedPhone, setSelectedPhone] = useState("");
   const [selectedPhone, setSelectedPhone] = useState("");
@@ -91,6 +42,39 @@ export function OnboardingContent() {
   const [loadingPhoneNumbers, setLoadingPhoneNumbers] = useState(false);
   const [loadingPhoneNumbers, setLoadingPhoneNumbers] = useState(false);
   const [phoneNumbersError, setPhoneNumbersError] = useState<string | null>(null);
   const [phoneNumbersError, setPhoneNumbersError] = useState<string | null>(null);
 
 
+  const packages = [
+    {
+      id: "free-trial",
+      name: t('onboarding.step3.packages.freeTrial.name'),
+      price: t('onboarding.step3.packages.freeTrial.price'),
+      period: t('onboarding.step3.packages.freeTrial.period'),
+      description: t('onboarding.step3.packages.freeTrial.description'),
+      features: t('onboarding.step3.packages.freeTrial.features', { returnObjects: true }) as string[],
+      badge: t('onboarding.step3.packages.freeTrial.badge'),
+      badgeColor: "bg-green-500"
+    },
+    {
+      id: "starter",
+      name: t('onboarding.step3.packages.starter.name'),
+      price: t('onboarding.step3.packages.starter.price'),
+      period: t('onboarding.step3.packages.starter.period'),
+      description: t('onboarding.step3.packages.starter.description'),
+      features: t('onboarding.step3.packages.starter.features', { returnObjects: true }) as string[],
+      badge: null,
+      badgeColor: ""
+    },
+    {
+      id: "professional",
+      name: t('onboarding.step3.packages.professional.name'),
+      price: t('onboarding.step3.packages.professional.price'),
+      period: t('onboarding.step3.packages.professional.period'),
+      description: t('onboarding.step3.packages.professional.description'),
+      features: t('onboarding.step3.packages.professional.features', { returnObjects: true }) as string[],
+      badge: t('onboarding.step3.packages.professional.badge'),
+      badgeColor: "bg-purple-500"
+    }
+  ];
+
   // Fetch phone numbers when component mounts or step changes to 2
   // Fetch phone numbers when component mounts or step changes to 2
   useEffect(() => {
   useEffect(() => {
     if (currentStep === 2 && phoneNumbers.length === 0) {
     if (currentStep === 2 && phoneNumbers.length === 0) {
@@ -169,9 +153,9 @@ export function OnboardingContent() {
             <div className="w-12 h-12 bg-cyan-500 rounded-xl flex items-center justify-center">
             <div className="w-12 h-12 bg-cyan-500 rounded-xl flex items-center justify-center">
               <PhoneCall className="w-6 h-6 text-white" />
               <PhoneCall className="w-6 h-6 text-white" />
             </div>
             </div>
-            <h1 className="text-3xl font-bold text-white">AI Phone Assistant</h1>
+            <h1 className="text-3xl font-bold text-white">{t('onboarding.title')}</h1>
           </div>
           </div>
-          <p className="text-slate-400 text-lg">Get your AI phone assistant up and running in 3 simple steps</p>
+          <p className="text-slate-400 text-lg">{t('onboarding.subtitle')}</p>
         </div>
         </div>
 
 
         {/* Progress Steps */}
         {/* Progress Steps */}
@@ -204,15 +188,15 @@ export function OnboardingContent() {
               {currentStep === 2 && <PhoneCall className="w-6 h-6 text-cyan-500" />}
               {currentStep === 2 && <PhoneCall className="w-6 h-6 text-cyan-500" />}
               {currentStep === 3 && <CreditCard className="w-6 h-6 text-cyan-500" />}
               {currentStep === 3 && <CreditCard className="w-6 h-6 text-cyan-500" />}
               <CardTitle className="text-white">
               <CardTitle className="text-white">
-                {currentStep === 1 && "Connect Your Shopify Store"}
-                {currentStep === 2 && "Choose Your Phone Number"}
-                {currentStep === 3 && "Select Your Package"}
+                {currentStep === 1 && t('onboarding.step1.title')}
+                {currentStep === 2 && t('onboarding.step2.title')}
+                {currentStep === 3 && t('onboarding.step3.title')}
               </CardTitle>
               </CardTitle>
             </div>
             </div>
             <p className="text-slate-400">
             <p className="text-slate-400">
-              {currentStep === 1 && "Enter your Shopify store URL to get started"}
-              {currentStep === 2 && "Pick a phone number for your customers to reach you"}
-              {currentStep === 3 && "Choose the perfect plan for your business needs"}
+              {currentStep === 1 && t('onboarding.step1.subtitle')}
+              {currentStep === 2 && t('onboarding.step2.subtitle')}
+              {currentStep === 3 && t('onboarding.step3.subtitle')}
             </p>
             </p>
           </CardHeader>
           </CardHeader>
           <CardContent className="space-y-6">
           <CardContent className="space-y-6">
@@ -220,27 +204,26 @@ export function OnboardingContent() {
             {currentStep === 1 && (
             {currentStep === 1 && (
               <div className="space-y-6">
               <div className="space-y-6">
                 <div className="space-y-2">
                 <div className="space-y-2">
-                  <Label htmlFor="shopify-url" className="text-white">Shopify Store URL</Label>
+                  <Label htmlFor="shopify-url" className="text-white">{t('onboarding.step1.label')}</Label>
                   <Input
                   <Input
                     id="shopify-url"
                     id="shopify-url"
-                    placeholder="your-store.myshopify.com"
+                    placeholder={t('onboarding.step1.placeholder')}
                     value={shopifyUrl}
                     value={shopifyUrl}
                     onChange={(e) => setShopifyUrl(e.target.value)}
                     onChange={(e) => setShopifyUrl(e.target.value)}
                     className="bg-slate-700 border-slate-600 text-white"
                     className="bg-slate-700 border-slate-600 text-white"
                   />
                   />
-                  <p className="text-slate-400 text-sm">We'll connect to your store to understand your products and customers</p>
+                  <p className="text-slate-400 text-sm">{t('onboarding.step1.description')}</p>
                 </div>
                 </div>
 
 
                 <div className="bg-slate-700/50 p-6 rounded-lg">
                 <div className="bg-slate-700/50 p-6 rounded-lg">
                   <div className="flex items-start gap-3">
                   <div className="flex items-start gap-3">
                     <Shield className="w-6 h-6 text-cyan-500 mt-1" />
                     <Shield className="w-6 h-6 text-cyan-500 mt-1" />
                     <div>
                     <div>
-                      <h4 className="text-white font-medium mb-2">Secure Connection</h4>
+                      <h4 className="text-white font-medium mb-2">{t('onboarding.step1.secureTitle')}</h4>
                       <ul className="text-slate-300 text-sm space-y-1">
                       <ul className="text-slate-300 text-sm space-y-1">
-                        <li>• We only read public product information</li>
-                        <li>• No access to customer payment data</li>
-                        <li>• Industry-standard encryption</li>
-                        <li>• You can disconnect anytime</li>
+                        {(t('onboarding.step1.securePoints', { returnObjects: true }) as string[]).map((point, idx) => (
+                          <li key={idx}>• {point}</li>
+                        ))}
                       </ul>
                       </ul>
                     </div>
                     </div>
                   </div>
                   </div>
@@ -254,21 +237,21 @@ export function OnboardingContent() {
                 {loadingPhoneNumbers ? (
                 {loadingPhoneNumbers ? (
                   <div className="flex items-center justify-center py-8">
                   <div className="flex items-center justify-center py-8">
                     <Loader2 className="w-8 h-8 text-cyan-500 animate-spin" />
                     <Loader2 className="w-8 h-8 text-cyan-500 animate-spin" />
-                    <span className="ml-3 text-slate-400">Loading phone numbers...</span>
+                    <span className="ml-3 text-slate-400">{t('onboarding.step2.loading')}</span>
                   </div>
                   </div>
                 ) : phoneNumbersError ? (
                 ) : phoneNumbersError ? (
                   <div className="bg-red-500/10 border border-red-500 rounded-lg p-4">
                   <div className="bg-red-500/10 border border-red-500 rounded-lg p-4">
-                    <p className="text-red-500">{phoneNumbersError}</p>
+                    <p className="text-red-500">{t('onboarding.step2.error')}</p>
                     <Button
                     <Button
                       onClick={fetchPhoneNumbers}
                       onClick={fetchPhoneNumbers}
                       className="mt-4 bg-cyan-500 hover:bg-cyan-600"
                       className="mt-4 bg-cyan-500 hover:bg-cyan-600"
                     >
                     >
-                      Retry
+                      {t('common.tryAgain')}
                     </Button>
                     </Button>
                   </div>
                   </div>
                 ) : phoneNumbers.length === 0 ? (
                 ) : phoneNumbers.length === 0 ? (
                   <div className="bg-yellow-500/10 border border-yellow-500 rounded-lg p-4">
                   <div className="bg-yellow-500/10 border border-yellow-500 rounded-lg p-4">
-                    <p className="text-yellow-500">No phone numbers available for your country yet. Please contact support.</p>
+                    <p className="text-yellow-500">{t('onboarding.step2.noPhones')}</p>
                   </div>
                   </div>
                 ) : (
                 ) : (
                   <>
                   <>
@@ -378,7 +361,7 @@ export function OnboardingContent() {
             className="text-slate-400 border-slate-600 hover:bg-slate-700"
             className="text-slate-400 border-slate-600 hover:bg-slate-700"
           >
           >
             <ArrowLeft className="w-4 h-4 mr-2" />
             <ArrowLeft className="w-4 h-4 mr-2" />
-            Back
+            {t('onboarding.back')}
           </Button>
           </Button>
 
 
           {currentStep < 3 ? (
           {currentStep < 3 ? (
@@ -390,7 +373,7 @@ export function OnboardingContent() {
               }
               }
               className="bg-cyan-500 hover:bg-cyan-600 text-white"
               className="bg-cyan-500 hover:bg-cyan-600 text-white"
             >
             >
-              Continue
+              {t('onboarding.next')}
               <ArrowRight className="w-4 h-4 ml-2" />
               <ArrowRight className="w-4 h-4 ml-2" />
             </Button>
             </Button>
           ) : (
           ) : (
@@ -398,7 +381,7 @@ export function OnboardingContent() {
               onClick={handleFinish}
               onClick={handleFinish}
               className="bg-green-500 hover:bg-green-600 text-white"
               className="bg-green-500 hover:bg-green-600 text-white"
             >
             >
-              Start Free Trial
+              {t('onboarding.finish')}
               <Check className="w-4 h-4 ml-2" />
               <Check className="w-4 h-4 ml-2" />
             </Button>
             </Button>
           )}
           )}