sm_ai_support 1.0.6 copy "sm_ai_support: ^1.0.6" to clipboard
sm_ai_support: ^1.0.6 copied to clipboard

A comprehensive Flutter package for integrating AI-powered customer support with real-time chat, media sharing, and multi-language support.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:sm_ai_support/sm_ai_support.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'SM AI Support Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF2563EB), primary: const Color(0xFF2563EB)),
        useMaterial3: true,
      ),
      home: const SupportDemoScreen(),
    );
  }
}

class SupportDemoScreen extends StatefulWidget {
  const SupportDemoScreen({super.key});

  @override
  State<SupportDemoScreen> createState() => _SupportDemoScreenState();
}

class _SupportDemoScreenState extends State<SupportDemoScreen> {
  final TextEditingController _phoneController = TextEditingController();
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _countryCodeController = TextEditingController(text: '+20');

  @override
  void dispose() {
    _phoneController.dispose();
    _nameController.dispose();
    _countryCodeController.dispose();
    super.dispose();
  }

  /// Opens SM Support as a bottom sheet within the current app context
  void _openBottomSheet(BuildContext context, {required bool isEnglish}) {
    SMSupport.show(
      context: context,
      smSupportData: SMSupportData(
        appName: 'UNI-SUPPORT',
        customer: _phoneController.text.isNotEmpty && _nameController.text.isNotEmpty && _countryCodeController.text.isNotEmpty
            ? CustomerData(
                countryCode: _countryCodeController.text,
                phone: _phoneController.text,
                name: _nameController.text,
              )
            : null,
        locale: isEnglish ? SMSupportLocale.en : SMSupportLocale.ar,
        tenantId: '1',
        apiKey: '17841476553120002', // Test API key for sandbox
        secretKey: 'in-app-default', // Test secret key for HMAC signing
        baseUrl: 'https://sandbox.unicode.team/api/core', // REST API base URL (HTTPS)
        socketBaseUrl: 'wss://sandbox.unicode.team/ws', // WebSocket base URL
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0,
        centerTitle: true,
        title: const Text(
          'SM AI Support',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Color(0xFF1E293B)),
        ),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const SizedBox(height: 20),

            // Logo
            Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(color: const Color(0xFF2563EB).withValues(alpha: 0.1), shape: BoxShape.circle),
              child: const Icon(Icons.support_agent_rounded, size: 64, color: Color(0xFF2563EB)),
            ),

            const SizedBox(height: 24),

            // Version
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
              decoration: BoxDecoration(
                color: const Color(0xFF2563EB).withValues(alpha: 0.1),
                borderRadius: BorderRadius.circular(16),
              ),
              child: const Text(
                'VERSION 1.0.6+7',
                style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: Color(0xFF2563EB), letterSpacing: 1),
              ),
            ),

            const SizedBox(height: 16),

            // Description
            const Text(
              'AI-Powered Customer Support',
              style: TextStyle(fontSize: 16, color: Color(0xFF64748B)),
              textAlign: TextAlign.center,
            ),

            const SizedBox(height: 40),

            // Auto-Login Test Fields
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                'Auto-Login Test (Optional)',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1E293B)),
              ),
            ),

            const SizedBox(height: 16),

            TextField(
              controller: _nameController,
              decoration: InputDecoration(
                labelText: 'Name',
                hintText: 'Enter customer name',
                prefixIcon: const Icon(Icons.person_outline, color: Color(0xFF2563EB)),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                  borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                ),
                enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                  borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(12),
                  borderSide: const BorderSide(color: Color(0xFF2563EB), width: 2),
                ),
              ),
            ),

            const SizedBox(height: 12),

            Row(
              children: [
                SizedBox(
                  width: 100,
                  child: TextField(
                    controller: _countryCodeController,
                    keyboardType: TextInputType.phone,
                    decoration: InputDecoration(
                      labelText: 'Code',
                      hintText: '+20',
                      prefixIcon: const Icon(Icons.flag_outlined, color: Color(0xFF2563EB)),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFF2563EB), width: 2),
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: TextField(
                    controller: _phoneController,
                    keyboardType: TextInputType.phone,
                    decoration: InputDecoration(
                      labelText: 'Phone',
                      hintText: 'Enter phone number',
                      prefixIcon: const Icon(Icons.phone_outlined, color: Color(0xFF2563EB)),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFFE2E8F0)),
                      ),
                      focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(12),
                        borderSide: const BorderSide(color: Color(0xFF2563EB), width: 2),
                      ),
                    ),
                  ),
                ),
              ],
            ),

            const SizedBox(height: 8),

            const Text(
              'Leave empty for anonymous mode',
              style: TextStyle(fontSize: 12, color: Color(0xFF64748B), fontStyle: FontStyle.italic),
              textAlign: TextAlign.center,
            ),

            const SizedBox(height: 32),

            // Demo Buttons - Bottom Sheet Mode
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                'Bottom Sheet Mode (Recommended)',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1E293B)),
              ),
            ),

            const SizedBox(height: 16),

            _buildDemoButton(
              context,
              icon: Icons.chat_bubble_outline_rounded,
              title: 'Open as Bottom Sheet',
              subtitle: 'Arabic - Opens within current app',
              onTap: () => _openBottomSheet(context, isEnglish: false),
            ),

            const SizedBox(height: 12),

            _buildDemoButton(
              context,
              icon: Icons.language_rounded,
              title: 'Open as Bottom Sheet EN',
              subtitle: 'English - Opens within current app',
              onTap: () => _openBottomSheet(context, isEnglish: true),
            ),

            const SizedBox(height: 32),

            // Demo Buttons - Full Screen Mode
            // const Align(
            //   alignment: Alignment.centerLeft,
            //   child: Text(
            //     'Full Screen Mode (Legacy)',
            //     style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1E293B)),
            //   ),
            // ),

            // const SizedBox(height: 16),

            // _buildDemoButton(
            //   context,
            //   icon: Icons.fullscreen_rounded,
            //   title: 'Open Full Screen',
            //   subtitle: 'Arabic - Opens as new screen',
            //   onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => SMSupportPage())),
            // ),

            // const SizedBox(height: 12),

            // _buildDemoButton(
            //   context,
            //   icon: Icons.fullscreen_rounded,
            //   title: 'Open Full Screen EN',
            //   subtitle: 'English - Opens as new screen',
            //   onTap: () =>
            //       Navigator.push(context, MaterialPageRoute(builder: (context) => SMSupportPage(isEnglish: true))),
            // ),

            // const SizedBox(height: 40),

            // Features
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                'Features',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1E293B)),
              ),
            ),

            const SizedBox(height: 16),

            _buildFeature('Tenant-based configuration'),
            _buildFeature('Auto-fetched categories'),
            _buildFeature('Real-time chat'),
            _buildFeature('Media upload'),
            _buildFeature('Session management'),
            _buildFeature('Bilingual support (EN/AR)'),
            _buildFeature('Customizable theme', isLast: true),

            const SizedBox(height: 40),

            // Footer
            Text(
              'Powered by SM Platform',
              style: TextStyle(fontSize: 12, color: const Color(0xFF64748B).withValues(alpha: 0.7)),
            ),

            const SizedBox(height: 20),
          ],
        ),
      ),
    );
  }

  Widget _buildDemoButton(
    BuildContext context, {
    required IconData icon,
    required String title,
    required String subtitle,
    required VoidCallback onTap,
  }) {
    return Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(12),
        child: Container(
          padding: const EdgeInsets.all(16),
          decoration: BoxDecoration(
            border: Border.all(color: const Color(0xFFE2E8F0)),
            borderRadius: BorderRadius.circular(12),
          ),
          child: Row(
            children: [
              Icon(icon, color: const Color(0xFF2563EB), size: 24),
              const SizedBox(width: 16),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      title,
                      style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1E293B)),
                    ),
                    const SizedBox(height: 2),
                    Text(subtitle, style: const TextStyle(fontSize: 13, color: Color(0xFF64748B))),
                  ],
                ),
              ),
              const Icon(Icons.arrow_forward_ios_rounded, color: Color(0xFF94A3B8), size: 16),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildFeature(String text, {bool isLast = false}) {
    return Padding(
      padding: EdgeInsets.only(bottom: isLast ? 0 : 12),
      child: Row(
        children: [
          const Icon(Icons.check_circle_rounded, color: Color(0xFF10B981), size: 18),
          const SizedBox(width: 12),
          Expanded(
            child: Text(text, style: const TextStyle(fontSize: 14, color: Color(0xFF475569))),
          ),
        ],
      ),
    );
  }
}