Skip to content

Latest commit

 

History

History
1018 lines (898 loc) · 28.4 KB

File metadata and controls

1018 lines (898 loc) · 28.4 KB

Securiace Technologies - Implementation Guides

🚀 Quick Start Implementation

Phase 1: Foundation Setup (Week 1)

  1. Project Initialization

    • Initialize Next.js 14 with TypeScript
    • Configure TailwindCSS and ShadCN UI
    • Set up ESLint, Prettier, and Husky
    • Configure environment variables
  2. Core Infrastructure

    • Create base layout components
    • Set up routing structure
    • Configure analytics and tracking
    • Implement security headers
  3. Design System

    • Set up color palette and typography
    • Create base UI components
    • Implement responsive breakpoints
    • Configure animation system

Phase 2: Core Pages (Week 2-3)

  1. Homepage Implementation

    • Hero section with domain search
    • Services overview
    • Trust signals and testimonials
    • Call-to-action sections
  2. Services Pages

    • Individual service pages
    • Pricing integration
    • FAQ sections
    • Contact forms
  3. Supporting Pages

    • About page
    • Contact page
    • Legal pages
    • Blog structure

Phase 3: Advanced Features (Week 4-5)

  1. Integrations

    • WHMCS integration
    • CRM and email automation
    • Analytics implementation
    • Live chat integration
  2. Performance Optimization

    • Image optimization
    • Code splitting
    • Caching strategies
    • Core Web Vitals optimization
  3. SEO Implementation

    • Meta tag generation
    • Schema markup
    • Sitemap generation
    • Content optimization

🏗️ Component Implementation Guide

1. Layout Components

Header Component

// src/components/layout/header.tsx
import { useState } from 'react';
import { Menu, X, Shield, Server } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { MobileMenu } from './mobile-menu';

interface HeaderProps {
  className?: string;
}

