flutter_privacy_shield 0.0.1 copy "flutter_privacy_shield: ^0.0.1" to clipboard
flutter_privacy_shield: ^0.0.1 copied to clipboard

Privacy-focused utilities for data anonymization and GDPR compliance

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Privacy Shield Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const PrivacyShieldDemo(),
    );
  }
}

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

  @override
  State<PrivacyShieldDemo> createState() => _PrivacyShieldDemoState();
}

class _PrivacyShieldDemoState extends State<PrivacyShieldDemo> {
  late PrivacyShield privacyShield;
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _phoneController = TextEditingController();
  final TextEditingController _ssnController = TextEditingController();

  Map<String, dynamic>? processedData;
  String? privacyScore;
  List<Map<String, dynamic>> auditLog = [];
  ConsentStatus selectedConsent = ConsentStatus.granted;
  RetentionPolicy selectedRetention = RetentionPolicy.mediumTerm;

  @override
  void initState() {
    super.initState();
    privacyShield = PrivacyShield();
    _updatePrivacyScore();
    _updateAuditLog();
  }

  void _updatePrivacyScore() {
    setState(() {
      privacyScore = privacyShield.getPrivacyScore().toString();
    });
  }

  void _updateAuditLog() {
    setState(() {
      auditLog = privacyShield.getAuditLog();
    });
  }

  void _processData() {
    if (_nameController.text.isEmpty) {
      _showSnackBar('Please enter a name');
      return;
    }

    final userData = {
      'name': _nameController.text,
      'email': _emailController.text.isNotEmpty ? _emailController.text : null,
      'phone': _phoneController.text.isNotEmpty ? _phoneController.text : null,
      'ssn': _ssnController.text.isNotEmpty ? _ssnController.text : null,
    };

    // Remove null values
    userData.removeWhere((key, value) => value == null);

    try {
      final processed = privacyShield.processData(
        userData,
        purpose: 'demo_processing',
        consentStatus: selectedConsent,
        retentionPolicy: selectedRetention,
      );

      setState(() {
        processedData = processed;
      });

      _updateAuditLog();
      _showSnackBar('Data processed successfully!');
    } catch (e) {
      _showSnackBar('Error: ${e.toString()}');
    }
  }

  void _clearData() {
    setState(() {
      processedData = null;
      _nameController.clear();
      _emailController.clear();
      _phoneController.clear();
      _ssnController.clear();
    });
  }

  void _clearAuditLog() {
    privacyShield.clearAuditLog();
    _updateAuditLog();
    _showSnackBar('Audit log cleared');
  }

  void _showSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Privacy Shield Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildPrivacyScoreCard(),
            const SizedBox(height: 16),
            _buildInputForm(),
            const SizedBox(height: 16),
            _buildProcessedDataCard(),
            const SizedBox(height: 16),
            _buildAuditLogCard(),
          ],
        ),
      ),
    );
  }

  Widget _buildPrivacyScoreCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Privacy Score: $privacyScore/100',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 8),
            LinearProgressIndicator(
              value: (int.tryParse(privacyScore ?? '0') ?? 0) / 100,
              backgroundColor: Colors.grey[300],
              valueColor: AlwaysStoppedAnimation<Color>(
                (int.tryParse(privacyScore ?? '0') ?? 0) >= 80
                    ? Colors.green
                    : (int.tryParse(privacyScore ?? '0') ?? 0) >= 60
                        ? Colors.orange
                        : Colors.red,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              'This score indicates how well your data processing meets privacy requirements.',
              style: Theme.of(context).textTheme.bodySmall,
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildInputForm() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Input Data',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _nameController,
              decoration: const InputDecoration(
                labelText: 'Name *',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _emailController,
              decoration: const InputDecoration(
                labelText: 'Email',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _phoneController,
              decoration: const InputDecoration(
                labelText: 'Phone',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _ssnController,
              decoration: const InputDecoration(
                labelText: 'SSN',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: DropdownButtonFormField<ConsentStatus>(
                    initialValue: selectedConsent,
                    decoration: const InputDecoration(
                      labelText: 'Consent Status',
                      border: OutlineInputBorder(),
                    ),
                    items: ConsentStatus.values.map((status) {
                      return DropdownMenuItem(
                        value: status,
                        child: Text(status.toString().split('.').last),
                      );
                    }).toList(),
                    onChanged: (value) {
                      if (value != null) {
                        setState(() {
                          selectedConsent = value;
                        });
                      }
                    },
                  ),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: DropdownButtonFormField<RetentionPolicy>(
                    initialValue: selectedRetention,
                    decoration: const InputDecoration(
                      labelText: 'Retention Policy',
                      border: OutlineInputBorder(),
                    ),
                    items: RetentionPolicy.values.map((policy) {
                      return DropdownMenuItem(
                        value: policy,
                        child: Text(policy.toString().split('.').last),
                      );
                    }).toList(),
                    onChanged: (value) {
                      if (value != null) {
                        setState(() {
                          selectedRetention = value;
                        });
                      }
                    },
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _processData,
                    child: const Text('Process Data'),
                  ),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: OutlinedButton(
                    onPressed: _clearData,
                    child: const Text('Clear'),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildProcessedDataCard() {
    if (processedData == null) {
      return const SizedBox.shrink();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Processed Data',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SizedBox(height: 16),
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(8),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: processedData!.entries.map((entry) {
                  if (entry.key == '_privacy_metadata') {
                    return Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Divider(),
                        Text(
                          'Privacy Metadata:',
                          style: Theme.of(context).textTheme.titleMedium,
                        ),
                        const SizedBox(height: 8),
                        ...(entry.value as Map<String, dynamic>)
                            .entries
                            .map((meta) {
                          return Padding(
                            padding: const EdgeInsets.only(left: 16, bottom: 4),
                            child: Text('${meta.key}: ${meta.value}'),
                          );
                        }),
                      ],
                    );
                  }
                  return Padding(
                    padding: const EdgeInsets.only(bottom: 8),
                    child: Text('${entry.key}: ${entry.value}'),
                  );
                }).toList(),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildAuditLogCard() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  'Audit Log (${auditLog.length})',
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                if (auditLog.isNotEmpty)
                  TextButton(
                    onPressed: _clearAuditLog,
                    child: const Text('Clear Log'),
                  ),
              ],
            ),
            const SizedBox(height: 16),
            if (auditLog.isEmpty)
              const Text('No audit log entries yet.')
            else
              Container(
                height: 200,
                decoration: BoxDecoration(
                  color: Colors.grey[100],
                  borderRadius: BorderRadius.circular(8),
                ),
                child: ListView.builder(
                  itemCount: auditLog.length,
                  itemBuilder: (context, index) {
                    final entry = auditLog[
                        auditLog.length - 1 - index]; // Show newest first
                    return ListTile(
                      title: Text(entry['operation'] ?? 'Unknown'),
                      subtitle: Text(
                          '${entry['data_type']} - ${entry['consent_status']}'),
                      trailing: Text(
                        entry['timestamp']?.toString().substring(11, 19) ?? '',
                        style: Theme.of(context).textTheme.bodySmall,
                      ),
                    );
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _nameController.dispose();
    _emailController.dispose();
    _phoneController.dispose();
    _ssnController.dispose();
    super.dispose();
  }
}
2
likes
160
points
14
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

Privacy-focused utilities for data anonymization and GDPR compliance

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_privacy_shield