Add TinaCMS Cloud integration (Phase 1)

- Add tina/config.ts with full schema for all site sections
- Convert i18n from TypeScript to nested JSON (content/translations/)
- Update LanguageContext to import JSON with flattenObject utility
- Update dev/build scripts to run tinacms build
- Add sync-blog.mjs support for content/blog/*.md (TinaCMS posts)
- Update CI/CD with Tina env vars, remove blog rsync exclusion
- Add tina/__generated__/ to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-03-12 20:34:35 +00:00
parent de292da095
commit 985d21b53d
10 changed files with 15768 additions and 75 deletions

View file

@ -18,6 +18,10 @@ jobs:
- run: npm ci
- run: npm run build
env:
TINA_PUBLIC_CLIENT_ID: ${{ secrets.TINA_PUBLIC_CLIENT_ID }}
TINA_TOKEN: ${{ secrets.TINA_TOKEN }}
GITHUB_REF_NAME: ${{ github.ref_name }}
- name: Setup SSH
run: |
@ -29,7 +33,6 @@ jobs:
- name: Deploy to server
run: |
rsync -avz --delete \
--exclude='blog/' \
-e "ssh -p 1220 -i ~/.ssh/id_deploy" \
dist/ ubuntu@57.128.160.249:/opt/00-infrastructure/Website/website/dist/

1
.gitignore vendored
View file

@ -5,6 +5,7 @@ dist
.env
.env.*
public/blog
tina/__generated__/
.claude/
pronpt.txt
.mcp.json

View file

@ -0,0 +1,771 @@
{
"header": {
"nav": {
"home": "Home",
"about": "About Us",
"services": "Services",
"pricing": "Pricing",
"blog": "Blog",
"contacts": "Contacts"
},
"lang": {
"en": "Eng",
"uk": "Ukr"
},
"login": "Log in",
"loginModal": {
"title": "Welcome Back",
"emailLabel": "Email / Login",
"emailPlaceholder": "Enter your email",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter your password",
"submit": "Log In",
"signupPrompt": "Don't have an account?",
"signupLink": "Sign up"
}
},
"hero": {
"circle1": "Build.",
"circle2": "Automate.",
"circle3": "Impress.",
"title": "Stop Hiring. Start Scaling. Deploy Your AI Digital Workforce.",
"cta": "Get your free consultation"
},
"benefits": {
"card1": {
"front": "Cost & Scale",
"subtitle": "Elastic Growth, Zero Headcount",
"back": "Scale 10x without hiring. AI assistants handle peak loads automatically, keeping your operations elastic and efficient."
},
"card2": {
"front": "Accuracy",
"subtitle": "Machine Learning Precision (99.9%)",
"back": "Eliminate human error. Our ML-validated workflows guarantee data integrity across CRM, finance, and logistics systems."
},
"card3": {
"front": "Availability",
"subtitle": "True 24/7/365 Operations",
"back": "Your AI workforce never sleeps, takes breaks, or burns out. Serve global clients nonstop."
},
"builtTitle": "Built for Local Entrepreneurs Like You",
"builtDesc": "AImpress turns chaos into a system. We build automations that save up to 75% of your time and boost sales.",
"static1": {
"title": "Chatbots & AI Assistants",
"desc": "→ instant answers 24/7"
},
"static2": {
"title": "Business Process Automation (n8n, Make.com)",
"desc": "→ CRM, email, finance, inventory"
},
"static3": {
"title": "Content Farms & AI Copywriting",
"desc": "→ AI creates posts, articles, product descriptions"
},
"static4": {
"title": "Marketing Automation (email, CRM, ads)",
"desc": "→ campaigns, lead nurturing, ads on autopilot"
}
},
"banner1": {
"q1": "How many employees in your company?",
"q2": "How many hours per day on repetitive tasks?",
"q3": "Which processes do you want to automate?",
"cta": "Get Your Free Consultation"
},
"realResults": {
"title": "Real Results from Real Local Clients",
"card1": {
"title": "AutoBrat Garage",
"resultsLabel": "Results:",
"desc": "Ukrainian-founded specialist garage struggled with local recognition. AImpress created bilingual content showcasing their German vehicle expertise.",
"stat1": "157% - increase in bookings",
"stat2": "85% - service bay utilisation",
"stat3": "recognition in Oxford Mail within 6 months"
},
"card2": {
"title": "Cotswolld Honey Company",
"desc": "Artisanal honey producer limited to seasonal markets. AImpress developed e-commerce and educational content highlighting sustainable practices.",
"stat1": "78% - increase in online sales",
"stat2": "four new retail partnerships in just 4 months"
},
"card3": {
"title": "Wcounting Accounting Partners",
"desc": "Traditional firm losing younger clients. AImpress created accessible financial guides and Making Tax Digital content.",
"stat1": "41% - increase in under-40 enquiries",
"stat2": "12 - new e-commerce clients within 5 months"
}
},
"timeline": {
"title": "Your Path to Autonomous Operations",
"step1": {
"title": "Challenge Briefing",
"duration": "2h",
"short": "Identify top-impact opportunities and define ROI metrics.",
"detail": "We audit your workflows, pinpoint bottlenecks, and map out the highest-ROI automation targets — all in a single focused session."
},
"step2": {
"title": "Tech Assessment & Strategy",
"duration": "23 days",
"short": "Review existing stack, architecture, and compliance.",
"detail": "Deep dive into your CRM, accounting, comms, and data flow. We design the integration blueprint and security model before writing a single line."
},
"step3": {
"title": "Proof of Concept",
"duration": "812 weeks",
"short": "Pilot for a critical process — visible ROI.",
"detail": "We build and deploy a working automation for your most painful workflow. You'll see measurable time and cost savings within the first sprint."
},
"step4": {
"title": "MVP Implementation",
"duration": "23 months",
"short": "Full deployment, team training, and integration.",
"detail": "Roll out across departments with hands-on training, monitoring dashboards, and a dedicated Slack channel for your team to get instant support."
},
"step5": {
"title": "Scaling & Optimization",
"duration": "Ongoing",
"short": "Continuous improvement and expansion.",
"detail": "Monthly performance reviews, A/B tested automation tweaks, and expansion into new departments. Your AI workforce grows with you."
}
},
"banner2": {
"cta": "Get Your Free Consultation"
},
"comparison": {
"title": "Why Businesses Switch to AImpress",
"aiLabel": "AI-Powered",
"metric1": {
"label": "Cost",
"ai": "From £1,500",
"agency": "£5,000+ /mo agency",
"inhouse": "£35,000+ /yr in-house"
},
"metric2": {
"label": "Speed",
"ai": "Instant",
"agency": "Depends on manager",
"inhouse": "9-to-5 only"
},
"metric3": {
"label": "Availability",
"ai": "24 / 7 / 365",
"agency": "Business hours",
"inhouse": "Sick leaves & holidays"
},
"metric4": {
"label": "Scalability",
"ai": "Unlimited",
"agency": "Limited by staff",
"inhouse": "Hard to scale"
},
"altHeading": "The alternatives",
"alt1": "Traditional Agency",
"alt2": "In-House Hire",
"footer": "Switch from legacy methods — save up to 70% on costs and 30+ hours per week.",
"cta": "Get Your Free Consultation"
},
"blogSection": {
"title": "Recent Updates",
"readMore": "Read More →",
"viewAll": "View All Posts →"
},
"resources": {
"title": "Free Resources to Scale Your Business"
},
"contactSection": {
"title": "Ready to Automate?",
"subtitle": "Stop wasting time on routine. Start scaling with AI today."
},
"contactForm": {
"title": "Get in touch:",
"fullName": "Full Name",
"fullNamePlaceholder": "John Doe",
"jobTitle": "Job Title / Role",
"jobTitlePlaceholder": "Project Manager",
"email": "Work Email",
"emailPlaceholder": "john@company.com",
"need": "Automation Need",
"needPlaceholder": "Workflow optimization",
"company": "Company Name",
"companyPlaceholder": "Tech Solutions Inc.",
"phone": "Phone Number",
"phonePlaceholder": "+44...",
"submit": "Submit a request",
"sending": "Sending...",
"error": "Something went wrong. Please try again.",
"successTitle": "Thank you!",
"successText": "We have received your request and will contact you shortly.",
"sendAnother": "Send another"
},
"footer": {
"privacy": "Privacy Policy",
"terms": "Terms of Use",
"copyright": "© 2026 AImpress LTD. All rights reserved."
},
"cookie": {
"text": "We use cookies and similar technologies to analyse website traffic and improve your experience. By clicking \"Accept\", you consent to the use of analytics cookies. See our {privacyLink} for details.",
"privacyLink": "Privacy Policy",
"reject": "Reject",
"accept": "Accept"
},
"chat": {
"greeting": "Hi! How can I help you today?",
"openChat": "Open chat",
"headerTitle": "AImpress",
"status": "Online",
"clearChat": "Clear chat",
"closeChat": "Close chat",
"welcome": "Hi! I'm the AImpress AI assistant. Ask me about our AI & automation services, pricing, or book a free consultation.",
"lead": {
"title": "AImpress",
"subtitle": "AI & Automation Consultancy",
"intro": "Hi! Before we start, please introduce yourself so we can better assist you.",
"namePlaceholder": "Your name *",
"nameError": "Please enter your name",
"emailPlaceholder": "Email *",
"emailError": "Please enter your email",
"emailInvalid": "Please enter a valid email",
"companyPlaceholder": "Company (optional)",
"consent": "I agree to the processing of my personal data in accordance with the {privacyLink}",
"privacyLink": "Privacy Policy",
"consentError": "Please accept to continue",
"submit": "Start Chat"
},
"inputPlaceholder": "Type a message...",
"send": "Send message"
},
"quoteForm": {
"title": "Get Your Quote",
"fullName": "Full Name",
"fullNamePlaceholder": "John Doe",
"jobTitle": "Job Title / Role",
"jobTitlePlaceholder": "Project Manager",
"email": "Work Email",
"emailPlaceholder": "john@company.com",
"phone": "Phone Number",
"phonePlaceholder": "+44...",
"company": "Company Name",
"companyPlaceholder": "Tech Solutions Ltd",
"service": "Service",
"serviceDefault": "Select a service...",
"service1": "Workflow Automation Implementation",
"service2": "System Integration & Synchronisation",
"service3": "CRM Workflow Optimisation",
"service4": "Marketing Automation Setup",
"service5": "AI Integration & Enhancement",
"service6": "Infrastructure Setup & Configuration",
"service7": "Support Retainer",
"service8": "Training & Workshop",
"service9": "Other / Not sure yet",
"description": "Project Description",
"descriptionPlaceholder": "Describe your automation needs, current challenges, and desired outcomes...",
"submit": "Get Your Quote",
"sending": "Sending...",
"error": "Something went wrong. Please try again.",
"successTitle": "Thank you!",
"successText": "We've received your quote request. We'll review your requirements and get back to you within 24 hours with a detailed proposal.",
"sendAnother": "Submit another request"
},
"about": {
"hero": {
"title": "About AImpress",
"subtitle": "Making professional automation accessible to impact-driven organisations."
},
"story": {
"title": "Our Story",
"p1": "Automation is no longer optional — it's the difference between growing and getting left behind. Yet for most SMEs, the options have been limited: offshore teams that are cheap but unreliable, or UK agencies that charge enterprise prices for basic work.",
"p2": "AImpress was founded to fill that gap. We're a London-based consultancy that brings enterprise-grade automation to small and medium businesses, charities, and public sector organisations — at prices that actually make sense.",
"p3": "We don't believe in black-box solutions or vendor lock-in. Every system we build runs on infrastructure you own, with documentation your team can follow. When we leave, you keep everything — and you know how it works."
},
"diff": {
"title": "What Makes Us Different"
},
"diff1": {
"title": "UK-Based, London Standards",
"desc": "Competitive rates of £90120/hr. UK business hours, GDPR-compliant by default, full accountability under English law."
},
"diff2": {
"title": "SME Specialisation",
"desc": "We focus on CRM, marketing, finance, and e-commerce automation — the workflows that matter most to growing businesses."
},
"diff3": {
"title": "Client-Owned Infrastructure",
"desc": "Your servers, your data, your accounts. We build on infrastructure you own — no vendor lock-in, no hostage situations."
},
"diff4": {
"title": "Knowledge Transfer, Not Dependency",
"desc": "Every project includes full documentation and team training. We teach your people to maintain what we build."
},
"values": {
"title": "Our Values"
},
"val1": {
"name": "Transparency",
"desc": "Fixed prices, clear scope, no hidden fees"
},
"val2": {
"name": "Client Ownership",
"desc": "You own everything we build — code, data, infrastructure"
},
"val3": {
"name": "Excellence",
"desc": "Enterprise-grade quality at SME-friendly prices"
},
"val4": {
"name": "Impact Over Profit",
"desc": "Discounted rates for charities, startups, and public sector"
},
"val5": {
"name": "Pragmatism",
"desc": "We recommend what works, not what costs more"
},
"founder": {
"title": "Meet the Founder",
"name": "Vadym Samoilenko",
"role": "CEO & Founder of AImpress Ltd",
"bgLabel": "Background:",
"bgText": "2.5+ years at OLIVER Agency (WPP) as Global Automation & AI Specialist, architecting AI-powered workflows that reduced manual effort by 3050% across creative operations for global brands",
"certLabel": "AI & Automation Certifications:",
"certText": "Prompt Engineering Specialization (Vanderbilt University), Generative AI for Marketing (Microsoft Copilot), Prompt Design in Vertex AI (Google), AI in Business (LinkedIn), Make Basics",
"analyticsLabel": "Analytics Certifications:",
"analyticsText": "Microsoft Power BI Data Analyst, Laba Business Analytics & Marketing Analytics",
"eduLabel": "Education:",
"eduText": "Master's in Economic Cybernetics — systems modelling, data analysis, process optimisation",
"visionLabel": "Vision:",
"visionText": "Founded AImpress to bring enterprise-level automation to SMEs at accessible price points"
},
"industries": {
"title": "Industries We Serve"
},
"ind1": {
"name": "E-commerce",
"desc": "Order processing, inventory sync, customer journeys"
},
"ind2": {
"name": "Professional Services",
"desc": "CRM, invoicing, client onboarding automation"
},
"ind3": {
"name": "SaaS",
"desc": "User onboarding, billing, support ticket workflows"
},
"ind4": {
"name": "Charities",
"desc": "Donor management, grant reporting, volunteer coordination"
},
"ind5": {
"name": "Education",
"desc": "Enrolment, student comms, content delivery"
},
"ind6": {
"name": "Healthcare",
"desc": "Appointment scheduling, patient records, compliance"
},
"ind7": {
"name": "Public Sector",
"desc": "Case management, reporting, citizen services"
},
"cta": {
"title": "Ready to Transform Your Operations?",
"subtitle": "Book a free discovery call and find out how automation can work for your business.",
"button": "Book a Free Discovery Call"
}
},
"services": {
"hero": {
"title": "Our Services",
"subtitle": "End-to-end automation consulting — from discovery to deployment and beyond."
},
"s1": {
"title": "AI Chatbots & Virtual Assistants",
"price": "£3,000 £10,000",
"purpose": "Deploy intelligent chatbots that handle customer support, qualify leads, and book appointments 24/7 — no human required.",
"f1": "Custom chatbot design & personality",
"f2": "Integration with your website, WhatsApp, or Messenger",
"f3": "Knowledge base training on your business data",
"f4": "Lead qualification & CRM handoff",
"f5": "Multi-language support",
"f6": "Analytics dashboard & conversation insights"
},
"s2": {
"title": "Custom Website Development",
"price": "£2,500 £15,000",
"purpose": "High-performance, conversion-optimised websites built with modern tech — fast, SEO-ready, and fully yours.",
"f1": "Custom design & responsive development",
"f2": "React / Next.js or WordPress build",
"f3": "SEO optimisation & Core Web Vitals",
"f4": "CMS integration for easy content updates",
"f5": "Contact forms, analytics & tracking setup",
"f6": "Hosting setup on your own infrastructure"
},
"s3": {
"title": "Workflow Automation Implementation",
"price": "£3,500 £12,000",
"purpose": "Automate repetitive business processes end-to-end so your team focuses on high-value work.",
"f1": "Process discovery & mapping",
"f2": "Custom workflow design & build (n8n / Make.com)",
"f3": "Multi-step logic with conditional branching",
"f4": "Error handling & retry mechanisms",
"f5": "Testing, deployment & documentation"
},
"s4": {
"title": "System Integration & Synchronisation",
"price": "£2,500 £10,000+",
"purpose": "Connect your tools into a single source of truth — CRM, accounting, e-commerce, comms, and more.",
"f1": "API integration between platforms",
"f2": "Bi-directional data sync",
"f3": "Data mapping & transformation",
"f4": "Webhook & event-driven triggers",
"f5": "Monitoring & alerting setup"
},
"s5": {
"title": "CRM Workflow Optimisation",
"price": "£3,000 £6,500",
"purpose": "Streamline your sales pipeline, automate follow-ups, and ensure no lead falls through the cracks.",
"f1": "CRM audit & pipeline restructure",
"f2": "Automated lead scoring & routing",
"f3": "Email sequence automation",
"f4": "Task & reminder workflows",
"f5": "Reporting dashboard setup"
},
"s6": {
"title": "Marketing Automation Setup",
"price": "£3,500 £8,000",
"purpose": "Put your campaigns, lead nurturing, and ads on autopilot with targeted, data-driven automation.",
"f1": "Email drip campaign setup",
"f2": "Lead capture & form automation",
"f3": "Audience segmentation logic",
"f4": "Social media scheduling integration",
"f5": "Analytics & conversion tracking"
},
"s7": {
"title": "AI Integration & Enhancement",
"price": "£4,000 £12,000",
"purpose": "Add AI capabilities to your existing workflows — chatbots, content generation, document processing, and more.",
"f1": "AI model selection & integration (OpenAI, Claude, etc.)",
"f2": "Custom chatbot / virtual assistant build",
"f3": "Document & data extraction with AI",
"f4": "AI-powered content generation pipelines",
"f5": "Prompt engineering & fine-tuning"
},
"s8": {
"title": "Infrastructure Setup & Configuration",
"price": "£1,500 £4,000",
"purpose": "Set up your automation infrastructure on servers you own — secure, scalable, and fully yours.",
"f1": "Server provisioning (VPS / cloud)",
"f2": "n8n / automation platform deployment",
"f3": "SSL, firewall & security hardening",
"f4": "Backup & recovery configuration",
"f5": "Monitoring & uptime alerting"
},
"popular": "Popular",
"whatsIncluded": "What's included",
"showLess": "Show less",
"assurance": {
"title": "AImpress Assurance Pack",
"subtitle": "Included free in every project (value £1,500)",
"i1": "Dedicated project manager",
"i2": "Weekly progress reports",
"i3": "Full technical documentation",
"i4": "End-user training session",
"i5": "Admin training session",
"i6": "30-day post-launch support",
"i7": "Bug fixes within SLA",
"i8": "Knowledge base & runbooks",
"i9": "Handover & transition plan"
},
"metrics": {
"title": "Results in Numbers",
"v1": "3050%",
"l1": "Reduction in manual work",
"v2": "28 wks",
"l2": "Average delivery time",
"v3": "24/7",
"l3": "Automated uptime",
"v4": "£0",
"l4": "Vendor lock-in fees"
},
"selector": {
"title": "Which Service Do You Need?",
"step1": "Your Goal",
"step2": "Budget",
"step3": "Results",
"goalQ": "What's your primary goal?",
"goal1": "Automate workflows",
"goal2": "Get more leads",
"goal3": "Build online presence",
"goal4": "Connect my tools",
"goal5": "Add AI capabilities",
"budgetQ": "What's your budget range?",
"budget1": "Under £5K",
"budget2": "£5K £10K",
"budget3": "£10K+",
"resultsHeading": "We recommend these services:",
"noMatch": "No exact match — but we can help! Contact us for a custom solution.",
"viewButton": "View Services",
"resetButton": "Start Over",
"backButton": "← Back"
},
"bundles": {
"title": "Popular Bundles"
},
"bundle1": {
"name": "Starter",
"tagline": "Launch & Engage",
"price": "from £5,500"
},
"bundle2": {
"name": "Growth",
"tagline": "Scale & Convert",
"price": "from £9,000",
"badge": "Most Popular"
},
"bundle3": {
"name": "Full Stack",
"tagline": "Transform Everything",
"price": "Custom pricing"
},
"bundle": {
"cta": "Get Started"
},
"cta": {
"title": "Not Sure Where to Start?",
"subtitle": "Book a free consultation and we'll map out the best automation strategy for your business.",
"button": "Get Your Free Consultation"
}
},
"pricing": {
"hero": {
"title": "Simple, Transparent Pricing",
"subtitle": "Fixed-price projects. No surprise costs. No vendor lock-in."
},
"impl": {
"title": "Implementation Pricing",
"s1": {
"_": "AI Chatbots & Virtual Assistants",
"price": "£3,000 £10,000"
},
"s2": {
"_": "Custom Website Development",
"price": "£2,500 £15,000"
},
"s3": {
"_": "Workflow Automation Implementation",
"price": "£3,500 £12,000"
},
"s4": {
"_": "System Integration & Synchronisation",
"price": "£2,500 £10,000+"
},
"s5": {
"_": "CRM Workflow Optimisation",
"price": "£3,000 £6,500"
},
"s6": {
"_": "Marketing Automation Setup",
"price": "£3,500 £8,000"
},
"s7": {
"_": "AI Integration & Enhancement",
"price": "£4,000 £12,000"
},
"s8": {
"_": "Infrastructure Setup & Configuration",
"price": "£1,500 £4,000"
}
},
"popular": "Popular",
"retainers": {
"title": "Support Retainers"
},
"ret1": {
"name": "Essential",
"price": "£1,000",
"period": "/month",
"hours": "10 hours",
"sla": "48h response",
"f1": "10 hours of support",
"f2": "Bug fixes & minor updates",
"f3": "48-hour response SLA",
"f4": "Email support",
"f5": "Monthly health check"
},
"ret2": {
"name": "Professional",
"price": "£2,000",
"hours": "22 hours",
"sla": "24h response",
"f1": "22 hours of support",
"f2": "Bug fixes, updates & new features",
"f3": "24-hour response SLA",
"f4": "Email + Slack support",
"f5": "Bi-weekly strategy call",
"f6": "Priority scheduling",
"badge": "Most Popular"
},
"ret3": {
"name": "Enterprise",
"price": "£3,500",
"hours": "40 hours",
"sla": "4h response",
"f1": "40 hours of support",
"f2": "Full-scope development & support",
"f3": "4-hour response SLA",
"f4": "Dedicated Slack channel",
"f5": "Weekly strategy call",
"f6": "Priority scheduling",
"f7": "Quarterly roadmap review"
},
"training": {
"title": "Training & Workshops",
"t1": {
"_": "End-User Training",
"price": "£250",
"desc": "Per session"
},
"t2": {
"_": "Admin Training",
"price": "£600 £1,000"
},
"t3": {
"_": "Certification Programme",
"price": "£1,800",
"desc": "Full course"
},
"t4": {
"_": "Custom Workshop",
"price": "£400 £1,200",
"desc": "Half to full day"
}
},
"payment": {
"title": "Payment Terms",
"r1": {
"_": "Under £5,000",
"split": "100% upfront"
},
"r2": {
"_": "£5,000 £10,000",
"split": "50% / 50%"
},
"r3": {
"_": "Over £10,000",
"split": "33% / 33% / 34%"
},
"r4": {
"_": "Public Sector",
"split": "Net 30 terms"
}
},
"discounts": {
"title": "Impact Grant Programme",
"intro": "We believe automation should be accessible to organisations making a difference. Eligible groups receive significant discounts.",
"g1": {
"_": "Charities & Non-Profits",
"disc": "Up to 50%"
},
"g2": "Startups (< 2 years)",
"g3": "Education",
"g4": {
"_": "Public Sector",
"disc": "25% + free pilot project"
},
"g5": "Ukrainian Businesses"
},
"compare": {
"title": "How We Compare",
"aimpress": "AImpress",
"agency": "Agency",
"inhouse": "In-House",
"r1": {
"metric": "Setup Cost",
"ai": "From £1,500",
"agency": "£5,000+ /mo",
"inhouse": "£35,000+ /yr"
},
"r2": {
"metric": "Time to Deploy",
"ai": "28 weeks",
"agency": "36 months",
"inhouse": "612 months"
},
"r3": {
"metric": "Availability",
"ai": "24/7 automated",
"agency": "Business hours",
"inhouse": "9-to-5 only"
},
"r4": {
"metric": "Scalability",
"ai": "Unlimited",
"agency": "Staff-limited",
"inhouse": "Hard to scale"
},
"r5": {
"metric": "You Own It",
"ai": "Yes, always",
"agency": "Rarely"
},
"r6": {
"metric": "Hidden Costs",
"ai": "None",
"agency": "Change requests",
"inhouse": "Benefits, turnover"
}
},
"faq": {
"title": "Frequently Asked Questions",
"q1": "Are you a UK company?",
"a1": "Yes. AImpress Ltd is registered in England & Wales (company number 16417799), VAT-registered, and ICO-registered. We operate under English law with full GDPR compliance.",
"q2": "Do you offer managed hosting?",
"a2": "We set up infrastructure on your own servers or cloud accounts. You own everything. We can provide ongoing management through our support retainers if needed.",
"q3": "What platforms do you work with?",
"a3": "We work with n8n, Make.com, Zapier, Power Automate, HubSpot, Salesforce, Pipedrive, Mailchimp, OpenAI, Claude, and many more. If your tool has an API, we can integrate it.",
"q4": "Can you work with our existing tools?",
"a4": "Absolutely. We build on top of your current stack — we don't rip and replace. Our goal is to connect and automate what you already have.",
"q5": "What if I don't qualify for a discount?",
"a5": "Our standard rates are already competitive at £90120/hr — significantly below typical UK agency rates. We offer fixed-price projects so you always know the total cost upfront.",
"q6": "Do you work with clients outside the UK?",
"a6": "Yes, we work with international clients. Our primary focus is UK businesses, but we're happy to support companies anywhere that need professional automation consulting."
},
"cta": {
"title": "Get Your Quote Today",
"subtitle": "Tell us about your project and we'll send you a detailed, fixed-price proposal within 24 hours."
}
},
"blog": {
"title": "Blog",
"loading": "Loading posts...",
"noPosts": "No posts yet.",
"readMore": "Read More →"
},
"blogPost": {
"back": "← Back to Blog",
"notFound": "Post not found",
"loading": "Loading...",
"source": "Source:"
},
"seo": {
"home": {
"title": "AImpress | AI & Automation Consulting for SMEs | London, UK",
"description": "AImpress helps small and medium businesses in the UK automate operations, cut costs, and grow faster with AI-powered solutions. Based in London."
},
"about": {
"title": "About Us | AImpress — AI & Automation Consulting, London",
"description": "AImpress Ltd is a London-based automation consultancy for SMEs, charities, and public sector. Founded 2024. Client-owned infrastructure, no vendor lock-in."
},
"services": {
"title": "AI & Automation Services for UK Businesses | AImpress",
"description": "Workflow automation, system integration, CRM optimisation, marketing automation, AI integration, and infrastructure setup. Fixed-price projects from £1,500."
},
"pricing": {
"title": "Pricing | AImpress — Transparent Automation Costs from £1,500",
"description": "Fixed-price automation projects from £1,500. Support retainers from £1,000/month. Up to 50% discount for charities, startups, and public sector."
},
"blog": {
"title": "Blog | AImpress — AI Automation Insights",
"description": "Insights, guides, and case studies on AI automation for small and medium businesses. Stay ahead with AImpress."
},
"siteName": "AImpress"
}
}

View file

@ -0,0 +1,771 @@
{
"header": {
"nav": {
"home": "Головна",
"about": "Про нас",
"services": "Послуги",
"pricing": "Ціни",
"blog": "Блог",
"contacts": "Контакти"
},
"lang": {
"en": "Eng",
"uk": "Укр"
},
"login": "Увійти",
"loginModal": {
"title": "З поверненням",
"emailLabel": "Email / Логін",
"emailPlaceholder": "Введіть ваш email",
"passwordLabel": "Пароль",
"passwordPlaceholder": "Введіть ваш пароль",
"submit": "Увійти",
"signupPrompt": "Немає акаунту?",
"signupLink": "Зареєструватися"
}
},
"hero": {
"circle1": "Будуй.",
"circle2": "Автоматизуй.",
"circle3": "Вражай.",
"title": "Припиніть наймати. Починайте масштабувати. Розгорніть свою AI-команду.",
"cta": "Отримати безкоштовну консультацію"
},
"benefits": {
"card1": {
"front": "Вартість і масштаб",
"subtitle": "Еластичне зростання, нуль штату",
"back": "Масштабуйтесь у 10 разів без найму. AI-асистенти автоматично обробляють пікові навантаження, зберігаючи гнучкість та ефективність ваших операцій."
},
"card2": {
"front": "Точність",
"subtitle": "Точність машинного навчання (99,9%)",
"back": "Усуньте людський фактор. Наші ML-валідовані процеси гарантують цілісність даних у CRM, фінансах та логістиці."
},
"card3": {
"front": "Доступність",
"subtitle": "Справжня робота 24/7/365",
"back": "Ваша AI-команда ніколи не спить, не бере перерв і не вигоряє. Обслуговуйте клієнтів по всьому світу безперервно."
},
"builtTitle": "Створено для місцевих підприємців, таких як ви",
"builtDesc": "AImpress перетворює хаос на систему. Ми створюємо автоматизації, які економлять до 75% вашого часу та збільшують продажі.",
"static1": {
"title": "Чат-боти та AI-асистенти",
"desc": "→ миттєві відповіді 24/7"
},
"static2": {
"title": "Автоматизація бізнес-процесів (n8n, Make.com)",
"desc": "→ CRM, email, фінанси, складський облік"
},
"static3": {
"title": "Контент-ферми та AI-копірайтинг",
"desc": "→ AI створює пости, статті, описи товарів"
},
"static4": {
"title": "Маркетингова автоматизація (email, CRM, реклама)",
"desc": "→ кампанії, прогрів лідів, реклама на автопілоті"
}
},
"banner1": {
"q1": "Скільки працівників у вашій компанії?",
"q2": "Скільки годин на день витрачається на рутинні завдання?",
"q3": "Які процеси ви хочете автоматизувати?",
"cta": "Отримати безкоштовну консультацію"
},
"realResults": {
"title": "Реальні результати реальних клієнтів",
"card1": {
"title": "AutoBrat Garage",
"resultsLabel": "Результати:",
"desc": "Спеціалізована майстерня, заснована українцями, мала проблеми з місцевою впізнаваністю. AImpress створив двомовний контент, що демонструє їхню експертизу з німецьких автомобілів.",
"stat1": "157% — зростання бронювань",
"stat2": "85% — завантаженість сервісних боксів",
"stat3": "згадка в Oxford Mail протягом 6 місяців"
},
"card2": {
"title": "Cotswolld Honey Company",
"desc": "Виробник крафтового меду, обмежений сезонними ринками. AImpress розробив e-commerce та освітній контент, що підкреслює сталі практики.",
"stat1": "78% — зростання онлайн-продажів",
"stat2": "чотири нових роздрібних партнерства всього за 4 місяці"
},
"card3": {
"title": "Wcounting Accounting Partners",
"desc": "Традиційна фірма, що втрачала молодих клієнтів. AImpress створив зрозумілі фінансові гіди та контент щодо Making Tax Digital.",
"stat1": "41% — зростання запитів від клієнтів до 40 років",
"stat2": "12 — нових e-commerce клієнтів за 5 місяців"
}
},
"timeline": {
"title": "Ваш шлях до автономних операцій",
"step1": {
"title": "Брифінг завдання",
"duration": "2 год",
"short": "Визначте найвпливовіші можливості та метрики ROI.",
"detail": "Ми аудируємо ваші процеси, знаходимо вузькі місця та визначаємо пріоритетні цілі автоматизації з найвищим ROI — все за одну фокусну сесію."
},
"step2": {
"title": "Технічна оцінка та стратегія",
"duration": "23 дні",
"short": "Огляд існуючого стеку, архітектури та відповідності.",
"detail": "Глибокий аналіз вашої CRM, бухгалтерії, комунікацій та потоків даних. Ми проєктуємо план інтеграції та модель безпеки ще до написання першого рядка коду."
},
"step3": {
"title": "Proof of Concept",
"duration": "812 тижнів",
"short": "Пілот для критичного процесу — видимий ROI.",
"detail": "Ми створюємо та впроваджуємо робочу автоматизацію для вашого найболючішого процесу. Ви побачите вимірну економію часу та коштів вже у першому спринті."
},
"step4": {
"title": "Впровадження MVP",
"duration": "23 місяці",
"short": "Повне розгортання, навчання команди та інтеграція.",
"detail": "Впровадження у всіх відділах з практичним навчанням, моніторинговими дашбордами та виділеним Slack-каналом для миттєвої підтримки."
},
"step5": {
"title": "Масштабування та оптимізація",
"duration": "Постійно",
"short": "Безперервне вдосконалення та розширення.",
"detail": "Щомісячні огляди продуктивності, A/B-тестування автоматизацій та розширення на нові відділи. Ваша AI-команда зростає разом з вами."
}
},
"banner2": {
"cta": "Отримати безкоштовну консультацію"
},
"comparison": {
"title": "Чому бізнеси переходять на AImpress",
"aiLabel": "AI-Powered",
"metric1": {
"label": "Вартість",
"ai": "Від £1 500",
"agency": "£5 000+ /міс агенція",
"inhouse": "£35 000+ /рік штатний спеціаліст"
},
"metric2": {
"label": "Швидкість",
"ai": "Миттєво",
"agency": "Залежить від менеджера",
"inhouse": "Тільки з 9 до 18"
},
"metric3": {
"label": "Доступність",
"ai": "24 / 7 / 365",
"agency": "Робочі години",
"inhouse": "Лікарняні та відпустки"
},
"metric4": {
"label": "Масштабованість",
"ai": "Необмежена",
"agency": "Обмежена штатом",
"inhouse": "Складно масштабувати"
},
"altHeading": "Альтернативи",
"alt1": "Традиційна агенція",
"alt2": "Штатний працівник",
"footer": "Перейдіть з застарілих методів — заощаджуйте до <strong>70%</strong> на витратах та <strong>30+ годин</strong> на тиждень.",
"cta": "Отримати безкоштовну консультацію"
},
"blogSection": {
"title": "Останні оновлення",
"readMore": "Читати далі →",
"viewAll": "Усі публікації →"
},
"resources": {
"title": "Безкоштовні ресурси для масштабування вашого бізнесу"
},
"contactSection": {
"title": "Готові до автоматизації?",
"subtitle": "Припиніть витрачати час на рутину. Починайте масштабуватись з AI вже сьогодні."
},
"contactForm": {
"title": "Зв'яжіться з нами:",
"fullName": "Повне ім'я",
"fullNamePlaceholder": "Іван Петренко",
"jobTitle": "Посада / Роль",
"jobTitlePlaceholder": "Менеджер проєктів",
"email": "Робочий email",
"emailPlaceholder": "ivan@company.com",
"need": "Потреба в автоматизації",
"needPlaceholder": "Оптимізація процесів",
"company": "Назва компанії",
"companyPlaceholder": "Тех Рішення",
"phone": "Номер телефону",
"phonePlaceholder": "+44...",
"submit": "Надіслати запит",
"sending": "Надсилання...",
"error": "Щось пішло не так. Будь ласка, спробуйте ще раз.",
"successTitle": "Дякуємо!",
"successText": "Ми отримали ваш запит і зв'яжемося з вами найближчим часом.",
"sendAnother": "Надіслати ще"
},
"footer": {
"privacy": "Політика конфіденційності",
"terms": "Умови використання",
"copyright": "© 2026 AImpress LTD. Усі права захищені."
},
"cookie": {
"text": "Ми використовуємо файли cookie та подібні технології для аналізу трафіку на сайті та покращення вашого досвіду. Натискаючи «Прийняти», ви погоджуєтесь на використання аналітичних cookie.",
"privacyLink": "Політика конфіденційності",
"reject": "Відхилити",
"accept": "Прийняти"
},
"chat": {
"greeting": "Привіт! Чим я можу вам допомогти?",
"openChat": "Відкрити чат",
"headerTitle": "AImpress",
"status": "Онлайн",
"clearChat": "Очистити чат",
"closeChat": "Закрити чат",
"welcome": "Привіт! Я AI-асистент AImpress. Запитайте мене про наші послуги з AI та автоматизації, ціни або запишіться на безкоштовну консультацію.",
"lead": {
"title": "AImpress",
"subtitle": "Консалтинг з AI та автоматизації",
"intro": "Привіт! Перед початком, будь ласка, представтеся, щоб ми могли краще вам допомогти.",
"namePlaceholder": "Ваше ім'я *",
"nameError": "Будь ласка, введіть ваше ім'я",
"emailPlaceholder": "Email *",
"emailError": "Будь ласка, введіть ваш email",
"emailInvalid": "Будь ласка, введіть дійсний email",
"companyPlaceholder": "Компанія (необов'язково)",
"consent": "Я погоджуюсь на обробку моїх персональних даних відповідно до",
"privacyLink": "Політики конфіденційності",
"consentError": "Будь ласка, надайте згоду для продовження",
"submit": "Розпочати чат"
},
"inputPlaceholder": "Введіть повідомлення...",
"send": "Надіслати повідомлення"
},
"quoteForm": {
"title": "Отримати пропозицію",
"fullName": "Повне ім'я",
"fullNamePlaceholder": "Іван Петренко",
"jobTitle": "Посада / Роль",
"jobTitlePlaceholder": "Менеджер проєктів",
"email": "Робочий email",
"emailPlaceholder": "ivan@company.com",
"phone": "Номер телефону",
"phonePlaceholder": "+44...",
"company": "Назва компанії",
"companyPlaceholder": "Тех Рішення",
"service": "Послуга",
"serviceDefault": "Оберіть послугу...",
"service1": "Впровадження автоматизації процесів",
"service2": "Системна інтеграція та синхронізація",
"service3": "Оптимізація CRM-процесів",
"service4": "Налаштування маркетингової автоматизації",
"service5": "Інтеграція та впровадження AI",
"service6": "Налаштування інфраструктури",
"service7": "Ретейнер підтримки",
"service8": "Навчання та воркшопи",
"service9": "Інше / Ще не визначився",
"description": "Опис проєкту",
"descriptionPlaceholder": "Опишіть ваші потреби в автоматизації, поточні виклики та бажані результати...",
"submit": "Отримати пропозицію",
"sending": "Надсилання...",
"error": "Щось пішло не так. Будь ласка, спробуйте ще раз.",
"successTitle": "Дякуємо!",
"successText": "Ми отримали ваш запит на пропозицію. Ми розглянемо ваші вимоги та надішлемо детальну пропозицію протягом 24 годин.",
"sendAnother": "Надіслати ще один запит"
},
"about": {
"hero": {
"title": "Про AImpress",
"subtitle": "Робимо професійну автоматизацію доступною для організацій, що створюють зміни."
},
"story": {
"title": "Наша історія",
"p1": "Автоматизація — це більше не опція, а різниця між зростанням та відставанням. Проте для більшості МСП варіанти були обмежені: офшорні команди — дешево, але ненадійно, або британські агенції, що беруть корпоративні ціни за базову роботу.",
"p2": "AImpress створено, щоб заповнити цю прогалину. Ми — лондонська консалтингова компанія, що приносить автоматизацію корпоративного рівня малому та середньому бізнесу, благодійним організаціям та державному сектору — за цінами, які дійсно мають сенс.",
"p3": "Ми не віримо в «чорні скриньки» чи прив'язку до постачальника. Кожна система, яку ми створюємо, працює на вашій власній інфраструктурі з документацією, яку ваша команда може використовувати. Коли ми завершуємо — ви зберігаєте все, і ви знаєте, як це працює."
},
"diff": {
"title": "Що нас відрізняє"
},
"diff1": {
"title": "Базування у Великобританії, лондонські стандарти",
"desc": "Конкурентні ставки £90120/год. Британські робочі години, GDPR-відповідність за замовчуванням, повна відповідальність за законодавством Англії."
},
"diff2": {
"title": "Спеціалізація на МСП",
"desc": "Ми фокусуємось на CRM, маркетингу, фінансах та e-commerce автоматизації — процесах, що найбільше важливі для бізнесу, що зростає."
},
"diff3": {
"title": "Інфраструктура, що належить клієнту",
"desc": "Ваші сервери, ваші дані, ваші акаунти. Ми будуємо на інфраструктурі, якою ви володієте — жодної прив'язки до постачальника."
},
"diff4": {
"title": "Передача знань, а не залежність",
"desc": "Кожен проєкт включає повну документацію та навчання команди. Ми вчимо ваших людей підтримувати те, що ми створили."
},
"values": {
"title": "Наші цінності"
},
"val1": {
"name": "Прозорість",
"desc": "Фіксовані ціни, чіткий обсяг, жодних прихованих платежів"
},
"val2": {
"name": "Власність клієнта",
"desc": "Ви володієте всім, що ми створюємо — код, дані, інфраструктура"
},
"val3": {
"name": "Досконалість",
"desc": "Якість корпоративного рівня за цінами, доступними для МСП"
},
"val4": {
"name": "Вплив, а не прибуток",
"desc": "Знижені тарифи для благодійних організацій, стартапів та державного сектору"
},
"val5": {
"name": "Прагматизм",
"desc": "Ми рекомендуємо те, що працює, а не те, що коштує більше"
},
"founder": {
"title": "Засновник",
"name": "Вадим Самойленко",
"role": "CEO та засновник AImpress Ltd",
"bgLabel": "Досвід:",
"bgText": "2,5+ роки в OLIVER Agency (WPP) як глобальний спеціаліст з автоматизації та AI, розробка AI-процесів, що зменшили ручну роботу на 3050% у креативних операціях для глобальних брендів",
"certLabel": "Сертифікації AI та автоматизації:",
"certText": "Prompt Engineering Specialization (Vanderbilt University), Generative AI for Marketing (Microsoft Copilot), Prompt Design in Vertex AI (Google), AI in Business (LinkedIn), Make Basics",
"analyticsLabel": "Сертифікації з аналітики:",
"analyticsText": "Microsoft Power BI Data Analyst, Laba Business Analytics & Marketing Analytics",
"eduLabel": "Освіта:",
"eduText": "Магістр економічної кібернетики — системне моделювання, аналіз даних, оптимізація процесів",
"visionLabel": "Бачення:",
"visionText": "Заснував AImpress, щоб зробити автоматизацію корпоративного рівня доступною для МСП"
},
"industries": {
"title": "Галузі, які ми обслуговуємо"
},
"ind1": {
"name": "E-commerce",
"desc": "Обробка замовлень, синхронізація складу, клієнтські шляхи"
},
"ind2": {
"name": "Професійні послуги",
"desc": "CRM, виставлення рахунків, автоматизація онбордингу клієнтів"
},
"ind3": {
"name": "SaaS",
"desc": "Онбординг користувачів, білінг, процеси обробки тікетів"
},
"ind4": {
"name": "Благодійні організації",
"desc": "Управління донорами, грантова звітність, координація волонтерів"
},
"ind5": {
"name": "Освіта",
"desc": "Зарахування, комунікація зі студентами, доставка контенту"
},
"ind6": {
"name": "Охорона здоров'я",
"desc": "Планування прийомів, медичні записи, відповідність нормам"
},
"ind7": {
"name": "Державний сектор",
"desc": "Управління справами, звітність, послуги для громадян"
},
"cta": {
"title": "Готові трансформувати свої операції?",
"subtitle": "Замовте безкоштовний дзвінок та дізнайтеся, як автоматизація може працювати для вашого бізнесу.",
"button": "Замовити безкоштовну консультацію"
}
},
"services": {
"hero": {
"title": "Наші послуги",
"subtitle": "Комплексний консалтинг з автоматизації — від аналізу до впровадження та подальшої підтримки."
},
"s1": {
"title": "AI чат-боти та віртуальні асистенти",
"price": "£3 000 £10 000",
"purpose": "Розгорніть інтелектуальних чат-ботів, що обслуговують клієнтів, кваліфікують ліди та записують на зустрічі 24/7 — без участі людини.",
"f1": "Розробка чат-бота та персоналізація",
"f2": "Інтеграція з вашим сайтом, WhatsApp або Messenger",
"f3": "Навчання бази знань на даних вашого бізнесу",
"f4": "Кваліфікація лідів та передача в CRM",
"f5": "Мультимовна підтримка",
"f6": "Аналітична панель та інсайти з розмов"
},
"s2": {
"title": "Розробка веб-сайтів",
"price": "£2 500 £15 000",
"purpose": "Високопродуктивні, конверсійно-оптимізовані сайти на сучасних технологіях — швидкі, SEO-готові та повністю ваші.",
"f1": "Індивідуальний дизайн та адаптивна розробка",
"f2": "Розробка на React / Next.js або WordPress",
"f3": "SEO-оптимізація та Core Web Vitals",
"f4": "Інтеграція CMS для зручного оновлення контенту",
"f5": "Контактні форми, аналітика та налаштування трекінгу",
"f6": "Налаштування хостингу на вашій інфраструктурі"
},
"s3": {
"title": "Впровадження автоматизації процесів",
"price": "£3 500 £12 000",
"purpose": "Автоматизуйте повторювані бізнес-процеси від початку до кінця, щоб ваша команда фокусувалась на високоцінній роботі.",
"f1": "Аналіз та картування процесів",
"f2": "Розробка та створення процесів (n8n / Make.com)",
"f3": "Багатокрокова логіка з умовним розгалуженням",
"f4": "Обробка помилок та механізми повторних спроб",
"f5": "Тестування, розгортання та документація"
},
"s4": {
"title": "Системна інтеграція та синхронізація",
"price": "£2 500 £10 000+",
"purpose": "Об'єднайте свої інструменти в єдине джерело правди — CRM, бухгалтерія, e-commerce, комунікації тощо.",
"f1": "API-інтеграція між платформами",
"f2": "Двонаправлена синхронізація даних",
"f3": "Маппінг та трансформація даних",
"f4": "Webhook та тригери на основі подій",
"f5": "Налаштування моніторингу та сповіщень"
},
"s5": {
"title": "Оптимізація CRM-процесів",
"price": "£3 000 £6 500",
"purpose": "Оптимізуйте воронку продажів, автоматизуйте follow-up та переконайтеся, що жоден лід не загубиться.",
"f1": "Аудит CRM та реструктуризація воронки",
"f2": "Автоматичний скоринг та маршрутизація лідів",
"f3": "Автоматизація email-послідовностей",
"f4": "Процеси завдань та нагадувань",
"f5": "Налаштування звітних панелей"
},
"s6": {
"title": "Налаштування маркетингової автоматизації",
"price": "£3 500 £8 000",
"purpose": "Переведіть кампанії, прогрів лідів та рекламу на автопілот з цілеспрямованою, дата-орієнтованою автоматизацією.",
"f1": "Налаштування email drip-кампаній",
"f2": "Автоматизація збору лідів та форм",
"f3": "Логіка сегментації аудиторії",
"f4": "Інтеграція з плануванням соціальних мереж",
"f5": "Аналітика та відстеження конверсій"
},
"s7": {
"title": "Інтеграція та впровадження AI",
"price": "£4 000 £12 000",
"purpose": "Додайте AI-можливості до існуючих процесів — чат-боти, генерація контенту, обробка документів тощо.",
"f1": "Вибір та інтеграція AI-моделей (OpenAI, Claude тощо)",
"f2": "Розробка чат-бота / віртуального асистента",
"f3": "Витяг даних з документів за допомогою AI",
"f4": "Конвеєри AI-генерації контенту",
"f5": "Prompt engineering та fine-tuning"
},
"s8": {
"title": "Налаштування інфраструктури",
"price": "£1 500 £4 000",
"purpose": "Налаштуйте інфраструктуру автоматизації на серверах, якими ви володієте — безпечно, масштабовано та повністю ваше.",
"f1": "Розгортання серверів (VPS / хмара)",
"f2": "Розгортання n8n / платформи автоматизації",
"f3": "SSL, файервол та посилення безпеки",
"f4": "Налаштування резервного копіювання та відновлення",
"f5": "Моніторинг та сповіщення про доступність"
},
"popular": "Популярне",
"whatsIncluded": "Що включено",
"showLess": "Показати менше",
"assurance": {
"title": "Пакет гарантій AImpress",
"subtitle": "Безкоштовно включено в кожен проєкт (вартість £1 500)",
"i1": "Виділений менеджер проєкту",
"i2": "Щотижневі звіти про прогрес",
"i3": "Повна технічна документація",
"i4": "Навчання кінцевих користувачів",
"i5": "Навчання адміністраторів",
"i6": "30-денна підтримка після запуску",
"i7": "Виправлення помилок в рамках SLA",
"i8": "База знань та runbooks",
"i9": "План передачі та переходу"
},
"metrics": {
"title": "Результати в цифрах",
"v1": "3050%",
"l1": "Зменшення ручної роботи",
"v2": "28 тижнів",
"l2": "Середній час реалізації",
"v3": "24/7",
"l3": "Автоматизований аптайм",
"v4": "£0",
"l4": "Плата за прив'язку до постачальника"
},
"selector": {
"title": "Яка послуга вам потрібна?",
"step1": "Ваша мета",
"step2": "Бюджет",
"step3": "Результати",
"goalQ": "Яка ваша основна мета?",
"goal1": "Автоматизувати процеси",
"goal2": "Отримати більше лідів",
"goal3": "Побудувати онлайн-присутність",
"goal4": "З'єднати мої інструменти",
"goal5": "Додати AI-можливості",
"budgetQ": "Який ваш діапазон бюджету?",
"budget1": "До £5K",
"budget2": "£5K £10K",
"budget3": "£10K+",
"resultsHeading": "Ми рекомендуємо ці послуги:",
"noMatch": "Точного збігу немає — але ми можемо допомогти! Зв'яжіться з нами для індивідуального рішення.",
"viewButton": "Переглянути послуги",
"resetButton": "Почати спочатку",
"backButton": "← Назад"
},
"bundles": {
"title": "Популярні пакети"
},
"bundle1": {
"name": "Starter",
"tagline": "Запуск та залучення",
"price": "від £5 500"
},
"bundle2": {
"name": "Growth",
"tagline": "Масштабування та конверсія",
"price": "від £9 000",
"badge": "Найпопулярніший"
},
"bundle3": {
"name": "Full Stack",
"tagline": "Трансформація всього",
"price": "Індивідуальна ціна"
},
"bundle": {
"cta": "Розпочати"
},
"cta": {
"title": "Не знаєте, з чого почати?",
"subtitle": "Замовте безкоштовну консультацію, і ми розробимо найкращу стратегію автоматизації для вашого бізнесу.",
"button": "Отримати безкоштовну консультацію"
}
},
"pricing": {
"hero": {
"title": "Прості, прозорі ціни",
"subtitle": "Проєкти з фіксованою ціною. Без несподіваних витрат. Без прив'язки до постачальника."
},
"impl": {
"title": "Ціни на впровадження",
"s1": {
"_": "AI чат-боти та віртуальні асистенти",
"price": "£3 000 £10 000"
},
"s2": {
"_": "Розробка веб-сайтів",
"price": "£2 500 £15 000"
},
"s3": {
"_": "Впровадження автоматизації процесів",
"price": "£3 500 £12 000"
},
"s4": {
"_": "Системна інтеграція та синхронізація",
"price": "£2 500 £10 000+"
},
"s5": {
"_": "Оптимізація CRM-процесів",
"price": "£3 000 £6 500"
},
"s6": {
"_": "Налаштування маркетингової автоматизації",
"price": "£3 500 £8 000"
},
"s7": {
"_": "Інтеграція та впровадження AI",
"price": "£4 000 £12 000"
},
"s8": {
"_": "Налаштування інфраструктури",
"price": "£1 500 £4 000"
}
},
"popular": "Популярне",
"retainers": {
"title": "Ретейнери підтримки"
},
"ret1": {
"name": "Essential",
"price": "£1 000",
"period": "/місяць",
"hours": "10 годин",
"sla": "Відповідь протягом 48 год",
"f1": "10 годин підтримки",
"f2": "Виправлення помилок та незначні оновлення",
"f3": "SLA відповіді 48 годин",
"f4": "Підтримка через email",
"f5": "Щомісячна перевірка стану"
},
"ret2": {
"name": "Professional",
"price": "£2 000",
"hours": "22 години",
"sla": "Відповідь протягом 24 год",
"f1": "22 години підтримки",
"f2": "Виправлення помилок, оновлення та нові функції",
"f3": "SLA відповіді 24 години",
"f4": "Підтримка через email та Slack",
"f5": "Стратегічний дзвінок раз на два тижні",
"f6": "Пріоритетне планування",
"badge": "Найпопулярніший"
},
"ret3": {
"name": "Enterprise",
"price": "£3 500",
"hours": "40 годин",
"sla": "Відповідь протягом 4 год",
"f1": "40 годин підтримки",
"f2": "Повний спектр розробки та підтримки",
"f3": "SLA відповіді 4 години",
"f4": "Виділений Slack-канал",
"f5": "Щотижневий стратегічний дзвінок",
"f6": "Пріоритетне планування",
"f7": "Квартальний огляд дорожньої карти"
},
"training": {
"title": "Навчання та воркшопи",
"t1": {
"_": "Навчання кінцевих користувачів",
"price": "£250",
"desc": "За сесію"
},
"t2": {
"_": "Навчання адміністраторів",
"price": "£600 £1 000"
},
"t3": {
"_": "Програма сертифікації",
"price": "£1 800",
"desc": "Повний курс"
},
"t4": {
"_": "Індивідуальний воркшоп",
"price": "£400 £1 200",
"desc": "Від пів дня до повного дня"
}
},
"payment": {
"title": "Умови оплати",
"r1": {
"_": "До £5 000",
"split": "100% передоплата"
},
"r2": {
"_": "£5 000 £10 000",
"split": "50% / 50%"
},
"r3": {
"_": "Понад £10 000",
"split": "33% / 33% / 34%"
},
"r4": {
"_": "Державний сектор",
"split": "Оплата протягом 30 днів"
}
},
"discounts": {
"title": "Програма грантів впливу",
"intro": "Ми переконані, що автоматизація повинна бути доступною для організацій, що роблять різницю. Відповідні групи отримують значні знижки.",
"g1": {
"_": "Благодійні та некомерційні організації",
"disc": "До 50%"
},
"g2": "Стартапи (менше 2 років)",
"g3": "Освіта",
"g4": {
"_": "Державний сектор",
"disc": "25% + безкоштовний пілотний проєкт"
},
"g5": "Українські бізнеси"
},
"compare": {
"title": "Як ми порівнюємося",
"aimpress": "AImpress",
"agency": "Агенція",
"inhouse": "Штатний спеціаліст",
"r1": {
"metric": "Вартість запуску",
"ai": "Від £1 500",
"agency": "£5 000+ /міс",
"inhouse": "£35 000+ /рік"
},
"r2": {
"metric": "Час розгортання",
"ai": "28 тижнів",
"agency": "36 місяців",
"inhouse": "612 місяців"
},
"r3": {
"metric": "Доступність",
"ai": "24/7 автоматизовано",
"agency": "Робочі години",
"inhouse": "Тільки з 9 до 18"
},
"r4": {
"metric": "Масштабованість",
"ai": "Необмежена",
"agency": "Обмежена штатом",
"inhouse": "Складно масштабувати"
},
"r5": {
"metric": "Ви це володієте",
"ai": "Так, завжди",
"agency": "Рідко"
},
"r6": {
"metric": "Приховані витрати",
"ai": "Немає",
"agency": "Запити на зміни",
"inhouse": "Соцпакет, плинність кадрів"
}
},
"faq": {
"title": "Часті запитання",
"q1": "Ви британська компанія?",
"a1": "Так. AImpress Ltd зареєстрована в Англії та Уельсі (реєстраційний номер 16417799), зареєстрована як платник ПДВ та в ICO. Ми працюємо за англійським законодавством з повною відповідністю GDPR.",
"q2": "Ви пропонуєте керований хостинг?",
"a2": "Ми налаштовуємо інфраструктуру на ваших власних серверах або хмарних акаунтах. Ви володієте всім. За потреби ми можемо забезпечити постійне управління через наші ретейнери підтримки.",
"q3": "З якими платформами ви працюєте?",
"a3": "Ми працюємо з n8n, Make.com, Zapier, Power Automate, HubSpot, Salesforce, Pipedrive, Mailchimp, OpenAI, Claude та багатьма іншими. Якщо ваш інструмент має API, ми можемо його інтегрувати.",
"q4": "Чи можете ви працювати з нашими існуючими інструментами?",
"a4": "Безумовно. Ми будуємо поверх вашого поточного стеку — ми не замінюємо все з нуля. Наша мета — з'єднати та автоматизувати те, що у вас вже є.",
"q5": "Що якщо я не підпадаю під знижку?",
"a5": "Наші стандартні ставки вже конкурентні — £90120/год, що значно нижче типових ставок британських агенцій. Ми пропонуємо проєкти з фіксованою ціною, тому ви завжди знаєте загальну вартість наперед.",
"q6": "Чи працюєте ви з клієнтами за межами Великобританії?",
"a6": "Так, ми працюємо з міжнародними клієнтами. Наш основний фокус — британський бізнес, але ми раді допомогти компаніям будь-де, яким потрібен професійний консалтинг з автоматизації."
},
"cta": {
"title": "Отримайте вашу пропозицію сьогодні",
"subtitle": "Розкажіть про ваш проєкт, і ми надішлемо детальну пропозицію з фіксованою ціною протягом 24 годин."
}
},
"blog": {
"title": "Блог",
"loading": "Завантаження публікацій...",
"noPosts": "Публікацій поки немає.",
"readMore": "Читати далі →"
},
"blogPost": {
"back": "← Назад до блогу",
"notFound": "Публікацію не знайдено",
"loading": "Завантаження...",
"source": "Джерело:"
},
"seo": {
"home": {
"title": "AImpress | Консалтинг з AI та автоматизації для МСП | Лондон, Великобританія",
"description": "AImpress допомагає малому та середньому бізнесу у Великобританії автоматизувати операції, скоротити витрати та швидше зростати за допомогою AI-рішень. Базується в Лондоні."
},
"about": {
"title": "Про нас | AImpress — Консалтинг з AI та автоматизації, Лондон",
"description": "AImpress Ltd — лондонська консалтингова компанія з автоматизації для МСП, благодійних організацій та державного сектору. Заснована 2024. Інфраструктура клієнта, без прив'язки до постачальника."
},
"services": {
"title": "Послуги AI та автоматизації для бізнесу у Великобританії | AImpress",
"description": "Автоматизація процесів, системна інтеграція, оптимізація CRM, маркетингова автоматизація, інтеграція AI та налаштування інфраструктури. Проєкти з фіксованою ціною від £1 500."
},
"pricing": {
"title": "Ціни | AImpress — Прозорі витрати на автоматизацію від £1 500",
"description": "Проєкти автоматизації з фіксованою ціною від £1 500. Ретейнери підтримки від £1 000/місяць. До 50% знижки для благодійних організацій, стартапів та державного сектору."
},
"blog": {
"title": "Блог | AImpress — Інсайти з AI-автоматизації",
"description": "Інсайти, гіди та кейси з AI-автоматизації для малого та середнього бізнесу. Будьте попереду з AImpress."
},
"siteName": "AImpress"
}
}

13595
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,8 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"dev": "tinacms dev -c \"vite\"",
"build": "tinacms build && node scripts/sync-blog.mjs && tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
"sync-blog": "node scripts/sync-blog.mjs",
@ -19,10 +19,12 @@
"react-dom": "^19.2.0",
"react-helmet-async": "^3.0.0",
"react-intersection-observer": "^10.0.2",
"react-router-dom": "^7.13.1"
"react-router-dom": "^7.13.1",
"tinacms": "^3.6.1"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@tinacms/cli": "^2.1.9",
"@types/node": "^24.10.1",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",

View file

@ -1,7 +1,8 @@
import { readdir, readFile, copyFile, mkdir, rm, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { readdir, readFile, copyFile, mkdir, rm, writeFile, stat } from 'node:fs/promises';
import { join, basename } from 'node:path';
const INPUT_DIR = '/Volumes/SSD/Projects/Aimpress/LinkedIn-autopost/output';
const LINKEDIN_INPUT_DIR = '/Volumes/SSD/Projects/Aimpress/LinkedIn-autopost/output';
const TINA_INPUT_DIR = join(import.meta.dirname, '..', 'content', 'blog');
const OUTPUT_DIR = join(import.meta.dirname, '..', 'public', 'blog');
function toSlug(title) {
@ -56,6 +57,47 @@ function parseArticle(text, date) {
return { slug, title, date, body, excerpt, sourceTitle, sourceUrl, hashtags };
}
// Parse YAML-style frontmatter from TinaCMS markdown files
function parseFrontmatter(text) {
const normalized = text.replace(/\r\n/g, '\n');
if (!normalized.startsWith('---\n')) return { meta: {}, body: normalized };
const endIdx = normalized.indexOf('\n---\n', 4);
if (endIdx === -1) return { meta: {}, body: normalized };
const yamlBlock = normalized.slice(4, endIdx);
const body = normalized.slice(endIdx + 5).trim();
const meta = {};
for (const line of yamlBlock.split('\n')) {
const colonIdx = line.indexOf(':');
if (colonIdx === -1) continue;
const key = line.slice(0, colonIdx).trim();
let val = line.slice(colonIdx + 1).trim();
// Strip surrounding quotes
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
val = val.slice(1, -1);
}
// Parse list values (simple single-line arrays: [a, b, c])
if (val.startsWith('[') && val.endsWith(']')) {
meta[key] = val.slice(1, -1).split(',').map(s => s.trim().replace(/^['"]|['"]$/g, '')).filter(Boolean);
} else {
meta[key] = val;
}
}
return { meta, body };
}
async function dirExists(dirPath) {
try {
const s = await stat(dirPath);
return s.isDirectory();
} catch {
return false;
}
}
async function main() {
// Clear output
await rm(join(OUTPUT_DIR, 'posts'), { recursive: true, force: true });
@ -63,62 +105,120 @@ async function main() {
await mkdir(join(OUTPUT_DIR, 'posts'), { recursive: true });
await mkdir(join(OUTPUT_DIR, 'images'), { recursive: true });
const entries = await readdir(INPUT_DIR, { withFileTypes: true });
const dateDirs = entries
.filter(e => e.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(e.name))
.map(e => e.name)
.sort();
const allPosts = [];
const usedSlugs = new Set();
for (const dateDir of dateDirs) {
const dirPath = join(INPUT_DIR, dateDir);
const files = await readdir(dirPath);
// --- Source 1: LinkedIn autopost output (optional — skipped if path doesn't exist) ---
if (await dirExists(LINKEDIN_INPUT_DIR)) {
const entries = await readdir(LINKEDIN_INPUT_DIR, { withFileTypes: true });
const dateDirs = entries
.filter(e => e.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(e.name))
.map(e => e.name)
.sort();
const articles = files.filter(f => f.startsWith('article_') && f.endsWith('.txt'));
for (const dateDir of dateDirs) {
const dirPath = join(LINKEDIN_INPUT_DIR, dateDir);
const files = await readdir(dirPath);
for (const articleFile of articles) {
const timestamp = articleFile.match(/article_(\d+)\.txt/)?.[1];
if (!timestamp) continue;
const articles = files.filter(f => f.startsWith('article_') && f.endsWith('.txt'));
const coverFile = `cover_${timestamp}.png`;
const hasCover = files.includes(coverFile);
for (const articleFile of articles) {
const timestamp = articleFile.match(/article_(\d+)\.txt/)?.[1];
if (!timestamp) continue;
const text = await readFile(join(dirPath, articleFile), 'utf-8');
const post = parseArticle(text, dateDir);
const coverFile = `cover_${timestamp}.png`;
const hasCover = files.includes(coverFile);
// Skip duplicate slugs (multiple versions of same article)
if (usedSlugs.has(post.slug)) continue;
usedSlugs.add(post.slug);
const text = await readFile(join(dirPath, articleFile), 'utf-8');
const post = parseArticle(text, dateDir);
// Skip duplicate slugs
if (usedSlugs.has(post.slug)) continue;
usedSlugs.add(post.slug);
const fullPost = {
...post,
coverImage: hasCover ? `/blog/images/${post.slug}.png` : '',
};
await writeFile(
join(OUTPUT_DIR, 'posts', `${post.slug}.json`),
JSON.stringify(fullPost, null, 2)
);
if (hasCover) {
await copyFile(
join(dirPath, coverFile),
join(OUTPUT_DIR, 'images', `${post.slug}.png`)
);
}
allPosts.push({
slug: post.slug,
title: post.title,
date: post.date,
excerpt: post.excerpt,
coverImage: fullPost.coverImage,
hashtags: post.hashtags,
});
}
}
console.log(`Synced ${allPosts.length} LinkedIn posts`);
} else {
console.log(`LinkedIn source not found (${LINKEDIN_INPUT_DIR}), skipping`);
}
// --- Source 2: TinaCMS-authored blog posts from content/blog/*.md ---
if (await dirExists(TINA_INPUT_DIR)) {
const mdFiles = (await readdir(TINA_INPUT_DIR)).filter(f => f.endsWith('.md'));
for (const mdFile of mdFiles) {
const text = await readFile(join(TINA_INPUT_DIR, mdFile), 'utf-8');
const { meta, body } = parseFrontmatter(text);
if (!meta.title || !meta.date) continue;
const date = meta.date.slice(0, 10); // ISO date → YYYY-MM-DD
const slug = toSlug(meta.title);
// TinaCMS posts take priority over LinkedIn (override if same slug)
if (usedSlugs.has(slug)) {
// Remove the existing post entry (will be replaced)
const idx = allPosts.findIndex(p => p.slug === slug);
if (idx !== -1) allPosts.splice(idx, 1);
}
usedSlugs.add(slug);
const excerpt = meta.excerpt || makeExcerpt(body.replace(/[#*`>\[\]]/g, ''));
const coverImage = meta.coverImage || '';
const hashtags = Array.isArray(meta.hashtags) ? meta.hashtags : [];
// Write full post JSON
const fullPost = {
...post,
coverImage: hasCover ? `/blog/images/${post.slug}.png` : '',
slug,
title: meta.title,
date,
body,
excerpt,
coverImage,
sourceTitle: meta.sourceTitle || '',
sourceUrl: meta.sourceUrl || '',
hashtags,
};
await writeFile(
join(OUTPUT_DIR, 'posts', `${post.slug}.json`),
join(OUTPUT_DIR, 'posts', `${slug}.json`),
JSON.stringify(fullPost, null, 2)
);
// Copy cover image
if (hasCover) {
await copyFile(
join(dirPath, coverFile),
join(OUTPUT_DIR, 'images', `${post.slug}.png`)
);
}
allPosts.push({
slug: post.slug,
title: post.title,
date: post.date,
excerpt: post.excerpt,
coverImage: fullPost.coverImage,
hashtags: post.hashtags,
slug,
title: meta.title,
date,
excerpt,
coverImage,
hashtags,
});
}
console.log(`Merged ${mdFiles.length} TinaCMS posts from content/blog/`);
}
// Sort newest first
@ -129,7 +229,7 @@ async function main() {
JSON.stringify(allPosts, null, 2)
);
console.log(`Synced ${allPosts.length} blog posts to ${OUTPUT_DIR}`);
console.log(`Total: ${allPosts.length} blog posts written to ${OUTPUT_DIR}`);
}
main().catch(err => {

View file

@ -1,9 +1,27 @@
import { createContext, useContext, useState, useCallback, useMemo, type ReactNode } from 'react';
import type { Lang, TranslationKey, Translations } from './types';
import { en } from './en';
import { uk } from './uk';
import enRaw from '../../content/translations/en.json';
import ukRaw from '../../content/translations/uk.json';
const translations: Record<Lang, Translations> = { en, uk };
function flattenObject(obj: Record<string, unknown>, prefix = ''): Record<string, string> {
return Object.entries(obj).reduce((acc, [key, val]) => {
const fullKey = prefix ? `${prefix}.${key}` : key;
if (key === '_') {
// Special case: _ maps the value to the parent key path
acc[prefix] = String(val);
} else if (typeof val === 'object' && val !== null) {
Object.assign(acc, flattenObject(val as Record<string, unknown>, fullKey));
} else {
acc[fullKey] = String(val);
}
return acc;
}, {} as Record<string, string>);
}
const translations: Record<Lang, Translations> = {
en: flattenObject(enRaw as Record<string, unknown>) as unknown as Translations,
uk: flattenObject(ukRaw as Record<string, unknown>) as unknown as Translations,
};
interface LanguageContextValue {
lang: Lang;

481
tina/config.ts Normal file
View file

@ -0,0 +1,481 @@
import { defineConfig, type TinaField } from "tinacms";
function stringField(name: string, label: string): TinaField {
return { name, label, type: "string" };
}
function textareaField(name: string, label: string): TinaField {
return { name, label, type: "string", ui: { component: "textarea" } };
}
function objectField(name: string, label: string, fields: TinaField[]): TinaField {
return {
name,
label,
type: "object",
ui: { allowedActions: { create: false, delete: false } },
fields,
};
}
// For pricing entries that have both a value (_) and sub-keys (price, split, desc, disc)
function pricingItemField(name: string, label: string, extraFields: TinaField[] = []): TinaField {
return objectField(name, label, [
stringField("_", "Name"),
...extraFields,
]);
}
function translationFields(): TinaField[] {
return [
objectField("header", "Header", [
objectField("nav", "Navigation", [
stringField("home", "Home"),
stringField("about", "About"),
stringField("services", "Services"),
stringField("pricing", "Pricing"),
stringField("blog", "Blog"),
stringField("contacts", "Contacts"),
]),
objectField("lang", "Language Labels", [
stringField("en", "English"),
stringField("uk", "Ukrainian"),
]),
stringField("login", "Login Button"),
objectField("loginModal", "Login Modal", [
stringField("title", "Title"),
stringField("emailLabel", "Email Label"),
stringField("emailPlaceholder", "Email Placeholder"),
stringField("passwordLabel", "Password Label"),
stringField("passwordPlaceholder", "Password Placeholder"),
stringField("submit", "Submit Button"),
stringField("signupPrompt", "Signup Prompt"),
stringField("signupLink", "Signup Link"),
]),
]),
objectField("hero", "Hero Section", [
stringField("circle1", "Rotating Text 1"),
stringField("circle2", "Rotating Text 2"),
stringField("circle3", "Rotating Text 3"),
textareaField("title", "Headline"),
stringField("cta", "CTA Button"),
]),
objectField("benefits", "Benefits Section", [
objectField("card1", "Card 1", [
stringField("front", "Front"),
stringField("subtitle", "Subtitle"),
textareaField("back", "Back"),
]),
objectField("card2", "Card 2", [
stringField("front", "Front"),
stringField("subtitle", "Subtitle"),
textareaField("back", "Back"),
]),
objectField("card3", "Card 3", [
stringField("front", "Front"),
stringField("subtitle", "Subtitle"),
textareaField("back", "Back"),
]),
stringField("builtTitle", "Built Title"),
textareaField("builtDesc", "Built Description"),
objectField("static1", "Static 1", [stringField("title", "Title"), stringField("desc", "Desc")]),
objectField("static2", "Static 2", [stringField("title", "Title"), stringField("desc", "Desc")]),
objectField("static3", "Static 3", [stringField("title", "Title"), stringField("desc", "Desc")]),
objectField("static4", "Static 4", [stringField("title", "Title"), stringField("desc", "Desc")]),
]),
objectField("banner1", "Banner 1 (Quiz)", [
stringField("q1", "Question 1"),
stringField("q2", "Question 2"),
stringField("q3", "Question 3"),
stringField("cta", "CTA Button"),
]),
objectField("realResults", "Real Results Section", [
stringField("title", "Title"),
objectField("card1", "Card 1 — AutoBrat Garage", [
stringField("title", "Title"),
stringField("resultsLabel", "Results Label"),
textareaField("desc", "Description"),
stringField("stat1", "Stat 1"),
stringField("stat2", "Stat 2"),
stringField("stat3", "Stat 3"),
]),
objectField("card2", "Card 2 — Cotswolld Honey", [
stringField("title", "Title"),
textareaField("desc", "Description"),
stringField("stat1", "Stat 1"),
stringField("stat2", "Stat 2"),
]),
objectField("card3", "Card 3 — Wcounting", [
stringField("title", "Title"),
textareaField("desc", "Description"),
stringField("stat1", "Stat 1"),
stringField("stat2", "Stat 2"),
]),
]),
objectField("timeline", "Timeline Section", [
stringField("title", "Title"),
objectField("step1", "Step 1", [stringField("title", "Title"), stringField("duration", "Duration"), textareaField("short", "Short"), textareaField("detail", "Detail")]),
objectField("step2", "Step 2", [stringField("title", "Title"), stringField("duration", "Duration"), textareaField("short", "Short"), textareaField("detail", "Detail")]),
objectField("step3", "Step 3", [stringField("title", "Title"), stringField("duration", "Duration"), textareaField("short", "Short"), textareaField("detail", "Detail")]),
objectField("step4", "Step 4", [stringField("title", "Title"), stringField("duration", "Duration"), textareaField("short", "Short"), textareaField("detail", "Detail")]),
objectField("step5", "Step 5", [stringField("title", "Title"), stringField("duration", "Duration"), textareaField("short", "Short"), textareaField("detail", "Detail")]),
]),
objectField("banner2", "Banner 2", [
stringField("cta", "CTA Button"),
]),
objectField("comparison", "Comparison Table", [
stringField("title", "Title"),
stringField("aiLabel", "AI Label"),
objectField("metric1", "Metric 1 — Cost", [stringField("label", "Label"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("metric2", "Metric 2 — Speed", [stringField("label", "Label"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("metric3", "Metric 3 — Availability", [stringField("label", "Label"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("metric4", "Metric 4 — Scalability", [stringField("label", "Label"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
stringField("altHeading", "Alternatives Heading"),
stringField("alt1", "Alternative 1"),
stringField("alt2", "Alternative 2"),
textareaField("footer", "Footer Text"),
stringField("cta", "CTA Button"),
]),
objectField("blogSection", "Blog Section (Homepage)", [
stringField("title", "Title"),
stringField("readMore", "Read More Link"),
stringField("viewAll", "View All Link"),
]),
objectField("resources", "Resources Section", [
stringField("title", "Title"),
]),
objectField("contactSection", "Contact Section", [
stringField("title", "Title"),
textareaField("subtitle", "Subtitle"),
]),
objectField("contactForm", "Contact Form", [
stringField("title", "Title"),
stringField("fullName", "Full Name Label"),
stringField("fullNamePlaceholder", "Full Name Placeholder"),
stringField("jobTitle", "Job Title Label"),
stringField("jobTitlePlaceholder", "Job Title Placeholder"),
stringField("email", "Email Label"),
stringField("emailPlaceholder", "Email Placeholder"),
stringField("need", "Need Label"),
stringField("needPlaceholder", "Need Placeholder"),
stringField("company", "Company Label"),
stringField("companyPlaceholder", "Company Placeholder"),
stringField("phone", "Phone Label"),
stringField("phonePlaceholder", "Phone Placeholder"),
stringField("submit", "Submit Button"),
stringField("sending", "Sending State"),
stringField("error", "Error Message"),
stringField("successTitle", "Success Title"),
textareaField("successText", "Success Text"),
stringField("sendAnother", "Send Another Button"),
]),
objectField("footer", "Footer", [
stringField("privacy", "Privacy Link"),
stringField("terms", "Terms Link"),
stringField("copyright", "Copyright"),
]),
objectField("cookie", "Cookie Consent", [
textareaField("text", "Cookie Text"),
stringField("privacyLink", "Privacy Link Text"),
stringField("reject", "Reject Button"),
stringField("accept", "Accept Button"),
]),
objectField("chat", "Chat Widget", [
stringField("greeting", "Greeting"),
stringField("openChat", "Open Chat"),
stringField("headerTitle", "Header Title"),
stringField("status", "Status"),
stringField("clearChat", "Clear Chat"),
stringField("closeChat", "Close Chat"),
textareaField("welcome", "Welcome Message"),
objectField("lead", "Lead Form", [
stringField("title", "Title"),
stringField("subtitle", "Subtitle"),
textareaField("intro", "Intro"),
stringField("namePlaceholder", "Name Placeholder"),
stringField("nameError", "Name Error"),
stringField("emailPlaceholder", "Email Placeholder"),
stringField("emailError", "Email Error"),
stringField("emailInvalid", "Email Invalid"),
stringField("companyPlaceholder", "Company Placeholder"),
textareaField("consent", "Consent Text"),
stringField("privacyLink", "Privacy Link Text"),
stringField("consentError", "Consent Error"),
stringField("submit", "Submit Button"),
]),
stringField("inputPlaceholder", "Input Placeholder"),
stringField("send", "Send Button"),
]),
objectField("quoteForm", "Quote Form", [
stringField("title", "Title"),
stringField("fullName", "Full Name Label"),
stringField("fullNamePlaceholder", "Full Name Placeholder"),
stringField("jobTitle", "Job Title Label"),
stringField("jobTitlePlaceholder", "Job Title Placeholder"),
stringField("email", "Email Label"),
stringField("emailPlaceholder", "Email Placeholder"),
stringField("phone", "Phone Label"),
stringField("phonePlaceholder", "Phone Placeholder"),
stringField("company", "Company Label"),
stringField("companyPlaceholder", "Company Placeholder"),
stringField("service", "Service Label"),
stringField("serviceDefault", "Service Default"),
stringField("service1", "Service 1"),
stringField("service2", "Service 2"),
stringField("service3", "Service 3"),
stringField("service4", "Service 4"),
stringField("service5", "Service 5"),
stringField("service6", "Service 6"),
stringField("service7", "Service 7"),
stringField("service8", "Service 8"),
stringField("service9", "Service 9"),
stringField("description", "Description Label"),
textareaField("descriptionPlaceholder", "Description Placeholder"),
stringField("submit", "Submit Button"),
stringField("sending", "Sending State"),
stringField("error", "Error Message"),
stringField("successTitle", "Success Title"),
textareaField("successText", "Success Text"),
stringField("sendAnother", "Send Another Button"),
]),
objectField("about", "About Page", [
objectField("hero", "Hero", [stringField("title", "Title"), textareaField("subtitle", "Subtitle")]),
objectField("story", "Our Story", [
stringField("title", "Title"),
textareaField("p1", "Paragraph 1"),
textareaField("p2", "Paragraph 2"),
textareaField("p3", "Paragraph 3"),
]),
objectField("diff", "What Makes Us Different", [stringField("title", "Title")]),
objectField("diff1", "Differentiator 1", [stringField("title", "Title"), textareaField("desc", "Description")]),
objectField("diff2", "Differentiator 2", [stringField("title", "Title"), textareaField("desc", "Description")]),
objectField("diff3", "Differentiator 3", [stringField("title", "Title"), textareaField("desc", "Description")]),
objectField("diff4", "Differentiator 4", [stringField("title", "Title"), textareaField("desc", "Description")]),
objectField("values", "Values", [stringField("title", "Title")]),
objectField("val1", "Value 1", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("val2", "Value 2", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("val3", "Value 3", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("val4", "Value 4", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("val5", "Value 5", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("founder", "Founder", [
stringField("title", "Section Title"),
stringField("name", "Name"),
stringField("role", "Role"),
stringField("bgLabel", "Background Label"),
textareaField("bgText", "Background Text"),
stringField("certLabel", "Certifications Label"),
textareaField("certText", "Certifications Text"),
stringField("analyticsLabel", "Analytics Label"),
textareaField("analyticsText", "Analytics Text"),
stringField("eduLabel", "Education Label"),
textareaField("eduText", "Education Text"),
stringField("visionLabel", "Vision Label"),
textareaField("visionText", "Vision Text"),
]),
objectField("industries", "Industries", [stringField("title", "Title")]),
objectField("ind1", "Industry 1", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind2", "Industry 2", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind3", "Industry 3", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind4", "Industry 4", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind5", "Industry 5", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind6", "Industry 6", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("ind7", "Industry 7", [stringField("name", "Name"), stringField("desc", "Description")]),
objectField("cta", "CTA", [stringField("title", "Title"), textareaField("subtitle", "Subtitle"), stringField("button", "Button")]),
]),
objectField("services", "Services Page", [
objectField("hero", "Hero", [stringField("title", "Title"), textareaField("subtitle", "Subtitle")]),
objectField("s1", "Service 1 — AI Chatbots", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5"), stringField("f6", "F6")]),
objectField("s2", "Service 2 — Website Dev", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5"), stringField("f6", "F6")]),
objectField("s3", "Service 3 — Workflow Automation", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
objectField("s4", "Service 4 — System Integration", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
objectField("s5", "Service 5 — CRM", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
objectField("s6", "Service 6 — Marketing Automation", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
objectField("s7", "Service 7 — AI Integration", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
objectField("s8", "Service 8 — Infrastructure", [stringField("title", "Title"), stringField("price", "Price"), textareaField("purpose", "Purpose"), stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5")]),
stringField("popular", "Popular Badge"),
stringField("whatsIncluded", "What's Included"),
stringField("showLess", "Show Less"),
objectField("assurance", "Assurance Pack", [
stringField("title", "Title"),
stringField("subtitle", "Subtitle"),
stringField("i1", "Item 1"), stringField("i2", "Item 2"), stringField("i3", "Item 3"),
stringField("i4", "Item 4"), stringField("i5", "Item 5"), stringField("i6", "Item 6"),
stringField("i7", "Item 7"), stringField("i8", "Item 8"), stringField("i9", "Item 9"),
]),
objectField("metrics", "Metrics", [
stringField("title", "Title"),
stringField("v1", "Value 1"), stringField("l1", "Label 1"),
stringField("v2", "Value 2"), stringField("l2", "Label 2"),
stringField("v3", "Value 3"), stringField("l3", "Label 3"),
stringField("v4", "Value 4"), stringField("l4", "Label 4"),
]),
objectField("selector", "Service Selector", [
stringField("title", "Title"),
stringField("step1", "Step 1"), stringField("step2", "Step 2"), stringField("step3", "Step 3"),
stringField("goalQ", "Goal Question"),
stringField("goal1", "Goal 1"), stringField("goal2", "Goal 2"), stringField("goal3", "Goal 3"),
stringField("goal4", "Goal 4"), stringField("goal5", "Goal 5"),
stringField("budgetQ", "Budget Question"),
stringField("budget1", "Budget 1"), stringField("budget2", "Budget 2"), stringField("budget3", "Budget 3"),
stringField("resultsHeading", "Results Heading"),
textareaField("noMatch", "No Match"),
stringField("viewButton", "View Button"), stringField("resetButton", "Reset Button"), stringField("backButton", "Back Button"),
]),
objectField("bundles", "Bundles", [stringField("title", "Title")]),
objectField("bundle1", "Bundle 1 — Starter", [stringField("name", "Name"), stringField("tagline", "Tagline"), stringField("price", "Price")]),
objectField("bundle2", "Bundle 2 — Growth", [stringField("name", "Name"), stringField("tagline", "Tagline"), stringField("price", "Price"), stringField("badge", "Badge")]),
objectField("bundle3", "Bundle 3 — Full Stack", [stringField("name", "Name"), stringField("tagline", "Tagline"), stringField("price", "Price")]),
objectField("bundle", "Bundle CTA", [stringField("cta", "CTA Button")]),
objectField("cta", "Bottom CTA", [stringField("title", "Title"), textareaField("subtitle", "Subtitle"), stringField("button", "Button")]),
]),
objectField("pricing", "Pricing Page", [
objectField("hero", "Hero", [stringField("title", "Title"), textareaField("subtitle", "Subtitle")]),
objectField("impl", "Implementation Pricing", [
stringField("title", "Section Title"),
pricingItemField("s1", "Service 1", [stringField("price", "Price")]),
pricingItemField("s2", "Service 2", [stringField("price", "Price")]),
pricingItemField("s3", "Service 3", [stringField("price", "Price")]),
pricingItemField("s4", "Service 4", [stringField("price", "Price")]),
pricingItemField("s5", "Service 5", [stringField("price", "Price")]),
pricingItemField("s6", "Service 6", [stringField("price", "Price")]),
pricingItemField("s7", "Service 7", [stringField("price", "Price")]),
pricingItemField("s8", "Service 8", [stringField("price", "Price")]),
]),
stringField("popular", "Popular Badge"),
objectField("retainers", "Retainers", [stringField("title", "Title")]),
objectField("ret1", "Retainer — Essential", [
stringField("name", "Name"), stringField("price", "Price"), stringField("period", "Period"),
stringField("hours", "Hours"), stringField("sla", "SLA"),
stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5"),
]),
objectField("ret2", "Retainer — Professional", [
stringField("name", "Name"), stringField("price", "Price"), stringField("hours", "Hours"), stringField("sla", "SLA"), stringField("badge", "Badge"),
stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5"), stringField("f6", "F6"),
]),
objectField("ret3", "Retainer — Enterprise", [
stringField("name", "Name"), stringField("price", "Price"), stringField("hours", "Hours"), stringField("sla", "SLA"),
stringField("f1", "F1"), stringField("f2", "F2"), stringField("f3", "F3"), stringField("f4", "F4"), stringField("f5", "F5"), stringField("f6", "F6"), stringField("f7", "F7"),
]),
objectField("training", "Training & Workshops", [
stringField("title", "Title"),
pricingItemField("t1", "Training 1", [stringField("price", "Price"), stringField("desc", "Desc")]),
pricingItemField("t2", "Training 2", [stringField("price", "Price")]),
pricingItemField("t3", "Training 3", [stringField("price", "Price"), stringField("desc", "Desc")]),
pricingItemField("t4", "Training 4", [stringField("price", "Price"), stringField("desc", "Desc")]),
]),
objectField("payment", "Payment Terms", [
stringField("title", "Title"),
pricingItemField("r1", "Range 1", [stringField("split", "Split")]),
pricingItemField("r2", "Range 2", [stringField("split", "Split")]),
pricingItemField("r3", "Range 3", [stringField("split", "Split")]),
pricingItemField("r4", "Range 4 (Public Sector)", [stringField("split", "Split")]),
]),
objectField("discounts", "Discounts / Impact Grant", [
stringField("title", "Title"),
textareaField("intro", "Intro"),
pricingItemField("g1", "Group 1", [stringField("disc", "Discount")]),
stringField("g2", "Group 2"),
stringField("g3", "Group 3"),
pricingItemField("g4", "Group 4", [stringField("disc", "Discount")]),
stringField("g5", "Group 5"),
]),
objectField("compare", "Comparison Table", [
stringField("title", "Title"),
stringField("aimpress", "AImpress Label"), stringField("agency", "Agency Label"), stringField("inhouse", "In-House Label"),
objectField("r1", "Row 1", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("r2", "Row 2", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("r3", "Row 3", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("r4", "Row 4", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
objectField("r5", "Row 5", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency")]),
objectField("r6", "Row 6", [stringField("metric", "Metric"), stringField("ai", "AI"), stringField("agency", "Agency"), stringField("inhouse", "In-House")]),
]),
objectField("faq", "FAQ", [
stringField("title", "Title"),
stringField("q1", "Q1"), textareaField("a1", "A1"),
stringField("q2", "Q2"), textareaField("a2", "A2"),
stringField("q3", "Q3"), textareaField("a3", "A3"),
stringField("q4", "Q4"), textareaField("a4", "A4"),
stringField("q5", "Q5"), textareaField("a5", "A5"),
stringField("q6", "Q6"), textareaField("a6", "A6"),
]),
objectField("cta", "Bottom CTA", [stringField("title", "Title"), textareaField("subtitle", "Subtitle")]),
]),
objectField("blog", "Blog Page", [
stringField("title", "Title"),
stringField("loading", "Loading"),
stringField("noPosts", "No Posts"),
stringField("readMore", "Read More"),
]),
objectField("blogPost", "Blog Post Page", [
stringField("back", "Back Link"),
stringField("notFound", "Not Found"),
stringField("loading", "Loading"),
stringField("source", "Source Label"),
]),
objectField("seo", "SEO Meta Tags", [
objectField("home", "Home Page", [stringField("title", "Title"), textareaField("description", "Description")]),
objectField("about", "About Page", [stringField("title", "Title"), textareaField("description", "Description")]),
objectField("services", "Services Page", [stringField("title", "Title"), textareaField("description", "Description")]),
objectField("pricing", "Pricing Page", [stringField("title", "Title"), textareaField("description", "Description")]),
objectField("blog", "Blog Page", [stringField("title", "Title"), textareaField("description", "Description")]),
stringField("siteName", "Site Name"),
]),
];
}
export default defineConfig({
branch: process.env.GITHUB_REF_NAME ?? "main",
clientId: process.env.TINA_PUBLIC_CLIENT_ID!,
token: process.env.TINA_TOKEN!,
build: {
outputFolder: "admin",
publicFolder: "public",
},
media: {
tina: {
mediaRoot: "uploads",
publicFolder: "public",
},
},
schema: {
collections: [
{
name: "translationsEn",
label: "Site Content (English)",
path: "content/translations",
match: { include: "en" },
format: "json",
ui: { allowedActions: { create: false, delete: false } },
fields: translationFields(),
},
{
name: "translationsUk",
label: "Site Content (Ukrainian)",
path: "content/translations",
match: { include: "uk" },
format: "json",
ui: { allowedActions: { create: false, delete: false } },
fields: translationFields(),
},
{
name: "blogPost",
label: "Blog Posts",
path: "content/blog",
format: "md",
fields: [
{ name: "title", type: "string", label: "Title", required: true, isTitle: true },
{ name: "date", type: "datetime", label: "Date", required: true },
{ name: "excerpt", type: "string", label: "Excerpt", ui: { component: "textarea" } },
{ name: "coverImage", type: "image", label: "Cover Image" },
{ name: "hashtags", type: "string", label: "Tags", list: true },
{ name: "sourceTitle", type: "string", label: "Source Name" },
{ name: "sourceUrl", type: "string", label: "Source URL" },
{ name: "body", type: "rich-text", label: "Body", isBody: true },
],
},
],
},
});

View file

@ -22,7 +22,8 @@
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
"noUncheckedSideEffectImports": true,
"resolveJsonModule": true
},
"include": ["src"]
}