export function Header({ className }: HeaderProps) {
  const [isMenuOpen, setIsMenuOpen] = useState(false);

  return (
    <header className={`sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 ${className}`}>
      <div className="container flex h-16 items-center justify-between">
        {/* Logo */}
        <div className="flex items-center space-x-2">
          <Shield className="h-8 w-8 text-primary" />
          <span className="text-xl font-bold">Securiace</span>
        </div>

        {/* Desktop Navigation */}
        <nav className="hidden md:flex items-center space-x-6">
          <a href="/services" className="text-sm font-medium hover:text-primary transition-colors">
            Services
          </a>
          <a href="/pricing" className="text-sm font-medium hover:text-primary transition-colors">
            Pricing
          </a>
          <a href="/about" className="text-sm font-medium hover:text-primary transition-colors">
            About
          </a>
          <a href="/blog" className="text-sm font-medium hover:text-primary transition-colors">
            Blog
          </a>
          <a href="/support" className="text-sm font-medium hover:text-primary transition-colors">
            Support
          </a>
        </nav>

        {/* CTA Buttons */}
        <div className="hidden md:flex items-center space-x-4">
          <Button variant="ghost" size="sm">
            Sign In
          </Button>
          <Button size="sm">
            Get Started
          </Button>
        </div>

        {/* Mobile Menu Button */}
        <Button
          variant="ghost"
          size="sm"
          className="md:hidden"
          onClick={() => setIsMenuOpen(!isMenuOpen)}
        >
          {isMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
        </Button>
      </div>

      {/* Mobile Menu */}
      {isMenuOpen && <MobileMenu onClose={() => setIsMenuOpen(false)} />}
    </header>
  );
}

Footer Component

// src/components/layout/footer.tsx
import { Shield, Mail, Phone, MapPin } from 'lucide-react';
import { Button } from '@/components/ui/button';

export function Footer() {
  return (
    <footer className="bg-gray-900 text-white">
      <div className="container py-12">
        <div className="grid grid-cols-1 md:grid-cols-4 gap-8">
          {/* Company Info */}
          <div className="space-y-4">
            <div className="flex items-center space-x-2">
              <Shield className="h-8 w-8 text-primary" />
              <span className="text-xl font-bold">Securiace</span>
            </div>
            <p className="text-gray-300 text-sm">
              Secure, Reliable, Managed Hosting & IT Solutions for businesses worldwide.
            </p>
            <div className="flex space-x-4">
              {/* Social Media Links */}
            </div>
          </div>

          {/* Services */}
          <div>
            <h3 className="font-semibold mb-4">Services</h3>
            <ul className="space-y-2 text-sm text-gray-300">
              <li><a href="/services/shared-hosting" className="hover:text-white transition-colors">Shared Hosting</a></li>
              <li><a href="/services/cloud-hosting" className="hover:text-white transition-colors">Cloud Hosting</a></li>
              <li><a href="/services/managed-vps" className="hover:text-white transition-colors">Managed VPS</a></li>
              <li><a href="/services/cybersecurity" className="hover:text-white transition-colors">Cybersecurity</a></li>
            </ul>
          </div>

          {/* Support */}
          <div>
            <h3 className="font-semibold mb-4">Support</h3>
            <ul className="space-y-2 text-sm text-gray-300">
              <li><a href="/support" className="hover:text-white transition-colors">Help Center</a></li>
              <li><a href="/support/contact" className="hover:text-white transition-colors">Contact Us</a></li>
              <li><a href="/trust/status" className="hover:text-white transition-colors">Status Page</a></li>
              <li><a href="/blog" className="hover:text-white transition-colors">Blog</a></li>
            </ul>
          </div>

          {/* Contact */}
          <div>
            <h3 className="font-semibold mb-4">Contact</h3>
            <div className="space-y-2 text-sm text-gray-300">
              <div className="flex items-center space-x-2">
                <Mail className="h-4 w-4" />
                <span>support@securiace.com</span>
              </div>
              <div className="flex items-center space-x-2">
                <Phone className="h-4 w-4" />
                <span>+91-XXXXXXXXXX</span>
              </div>
              <div className="flex items-center space-x-2">
                <MapPin className="h-4 w-4" />
                <span>Mumbai, India</span>
              </div>
            </div>
          </div>
        </div>

        <div className="border-t border-gray-800 mt-8 pt-8 flex flex-col md:flex-row justify-between items-center">
          <p className="text-sm text-gray-400">
            © 2024 Securiace Technologies. All rights reserved.
          </p>
          <div className="flex space-x-6 mt-4 md:mt-0">
            <a href="/legal/privacy-policy" className="text-sm text-gray-400 hover:text-white transition-colors">
              Privacy Policy
            </a>
            <a href="/legal/terms-of-service" className="text-sm text-gray-400 hover:text-white transition-colors">
              Terms of Service
            </a>
          </div>
        </div>
      </div>
    </footer>
  );
}

2. Hero Section Implementation

Hero Section Component

// src/components/sections/hero/hero-section.tsx
import { motion } from 'framer-motion';
import { Button } from '@/components/ui/button';
import { DomainSearch } from './domain-search';
import { TrustSignals } from './trust-signals';
import { CounterAnimation } from '@/components/animations/counter-animation';

const fadeInUp = {
  initial: { opacity: 0, y: 60 },
  animate: { opacity: 1, y: 0 },
  transition: { duration: 0.6, ease: "easeOut" }
};

const staggerContainer = {
  animate: {
    transition: {
      staggerChildren: 0.1
    }
  }
};

export function HeroSection() {
  return (
    <section className="relative min-h-screen flex items-center justify-center bg-gradient-to-br from-primary-50 to-secondary-50">
      <div className="container px-4 py-20">
        <motion.div
          variants={staggerContainer}
          initial="initial"
          animate="animate"
          className="text-center max-w-4xl mx-auto"
        >
          {/* Main Headline */}
          <motion.h1
            variants={fadeInUp}
            className="text-4xl md:text-6xl font-bold text-gray-900 mb-6"
          >
            Secure, Reliable, Managed
            <span className="text-primary block">Hosting & IT Solutions</span>
          </motion.h1>

          {/* Subheadline */}
          <motion.p
            variants={fadeInUp}
            className="text-xl text-gray-600 mb-8 max-w-2xl mx-auto"
          >
            Enterprise-grade hosting with 99.9% uptime guarantee, advanced security,
            and 24/7 expert support. Trusted by businesses worldwide.
          </motion.p>

          {/* Domain Search */}
          <motion.div variants={fadeInUp} className="mb-8">
            <DomainSearch />
          </motion.div>

          {/* CTA Buttons */}
          <motion.div
            variants={fadeInUp}
            className="flex flex-col sm:flex-row gap-4 justify-center mb-12"
          >
            <Button size="lg" className="text-lg px-8 py-6">
              Start Hosting Now
            </Button>
            <Button variant="outline" size="lg" className="text-lg px-8 py-6">
              Get Free SSL
            </Button>
          </motion.div>

          {/* Trust Signals */}
          <motion.div variants={fadeInUp}>
            <TrustSignals />
          </motion.div>

          {/* Animated Counters */}
          <motion.div
            variants={fadeInUp}
            className="grid grid-cols-1 md:grid-cols-3 gap-8 mt-16"
          >
            <div className="text-center">
              <CounterAnimation
                end={99.9}
                duration={2000}
                suffix="%"
                className="text-4xl font-bold text-primary"
              />
              <p className="text-gray-600 mt-2">Uptime Guarantee</p>
            </div>
            <div className="text-center">
              <CounterAnimation
                end={10000}
                duration={2000}
                suffix="+"
                className="text-4xl font-bold text-primary"
              />
              <p className="text-gray-600 mt-2">Happy Clients</p>
            </div>
            <div className="text-center">
              <CounterAnimation
                end={5}
                duration={2000}
                suffix="+"
                className="text-4xl font-bold text-primary"
              />
              <p className="text-gray-600 mt-2">Years Experience</p>
            </div>
          </motion.div>
        </motion.div>
      </div>
    </section>
  );
}

3. Services Section Implementation

Service Card Component

// src/components/sections/services/service-card.tsx
import { motion } from 'framer-motion';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Check, ArrowRight } from 'lucide-react';

