Files
SAVExSTATE/lib/admin_artifact_screen.dart

115 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:typed_data';
class AdminArtifactScreen extends StatefulWidget {
const AdminArtifactScreen({super.key});
@override
State<AdminArtifactScreen> createState() => _AdminArtifactScreenState();
}
class _AdminArtifactScreenState extends State<AdminArtifactScreen> {
final _titleController = TextEditingController();
final _descController = TextEditingController();
final _priceController = TextEditingController();
final _stockController = TextEditingController();
final _urlController = TextEditingController(); // FOR EXTERNAL STORE LINK
Uint8List? _fileBytes;
String? _fileName;
bool _isUploading = false;
Future<void> _pickImage() async {
final result = await FilePicker.platform.pickFiles(type: FileType.image, withData: true);
if (result != null) {
setState(() {
_fileBytes = result.files.first.bytes;
_fileName = result.files.first.name;
});
}
}
Future<void> _upload() async {
if (_fileBytes == null || _titleController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("MISSING_DATA")));
return;
}
setState(() => _isUploading = true);
try {
// 1. Upload to Storage
final path = 'artifacts/${DateTime.now().millisecondsSinceEpoch}_$_fileName';
final task = await FirebaseStorage.instance.ref().child(path).putData(_fileBytes!);
final url = await task.ref.getDownloadURL();
// 2. Save Document to Firestore
await FirebaseFirestore.instance.collection('artifacts').add({
'title': _titleController.text.trim(),
'description': _descController.text.trim(),
'price': _priceController.text.trim(),
'stock': _stockController.text.trim(),
'purchaseUrl': _urlController.text.trim(), // LINK TO STORE
'imageUrl': url,
'serial': "SS-${DateTime.now().millisecondsSinceEpoch.toString().substring(8)}",
'createdAt': FieldValue.serverTimestamp(),
});
if (!mounted) return;
Navigator.pop(context);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("SYSTEM_ERROR: $e")));
} finally {
setState(() => _isUploading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("REGISTER_ARTIFACT")),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
children: [
// Preview selected image
Container(
height: 200,
width: double.infinity,
decoration: BoxDecoration(border: Border.all(color: const Color(0xFF00FF00))),
child: _fileBytes == null
? const Center(child: Text("NO_IMAGE_LOADED"))
: Image.memory(_fileBytes!, fit: BoxFit.cover),
),
const SizedBox(height: 15),
OutlinedButton(onPressed: _pickImage, child: const Text("[ SELECT_ASSET_IMAGE ]")),
const SizedBox(height: 30),
TextField(controller: _titleController, decoration: const InputDecoration(labelText: "ASSET_NAME")),
const SizedBox(height: 15),
TextField(controller: _descController, maxLines: 3, decoration: const InputDecoration(labelText: "TECHNICAL_SPECS")),
const SizedBox(height: 15),
TextField(controller: _urlController, decoration: const InputDecoration(labelText: "PURCHASE_GATEWAY_URL")),
const SizedBox(height: 15),
Row(
children: [
Expanded(child: TextField(controller: _priceController, decoration: const InputDecoration(labelText: "VALUE_\$"))),
const SizedBox(width: 15),
Expanded(child: TextField(controller: _stockController, decoration: const InputDecoration(labelText: "UNITS_AVAIL"))),
],
),
const SizedBox(height: 50),
_isUploading
? const CircularProgressIndicator(color: Color(0xFF00FF00))
: ElevatedButton(onPressed: _upload, child: const Text("[ EXECUTE_REGISTRATION ]")),
],
),
),
);
}
}