interface ServiceCardProps {
  service: {
    id: string;
    name: string;
    description: string;
    features: string[];
    price: {
      monthly: number;
      annually: number;
    };
    popular?: boolean;
    cta: string;
  };
  index: number;
}

const cardVariants = {
  initial: { opacity: 0, y: 60 },
  animate: { opacity: 1, y: 0 },
  hover: { y: -8, transition: { duration: 0.2 } }
};

export function ServiceCard({ service, index }: ServiceCardProps) {
  return (
    <motion.div
      variants={cardVariants}
      initial="initial"
      whileInView="animate"
      whileHover="hover"
      viewport={{ once: true, margin: "-100px" }}
      transition={{ delay: index * 0.1 }}
    >
      <Card className={`relative h-full ${service.popular ? 'border-primary shadow-lg' : ''}`}>
        {service.popular && (
          <Badge className="absolute -top-3 left-1/2 transform -translate-x-1/2 bg-primary text-white">
            Most Popular
          </Badge>
        )}

        <CardHeader className="text-center pb-4">
          <CardTitle className="text-2xl font-bold">{service.name}</CardTitle>
          <CardDescription className="text-gray-600 mt-2">
            {service.description}
          </CardDescription>
        </CardHeader>

        <CardContent className="space-y-6">
          {/* Pricing */}
          <div className="text-center">
            <div className="text-4xl font-bold text-primary">
              {service.price.monthly}
              <span className="text-lg text-gray-500">/month</span>
            </div>
            <p className="text-sm text-gray-500 mt-1">
              Billed annually ({service.price.annually}/year)
            </p>
          </div>

          {/* Features */}
          <ul className="space-y-3">
            {service.features.map((feature, featureIndex) => (
              <li key={featureIndex} className="flex items-center space-x-3">
                <Check className="h-5 w-5 text-green-500 flex-shrink-0" />
                <span className="text-gray-700">{feature}</span>
              </li>
            ))}
          </ul>

          {/* CTA Button */}
          <Button
            className={`w-full ${service.popular ? 'bg-primary hover:bg-primary/90' : ''}`}
            variant={service.popular ? 'default' : 'outline'}
          >
            {service.cta}
            <ArrowRight className="ml-2 h-4 w-4" />
          </Button>
        </CardContent>
      </Card>
    </motion.div>
  );
}

4. Form Implementation

Contact Form Component

// src/components/forms/contact-form.tsx
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { toast } from '@/components/ui/use-toast';
import { Loader2, Send, CheckCircle } from 'lucide-react';

const contactSchema = z.object({
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  phone: z.string().optional(),
  company: z.string().optional(),
  service: z.string().min(1, 'Please select a service'),
  message: z.string().min(10, 'Message must be at least 10 characters'),
});

type ContactFormData = z.infer<typeof contactSchema>;

const services = [
  'Shared Hosting',
  'Cloud Hosting',
  'Managed VPS',
  'Dedicated Servers',
  'Cybersecurity',
  'MSP Services',
  'Other'
];

export function ContactForm() {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);

  const form = useForm<ContactFormData>({
    resolver: zodResolver(contactSchema),
    defaultValues: {
      name: '',
      email: '',
      phone: '',
      company: '',
      service: '',
      message: '',
    },
  });

  const onSubmit = async (data: ContactFormData) => {
    setIsSubmitting(true);

    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });

      if (response.ok) {
        setIsSubmitted(true);
        toast({
          title: "Message sent successfully!",
          description: "We'll get back to you within 24 hours.",
        });
        form.reset();
      } else {
        throw new Error('Failed to send message');
      }
    } catch (error) {
      toast({
        title: "Error",
        description: "Failed to send message. Please try again.",
        variant: "destructive",
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  if (isSubmitted) {
    return (
      <Card className="max-w-md mx-auto">
        <CardContent className="pt-6 text-center">
          <CheckCircle className="h-16 w-16 text-green-500 mx-auto mb-4" />
          <h3 className="text-xl font-semibold mb-2">Thank You!</h3>
          <p className="text-gray-600">
            Your message has been sent successfully. We'll get back to you within 24 hours.
          </p>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className="max-w-2xl mx-auto">
      <CardHeader>
        <CardTitle>Get in Touch</CardTitle>
        <CardDescription>
          Ready to secure your business? Send us a message and we'll get back to you.
        </CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label htmlFor="name" className="block text-sm font-medium mb-2">
                Name *
              </label>
              <Input
                id="name"
                {...form.register('name')}
                placeholder="Your full name"
                className={form.formState.errors.name ? 'border-red-500' : ''}
              />
              {form.formState.errors.name && (
                <p className="text-red-500 text-sm mt-1">
                  {form.formState.errors.name.message}
                </p>
              )}
            </div>

            <div>
              <label htmlFor="email" className="block text-sm font-medium mb-2">
                Email *
              </label>
              <Input
                id="email"
                type="email"
                {...form.register('email')}
                placeholder="your@email.com"
                className={form.formState.errors.email ? 'border-red-500' : ''}
              />
              {form.formState.errors.email && (
                <p className="text-red-500 text-sm mt-1">
                  {form.formState.errors.email.message}
                </p>
              )}
            </div>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label htmlFor="phone" className="block text-sm font-medium mb-2">
                Phone
              </label>
              <Input
                id="phone"
                {...form.register('phone')}
                placeholder="+91-XXXXXXXXXX"
              />
            </div>

            <div>
              <label htmlFor="company" className="block text-sm font-medium mb-2">
                Company
              </label>
              <Input
                id="company"
                {...form.register('company')}
                placeholder="Your company name"
              />
            </div>
          </div>

          <div>
            <label htmlFor="service" className="block text-sm font-medium mb-2">
              Service Interest *
            </label>
            <select
              id="service"
              {...form.register('service')}
              className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
            >
              <option value="">Select a service</option>
              {services.map((service) => (
                <option key={service} value={service}>
                  {service}
                </option>
              ))}
            </select>
            {form.formState.errors.service && (
              <p className="text-red-500 text-sm mt-1">
                {form.formState.errors.service.message}
              </p>
            )}
          </div>

          <div>
            <label htmlFor="message" className="block text-sm font-medium mb-2">
              Message *
            </label>
            <Textarea
              id="message"
              {...form.register('message')}
              placeholder="Tell us about your requirements..."
              rows={4}
              className={form.formState.errors.message ? 'border-red-500' : ''}
            />
            {form.formState.errors.message && (
              <p className="text-red-500 text-sm mt-1">
                {form.formState.errors.message.message}
              </p>
            )}
          </div>

          <Button
            type="submit"
            disabled={isSubmitting}
            className="w-full"
          >
            {isSubmitting ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                Sending...
              </>
            ) : (
              <>
                <Send className="mr-2 h-4 w-4" />
                Send Message
              </>
            )}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}

5. API Route Implementation

Contact API Route

// src/app/api/contact/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { sendEmail } from '@/lib/email';
import { createContact } from '@/lib/twenty-crm';
import { subscribeToListmonk } from '@/lib/listmonk';

const contactSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
  phone: z.string().optional(),
  company: z.string().optional(),
  service: z.string().min(1),
  message: z.string().min(10),
});

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const validatedData = contactSchema.parse(body);

    // Send email notification
    await sendEmail({
      to: 'support@securiace.com',
      subject: `New Contact Form Submission from ${validatedData.name}`,
      template: 'contact-notification',
      data: validatedData,
    });

    // Create contact in CRM
    await createContact({
      name: validatedData.name,
      email: validatedData.email,
      phone: validatedData.phone,
      company: validatedData.company,
      message: validatedData.message,
      source: 'website',
      tags: [
        'contact-form',
        validatedData.service.toLowerCase().replace(' ', '-'),
      ],
    });

    // Subscribe to email list
    await subscribeToListmonk({
      email: validatedData.email,
      name: validatedData.name,
      lists: [1], // General newsletter list
      attributes: {
        company: validatedData.company,
        phone: validatedData.phone,
        service_interest: validatedData.service,
        source: 'contact-form',
      },
    });

    return NextResponse.json(
      { message: 'Contact form submitted successfully' },
      { status: 200 }
    );
  } catch (error) {
    console.error('Contact form error:', error);

    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Invalid form data', details: error.errors },
        { status: 400 }
      );
    }

    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}

🎨 Animation Implementation

Framer Motion Variants

// src/lib/animations.ts
export const fadeInUp = {
  initial: { opacity: 0, y: 60 },
  animate: { opacity: 1, y: 0 },
  transition: { duration: 0.6, ease: 'easeOut' },
};

export const fadeInLeft = {
  initial: { opacity: 0, x: -60 },
  animate: { opacity: 1, x: 0 },
  transition: { duration: 0.6, ease: 'easeOut' },
};

export const fadeInRight = {
  initial: { opacity: 0, x: 60 },
  animate: { opacity: 1, x: 0 },
  transition: { duration: 0.6, ease: 'easeOut' },
};

export const scaleIn = {
  initial: { scale: 0.8, opacity: 0 },
  animate: { scale: 1, opacity: 1 },
  transition: { duration: 0.4, ease: 'easeOut' },
};

export const staggerContainer = {
  animate: {
    transition: {
      staggerChildren: 0.1,
    },
  },
};

export const slideInFromBottom = {
  initial: { opacity: 0, y: 100 },
  whileInView: { opacity: 1, y: 0 },
  transition: { duration: 0.8, ease: 'easeOut' },
  viewport: { once: true, margin: '-100px' },
};

Counter Animation Component

// src/components/animations/counter-animation.tsx
import { useEffect, useState } from 'react';
import { motion, useInView } from 'framer-motion';
import { useRef } from 'react';

interface CounterAnimationProps {
  end: number;
  duration?: number;
  suffix?: string;
  prefix?: string;
  className?: string;
}

export function CounterAnimation({
  end,
  duration = 2000,
  suffix = '',
  prefix = '',
  className
}: CounterAnimationProps) {
  const [count, setCount] = useState(0);
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true });

  useEffect(() => {
    if (!isInView) return;

    let startTime: number;
    const startCount = 0;

    const animate = (currentTime: number) => {
      if (!startTime) startTime = currentTime;
      const progress = Math.min((currentTime - startTime) / duration, 1);

      const easeOutQuart = 1 - Math.pow(1 - progress, 4);
      const currentCount = Math.floor(easeOutQuart * (end - startCount) + startCount);

      setCount(currentCount);

      if (progress < 1) {
        requestAnimationFrame(animate);
      }
    };

    requestAnimationFrame(animate);
  }, [end, duration, isInView]);

  return (
    <motion.span
      ref={ref}
      className={className}
      initial={{ opacity: 0 }}
      animate={{ opacity: isInView ? 1 : 0 }}
    >
      {prefix}{count}{suffix}
    </motion.span>
  );
}

🔧 Utility Functions

SEO Utilities

// src/lib/seo.ts
import { Metadata } from 'next';

interface SEOProps {
  title: string;
  description: string;
  keywords?: string[];
  canonical?: string;
  ogImage?: string;
  noIndex?: boolean;
}

export function generateMetadata({
  title,
  description,
  keywords = [],
  canonical,
  ogImage = '/images/og-default.jpg',
  noIndex = false,
}: SEOProps): Metadata {
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://securiace.com';
  const fullTitle = `${title} | Securiace Technologies`;
  const canonicalUrl = canonical ? `${siteUrl}${canonical}` : undefined;

  return {
    title: fullTitle,
    description,
    keywords: keywords.join(', '),
    canonical: canonicalUrl,
    robots: {
      index: !noIndex,
      follow: !noIndex,
      googleBot: {
        index: !noIndex,
        follow: !noIndex,
        'max-video-preview': -1,
        'max-image-preview': 'large',
        'max-snippet': -1,
      },
    },
    openGraph: {
      title: fullTitle,
      description,
      url: canonicalUrl,
      siteName: 'Securiace Technologies',
      images: [
        {
          url: ogImage,
          width: 1200,
          height: 630,
          alt: title,
        },
      ],
      locale: 'en_US',
      type: 'website',
    },
    twitter: {
      card: 'summary_large_image',
      title: fullTitle,
      description,
      images: [ogImage],
    },
  };
}

export function generateSchemaMarkup(
  type: 'organization' | 'product' | 'service',
  data: any
) {
  const baseSchema = {
    '@context': 'https://schema.org',
    '@type': type,
    ...data,
  };

  return {
    __html: JSON.stringify(baseSchema),
  };
}

Analytics Utilities

// src/lib/analytics.ts
declare global {
  interface Window {
    gtag: (...args: any[]) => void;
    plausible: (...args: any[]) => void;
  }
}

export function trackEvent(
  eventName: string,
  properties?: Record<string, any>
) {
  if (typeof window === 'undefined') return;

  // Google Analytics 4
  if (window.gtag) {
    window.gtag('event', eventName, {
      event_category: properties?.category || 'engagement',
      event_label: properties?.label,
      value: properties?.value,
      ...properties,
    });
  }

  // Plausible Analytics
  if (window.plausible) {
    window.plausible(eventName, {
      props: properties,
    });
  }
}

export function trackPageView(url: string, title: string) {
  if (typeof window === 'undefined') return;

  // Google Analytics 4
  if (window.gtag) {
    window.gtag('config', process.env.NEXT_PUBLIC_GA_ID, {
      page_title: title,
      page_location: url,
    });
  }

  // Plausible Analytics
  if (window.plausible) {
    window.plausible('pageview', {
      u: url,
    });
  }
}

export function trackConversion(conversionType: string, value?: number) {
  trackEvent('conversion', {
    conversion_type: conversionType,
    value: value,
    currency: 'INR',
  });
}

This implementation guide provides comprehensive, production-ready code examples that the Cursor AI agent can use to build the Securiace Technologies website with enterprise-grade quality and performance.