dev #1
@ -1,130 +1,683 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:enaklo_pos/presentation/setting/bloc/upload_file/upload_file_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
|
||||||
import '../assets/assets.gen.dart';
|
|
||||||
import '../constants/colors.dart';
|
import '../constants/colors.dart';
|
||||||
import '../constants/variables.dart';
|
import '../constants/variables.dart';
|
||||||
import 'buttons.dart';
|
|
||||||
import 'spaces.dart';
|
import 'spaces.dart';
|
||||||
|
|
||||||
class ImagePickerWidget extends StatefulWidget {
|
class ImagePickerWidget extends StatefulWidget {
|
||||||
final String label;
|
final String label;
|
||||||
final void Function(XFile? file) onChanged;
|
final void Function(XFile? file) onChanged;
|
||||||
|
final void Function(String? uploadedUrl)? onUploaded;
|
||||||
final bool showLabel;
|
final bool showLabel;
|
||||||
final String? initialImageUrl;
|
final String? initialImageUrl;
|
||||||
|
final bool autoUpload;
|
||||||
|
|
||||||
const ImagePickerWidget({
|
const ImagePickerWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.label,
|
required this.label,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
this.onUploaded,
|
||||||
this.showLabel = true,
|
this.showLabel = true,
|
||||||
this.initialImageUrl,
|
this.initialImageUrl,
|
||||||
|
this.autoUpload = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
|
State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ImagePickerWidgetState extends State<ImagePickerWidget> {
|
class _ImagePickerWidgetState extends State<ImagePickerWidget>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
String? imagePath;
|
String? imagePath;
|
||||||
|
String? uploadedImageUrl;
|
||||||
bool hasInitialImage = false;
|
bool hasInitialImage = false;
|
||||||
|
bool isHovering = false;
|
||||||
|
bool isUploading = false;
|
||||||
|
late AnimationController _scaleController;
|
||||||
|
late AnimationController _fadeController;
|
||||||
|
late AnimationController _uploadController;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
late Animation<double> _uploadAnimation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
hasInitialImage = widget.initialImageUrl != null;
|
hasInitialImage = widget.initialImageUrl != null;
|
||||||
|
|
||||||
|
_scaleController = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
_fadeController = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
_uploadController = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 1000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = Tween<double>(
|
||||||
|
begin: 1.0,
|
||||||
|
end: 0.95,
|
||||||
|
).animate(CurvedAnimation(
|
||||||
|
parent: _scaleController,
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
));
|
||||||
|
|
||||||
|
_fadeAnimation = Tween<double>(
|
||||||
|
begin: 0.0,
|
||||||
|
end: 1.0,
|
||||||
|
).animate(CurvedAnimation(
|
||||||
|
parent: _fadeController,
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
));
|
||||||
|
|
||||||
|
_uploadAnimation = Tween<double>(
|
||||||
|
begin: 0.0,
|
||||||
|
end: 1.0,
|
||||||
|
).animate(CurvedAnimation(
|
||||||
|
parent: _uploadController,
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
));
|
||||||
|
|
||||||
|
_fadeController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scaleController.dispose();
|
||||||
|
_fadeController.dispose();
|
||||||
|
_uploadController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _pickImage() async {
|
Future<void> _pickImage() async {
|
||||||
|
_scaleController.forward().then((_) {
|
||||||
|
_scaleController.reverse();
|
||||||
|
});
|
||||||
|
|
||||||
final pickedFile = await ImagePicker().pickImage(
|
final pickedFile = await ImagePicker().pickImage(
|
||||||
source: ImageSource.gallery,
|
source: ImageSource.gallery,
|
||||||
);
|
);
|
||||||
|
|
||||||
setState(() {
|
|
||||||
if (pickedFile != null) {
|
if (pickedFile != null) {
|
||||||
|
setState(() {
|
||||||
imagePath = pickedFile.path;
|
imagePath = pickedFile.path;
|
||||||
hasInitialImage = false; // Clear initial image when new image is picked
|
hasInitialImage = false;
|
||||||
|
uploadedImageUrl = null;
|
||||||
|
});
|
||||||
|
|
||||||
widget.onChanged(pickedFile);
|
widget.onChanged(pickedFile);
|
||||||
|
|
||||||
|
// Auto upload if enabled
|
||||||
|
if (widget.autoUpload) {
|
||||||
|
_uploadImage(pickedFile.path);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debugPrint('No image selected.');
|
debugPrint('No image selected.');
|
||||||
widget.onChanged(null);
|
widget.onChanged(null);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
void _uploadImage(String filePath) {
|
||||||
Widget build(BuildContext context) {
|
setState(() {
|
||||||
return Column(
|
isUploading = true;
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
});
|
||||||
children: [
|
_uploadController.forward();
|
||||||
if (widget.showLabel) ...[
|
|
||||||
Text(
|
context.read<UploadFileBloc>().add(
|
||||||
widget.label,
|
UploadFileEvent.upload(filePath),
|
||||||
style: const TextStyle(
|
);
|
||||||
fontSize: 14,
|
}
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
Widget _buildImageContainer() {
|
||||||
),
|
return Container(
|
||||||
const SpaceHeight(12.0),
|
width: 100.0,
|
||||||
],
|
height: 100.0,
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(6.0),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
border: Border.all(color: AppColors.primary),
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withOpacity(0.1),
|
||||||
|
blurRadius: 10,
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 80.0,
|
|
||||||
height: 80.0,
|
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned.fill(
|
||||||
child: imagePath != null
|
child: imagePath != null
|
||||||
? Image.file(
|
? Image.file(
|
||||||
File(imagePath!),
|
File(imagePath!),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
)
|
)
|
||||||
|
: uploadedImageUrl != null
|
||||||
|
? CachedNetworkImage(
|
||||||
|
imageUrl: uploadedImageUrl!.contains('http')
|
||||||
|
? uploadedImageUrl!
|
||||||
|
: '${Variables.baseUrl}/$uploadedImageUrl',
|
||||||
|
placeholder: (context, url) => Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColors.primary.withOpacity(0.1),
|
||||||
|
AppColors.primary.withOpacity(0.05),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
errorWidget: (context, url, error) =>
|
||||||
|
_buildPlaceholder(),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
)
|
||||||
: hasInitialImage && widget.initialImageUrl != null
|
: hasInitialImage && widget.initialImageUrl != null
|
||||||
? CachedNetworkImage(
|
? CachedNetworkImage(
|
||||||
imageUrl: widget.initialImageUrl!.contains('http')
|
imageUrl: widget.initialImageUrl!.contains('http')
|
||||||
? widget.initialImageUrl!
|
? widget.initialImageUrl!
|
||||||
: '${Variables.baseUrl}/${widget.initialImageUrl}',
|
: '${Variables.baseUrl}/${widget.initialImageUrl}',
|
||||||
placeholder: (context, url) =>
|
placeholder: (context, url) => Container(
|
||||||
const Center(child: CircularProgressIndicator()),
|
decoration: BoxDecoration(
|
||||||
errorWidget: (context, url, error) => Container(
|
gradient: LinearGradient(
|
||||||
padding: const EdgeInsets.all(16.0),
|
colors: [
|
||||||
color: AppColors.black.withOpacity(0.05),
|
AppColors.primary.withOpacity(0.1),
|
||||||
child: Assets.icons.image.svg(),
|
AppColors.primary.withOpacity(0.05),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
errorWidget: (context, url, error) =>
|
||||||
|
_buildPlaceholder(),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
)
|
)
|
||||||
: Container(
|
: _buildPlaceholder(),
|
||||||
padding: const EdgeInsets.all(16.0),
|
),
|
||||||
color: AppColors.black.withOpacity(0.05),
|
// Upload progress overlay
|
||||||
child: Assets.icons.image.svg(),
|
if (isUploading)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: Colors.white,
|
||||||
|
strokeWidth: 2,
|
||||||
|
value: _uploadAnimation.value == 1.0
|
||||||
|
? null
|
||||||
|
: _uploadAnimation.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
const Text(
|
||||||
|
'Uploading...',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
),
|
||||||
Padding(
|
// Overlay gradient for better button visibility
|
||||||
padding: const EdgeInsets.only(right: 10.0),
|
if ((imagePath != null ||
|
||||||
child: Button.filled(
|
uploadedImageUrl != null ||
|
||||||
height: 30.0,
|
(hasInitialImage && widget.initialImageUrl != null)) &&
|
||||||
width: 140.0,
|
!isUploading)
|
||||||
onPressed: _pickImage,
|
Positioned.fill(
|
||||||
label: 'Choose Photo',
|
child: Container(
|
||||||
fontSize: 12.0,
|
decoration: BoxDecoration(
|
||||||
borderRadius: 5.0,
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
Colors.transparent,
|
||||||
|
Colors.black.withOpacity(0.3),
|
||||||
|
],
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPlaceholder() {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColors.primary.withOpacity(0.1),
|
||||||
|
AppColors.primary.withOpacity(0.05),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.add_photo_alternate_outlined,
|
||||||
|
size: 32,
|
||||||
|
color: AppColors.primary.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
'Photo',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: AppColors.primary.withOpacity(0.6),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildActionButton() {
|
||||||
|
bool hasImage = imagePath != null ||
|
||||||
|
uploadedImageUrl != null ||
|
||||||
|
(hasInitialImage && widget.initialImageUrl != null);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
AppColors.primary,
|
||||||
|
AppColors.primary.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColors.primary.withOpacity(0.3),
|
||||||
|
blurRadius: 8,
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: isUploading ? null : _pickImage,
|
||||||
|
onHover: (hover) {
|
||||||
|
setState(() {
|
||||||
|
isHovering = hover;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
color: isHovering
|
||||||
|
? Colors.white.withOpacity(0.1)
|
||||||
|
: Colors.transparent,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
isUploading
|
||||||
|
? Icons.cloud_upload_outlined
|
||||||
|
: hasImage
|
||||||
|
? Icons.edit_outlined
|
||||||
|
: Icons.add_photo_alternate_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
isUploading
|
||||||
|
? 'Uploading...'
|
||||||
|
: hasImage
|
||||||
|
? 'Change Photo'
|
||||||
|
: 'Choose Photo',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildUploadButton() {
|
||||||
|
if (!widget.autoUpload &&
|
||||||
|
imagePath != null &&
|
||||||
|
uploadedImageUrl == null &&
|
||||||
|
!isUploading) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 12),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: [
|
||||||
|
Colors.green.shade600,
|
||||||
|
Colors.green.shade500,
|
||||||
|
],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.green.withOpacity(0.3),
|
||||||
|
blurRadius: 8,
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => _uploadImage(imagePath!),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.cloud_upload_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Upload to Server',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocListener<UploadFileBloc, UploadFileState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
state.when(
|
||||||
|
initial: () {},
|
||||||
|
loading: () {
|
||||||
|
if (!isUploading) {
|
||||||
|
setState(() {
|
||||||
|
isUploading = true;
|
||||||
|
});
|
||||||
|
_uploadController.repeat();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: (fileData) {
|
||||||
|
setState(() {
|
||||||
|
isUploading = false;
|
||||||
|
uploadedImageUrl = fileData.fileUrl;
|
||||||
|
});
|
||||||
|
_uploadController.reset();
|
||||||
|
|
||||||
|
if (widget.onUploaded != null) {
|
||||||
|
widget.onUploaded!(fileData.fileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.check_circle, color: Colors.white),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text('Image uploaded successfully!'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: (message) {
|
||||||
|
setState(() {
|
||||||
|
isUploading = false;
|
||||||
|
});
|
||||||
|
_uploadController.reset();
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.error_outline, color: Colors.white),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Expanded(child: Text('Upload failed: $message')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
duration: Duration(seconds: 3),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (widget.showLabel) ...[
|
||||||
|
Text(
|
||||||
|
widget.label,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SpaceHeight(16.0),
|
||||||
|
],
|
||||||
|
ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
|
color: Colors.white,
|
||||||
|
border: Border.all(
|
||||||
|
color: isUploading
|
||||||
|
? Colors.orange.withOpacity(0.5)
|
||||||
|
: uploadedImageUrl != null
|
||||||
|
? Colors.green.withOpacity(0.5)
|
||||||
|
: AppColors.primary.withOpacity(0.2),
|
||||||
|
width: 1.5,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withOpacity(0.05),
|
||||||
|
blurRadius: 20,
|
||||||
|
offset: const Offset(0, 10),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildImageContainer(),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
_buildActionButton(),
|
||||||
|
_buildUploadButton(),
|
||||||
|
if ((imagePath != null ||
|
||||||
|
uploadedImageUrl != null ||
|
||||||
|
(hasInitialImage &&
|
||||||
|
widget.initialImageUrl != null)) &&
|
||||||
|
!isUploading) ...[
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
imagePath = null;
|
||||||
|
hasInitialImage = false;
|
||||||
|
uploadedImageUrl = null;
|
||||||
|
});
|
||||||
|
widget.onChanged(null);
|
||||||
|
if (widget.onUploaded != null) {
|
||||||
|
widget.onUploaded!(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.delete_outline,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.red.shade400,
|
||||||
|
),
|
||||||
|
label: Text(
|
||||||
|
'Remove Photo',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.red.shade400,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
// Upload status indicator
|
||||||
|
if (uploadedImageUrl != null && !isUploading) ...[
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border:
|
||||||
|
Border.all(color: Colors.green.withOpacity(0.3)),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.cloud_done_outlined,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.green.shade600,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
'Uploaded',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.green.shade600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cara menggunakan widget ini:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// // 1. Basic usage tanpa auto upload
|
||||||
|
/// ImagePickerWidget(
|
||||||
|
/// label: 'Product Image',
|
||||||
|
/// onChanged: (file) {
|
||||||
|
/// // Handle selected file
|
||||||
|
/// print('Selected file: ${file?.path}');
|
||||||
|
/// },
|
||||||
|
/// onUploaded: (url) {
|
||||||
|
/// // Handle uploaded URL
|
||||||
|
/// print('Uploaded URL: $url');
|
||||||
|
/// },
|
||||||
|
/// )
|
||||||
|
///
|
||||||
|
/// // 2. Auto upload setelah memilih gambar
|
||||||
|
/// ImagePickerWidget(
|
||||||
|
/// label: 'Profile Picture',
|
||||||
|
/// autoUpload: true,
|
||||||
|
/// onChanged: (file) => setState(() => selectedFile = file),
|
||||||
|
/// onUploaded: (url) => setState(() => profileImageUrl = url),
|
||||||
|
/// )
|
||||||
|
///
|
||||||
|
/// // 3. Dengan initial image
|
||||||
|
/// ImagePickerWidget(
|
||||||
|
/// label: 'Banner Image',
|
||||||
|
/// initialImageUrl: existingImageUrl,
|
||||||
|
/// onChanged: (file) => handleFileChange(file),
|
||||||
|
/// onUploaded: (url) => handleUploadSuccess(url),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Pastikan untuk wrap widget ini dengan BlocProvider:
|
||||||
|
/// ```dart
|
||||||
|
/// BlocProvider(
|
||||||
|
/// create: (context) => UploadFileBloc(
|
||||||
|
/// context.read<FileRemoteDataSource>(),
|
||||||
|
/// ),
|
||||||
|
/// child: ImagePickerWidget(...),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
@ -1,27 +1,48 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:enaklo_pos/core/constants/variables.dart';
|
import 'package:enaklo_pos/core/constants/variables.dart';
|
||||||
|
import 'package:enaklo_pos/core/network/dio_client.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/category_response_model.dart';
|
import 'package:enaklo_pos/data/models/response/category_response_model.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
|
|
||||||
class CategoryRemoteDatasource {
|
class CategoryRemoteDatasource {
|
||||||
Future<Either<String, CategroyResponseModel>> getCategories() async {
|
final Dio dio = DioClient.instance;
|
||||||
|
|
||||||
|
Future<Either<String, CategoryResponseModel>> getCategories({
|
||||||
|
int page = 1,
|
||||||
|
int limit = 10,
|
||||||
|
bool isActive = true,
|
||||||
|
}) async {
|
||||||
final authData = await AuthLocalDataSource().getAuthData();
|
final authData = await AuthLocalDataSource().getAuthData();
|
||||||
final Map<String, String> headers = {
|
final headers = {
|
||||||
'Authorization': 'Bearer ${authData.token}',
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
};
|
};
|
||||||
final response = await http.get(
|
|
||||||
Uri.parse('${Variables.baseUrl}/api/api-categories'),
|
try {
|
||||||
headers: headers);
|
final response = await dio.get(
|
||||||
log(response.statusCode.toString());
|
'${Variables.baseUrl}/api/v1/categories',
|
||||||
log(response.body);
|
queryParameters: {
|
||||||
|
'page': page,
|
||||||
|
'limit': limit,
|
||||||
|
'is_active': isActive,
|
||||||
|
},
|
||||||
|
options: Options(headers: headers),
|
||||||
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
return right(CategroyResponseModel.fromJson(response.body));
|
return right(CategoryResponseModel.fromMap(response.data));
|
||||||
} else {
|
} else {
|
||||||
return left(response.body);
|
return left(response.data.toString());
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
log('Dio error: ${e.message}');
|
||||||
|
return left(e.response?.data.toString() ?? e.message ?? 'Unknown error');
|
||||||
|
} catch (e) {
|
||||||
|
log('Unexpected error: $e');
|
||||||
|
return left('Unexpected error occurred');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
lib/data/datasources/file_remote_datasource.dart
Normal file
53
lib/data/datasources/file_remote_datasource.dart
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:enaklo_pos/core/constants/variables.dart';
|
||||||
|
import 'package:enaklo_pos/core/network/dio_client.dart';
|
||||||
|
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
||||||
|
import 'package:enaklo_pos/data/models/response/file_response_model.dart';
|
||||||
|
|
||||||
|
class FileRemoteDataSource {
|
||||||
|
final Dio dio = DioClient.instance;
|
||||||
|
|
||||||
|
Future<Either<String, FileResponseModel>> uploadFile({
|
||||||
|
required String filePath,
|
||||||
|
required String fileType,
|
||||||
|
required String description,
|
||||||
|
}) async {
|
||||||
|
final url = '${Variables.baseUrl}/api/v1/files/upload';
|
||||||
|
|
||||||
|
try {
|
||||||
|
final authData = await AuthLocalDataSource().getAuthData();
|
||||||
|
|
||||||
|
// Membuat FormData
|
||||||
|
final formData = FormData.fromMap({
|
||||||
|
'file': await MultipartFile.fromFile(filePath,
|
||||||
|
filename: filePath.split('/').last),
|
||||||
|
'file_type': fileType,
|
||||||
|
'description': description,
|
||||||
|
});
|
||||||
|
|
||||||
|
final response = await dio.post(
|
||||||
|
url,
|
||||||
|
data: formData,
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
// Content-Type otomatis diatur oleh Dio untuk FormData
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 201 || response.statusCode == 200) {
|
||||||
|
// Misal response.data['url'] adalah URL file yang diupload
|
||||||
|
return Right(FileResponseModel.fromJson(response.data));
|
||||||
|
} else {
|
||||||
|
return Left('Upload gagal: ${response.statusMessage}');
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
return Left(e.response?.data['message'] ?? 'Upload gagal');
|
||||||
|
} catch (e) {
|
||||||
|
return Left('Unexpected error: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,6 @@ import 'package:enaklo_pos/core/network/dio_client.dart';
|
|||||||
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/add_product_response_model.dart';
|
import 'package:enaklo_pos/data/models/response/add_product_response_model.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
|
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
|
|
||||||
import '../../core/constants/variables.dart';
|
import '../../core/constants/variables.dart';
|
||||||
import 'auth_local_datasource.dart';
|
import 'auth_local_datasource.dart';
|
||||||
@ -21,6 +20,10 @@ class ProductRemoteDatasource {
|
|||||||
|
|
||||||
final response = await dio.get(
|
final response = await dio.get(
|
||||||
url,
|
url,
|
||||||
|
queryParameters: {
|
||||||
|
'page': 1,
|
||||||
|
'limit': 30,
|
||||||
|
},
|
||||||
options: Options(
|
options: Options(
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Bearer ${authData.token}',
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
@ -45,67 +48,64 @@ class ProductRemoteDatasource {
|
|||||||
|
|
||||||
Future<Either<String, AddProductResponseModel>> addProduct(
|
Future<Either<String, AddProductResponseModel>> addProduct(
|
||||||
ProductRequestModel productRequestModel) async {
|
ProductRequestModel productRequestModel) async {
|
||||||
|
try {
|
||||||
final authData = await AuthLocalDataSource().getAuthData();
|
final authData = await AuthLocalDataSource().getAuthData();
|
||||||
final Map<String, String> headers = {
|
final url = '${Variables.baseUrl}/api/v1/products';
|
||||||
|
|
||||||
|
final response = await dio.post(
|
||||||
|
url,
|
||||||
|
data: productRequestModel.toMap(),
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
'Authorization': 'Bearer ${authData.token}',
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
};
|
'Accept': 'application/json',
|
||||||
var request = http.MultipartRequest(
|
},
|
||||||
'POST', Uri.parse('${Variables.baseUrl}/api/products'));
|
),
|
||||||
request.fields.addAll(productRequestModel.toMap());
|
);
|
||||||
request.files.add(await http.MultipartFile.fromPath(
|
|
||||||
'image', productRequestModel.image!.path));
|
|
||||||
request.headers.addAll(headers);
|
|
||||||
|
|
||||||
http.StreamedResponse response = await request.send();
|
if (response.statusCode == 200) {
|
||||||
|
return Right(AddProductResponseModel.fromMap(response.data));
|
||||||
final String body = await response.stream.bytesToString();
|
|
||||||
log(response.stream.toString());
|
|
||||||
log(response.statusCode.toString());
|
|
||||||
if (response.statusCode == 201) {
|
|
||||||
return right(AddProductResponseModel.fromJson(body));
|
|
||||||
} else {
|
} else {
|
||||||
return left(body);
|
return const Left('Failed to create products');
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
log("Dio error: ${e.message}");
|
||||||
|
return Left(e.response?.data['message'] ?? 'Gagal menambah produk');
|
||||||
|
} catch (e) {
|
||||||
|
log("Unexpected error: $e");
|
||||||
|
return const Left('Unexpected error occurred');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<String, AddProductResponseModel>> updateProduct(
|
Future<Either<String, AddProductResponseModel>> updateProduct(
|
||||||
ProductRequestModel productRequestModel) async {
|
ProductRequestModel productRequestModel) async {
|
||||||
|
try {
|
||||||
final authData = await AuthLocalDataSource().getAuthData();
|
final authData = await AuthLocalDataSource().getAuthData();
|
||||||
final Map<String, String> headers = {
|
final url =
|
||||||
|
'${Variables.baseUrl}/api/v1/products/${productRequestModel.id}';
|
||||||
|
|
||||||
|
final response = await dio.put(
|
||||||
|
url,
|
||||||
|
data: productRequestModel.toMap(),
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
'Authorization': 'Bearer ${authData.token}',
|
'Authorization': 'Bearer ${authData.token}',
|
||||||
};
|
'Accept': 'application/json',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
log("Update Product Request Data: ${productRequestModel.toMap()}");
|
|
||||||
log("Update Product ID: ${productRequestModel.id}");
|
|
||||||
log("Update Product Name: ${productRequestModel.name}");
|
|
||||||
log("Update Product Price: ${productRequestModel.price}");
|
|
||||||
log("Update Product Stock: ${productRequestModel.stock}");
|
|
||||||
log("Update Product Category ID: ${productRequestModel.categoryId}");
|
|
||||||
log("Update Product Is Best Seller: ${productRequestModel.isBestSeller}");
|
|
||||||
log("Update Product Printer Type: ${productRequestModel.printerType}");
|
|
||||||
log("Update Product Has Image: ${productRequestModel.image != null}");
|
|
||||||
|
|
||||||
var request = http.MultipartRequest(
|
|
||||||
'POST', Uri.parse('${Variables.baseUrl}/api/products/edit'));
|
|
||||||
request.fields.addAll(productRequestModel.toMap());
|
|
||||||
if (productRequestModel.image != null) {
|
|
||||||
request.files.add(await http.MultipartFile.fromPath(
|
|
||||||
'image', productRequestModel.image!.path));
|
|
||||||
}
|
|
||||||
request.headers.addAll(headers);
|
|
||||||
|
|
||||||
log("Update Product Request Fields: ${request.fields}");
|
|
||||||
log("Update Product Request Files: ${request.files.length}");
|
|
||||||
|
|
||||||
http.StreamedResponse response = await request.send();
|
|
||||||
|
|
||||||
final String body = await response.stream.bytesToString();
|
|
||||||
log("Update Product Status Code: ${response.statusCode}");
|
|
||||||
log("Update Product Body: $body");
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
return right(AddProductResponseModel.fromJson(body));
|
return Right(AddProductResponseModel.fromMap(response.data));
|
||||||
} else {
|
} else {
|
||||||
return left(body);
|
return const Left('Failed to update products');
|
||||||
|
}
|
||||||
|
} on DioException catch (e) {
|
||||||
|
log("Dio error: ${e.message}");
|
||||||
|
return Left(e.response?.data['message'] ?? 'Gagal update produk');
|
||||||
|
} catch (e) {
|
||||||
|
log("Unexpected error: $e");
|
||||||
|
return const Left('Unexpected error occurred');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,49 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:image_picker/image_picker.dart';
|
|
||||||
|
|
||||||
class ProductRequestModel {
|
class ProductRequestModel {
|
||||||
final String? id;
|
final String? id;
|
||||||
final String name;
|
final String name;
|
||||||
|
final String? description;
|
||||||
|
final String categoryId;
|
||||||
|
final String? sku;
|
||||||
|
final String? barcode;
|
||||||
final int price;
|
final int price;
|
||||||
final int stock;
|
final int cost;
|
||||||
final int categoryId;
|
final bool isActive;
|
||||||
final int isBestSeller;
|
final bool hasVariants;
|
||||||
final XFile? image;
|
final String imageUrl;
|
||||||
final String? printerType;
|
final String? printerType;
|
||||||
|
|
||||||
ProductRequestModel({
|
ProductRequestModel({
|
||||||
this.id,
|
this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.price,
|
this.description,
|
||||||
required this.stock,
|
|
||||||
required this.categoryId,
|
required this.categoryId,
|
||||||
required this.isBestSeller,
|
this.sku,
|
||||||
this.image,
|
this.barcode,
|
||||||
|
required this.price,
|
||||||
|
required this.cost,
|
||||||
|
this.isActive = true,
|
||||||
|
this.hasVariants = false,
|
||||||
|
required this.imageUrl,
|
||||||
this.printerType,
|
this.printerType,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, String> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
log("toMap: $isBestSeller");
|
final map = <String, dynamic>{
|
||||||
final map = {
|
|
||||||
'name': name,
|
'name': name,
|
||||||
'price': price.toString(),
|
'description': description ?? '',
|
||||||
'stock': stock.toString(),
|
'category_id': categoryId,
|
||||||
'category_id': categoryId.toString(),
|
'sku': sku ?? '',
|
||||||
'is_best_seller': isBestSeller.toString(),
|
'barcode': barcode ?? '',
|
||||||
|
'price': price,
|
||||||
|
'cost': cost,
|
||||||
|
'is_active': isActive,
|
||||||
|
'has_variants': hasVariants,
|
||||||
|
'image_url': imageUrl,
|
||||||
'printer_type': printerType ?? '',
|
'printer_type': printerType ?? '',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
map['id'] = id.toString();
|
map['id'] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|||||||
@ -4,12 +4,10 @@ import 'package:enaklo_pos/data/models/response/product_response_model.dart';
|
|||||||
|
|
||||||
class AddProductResponseModel {
|
class AddProductResponseModel {
|
||||||
final bool success;
|
final bool success;
|
||||||
final String message;
|
|
||||||
final Product data;
|
final Product data;
|
||||||
|
|
||||||
AddProductResponseModel({
|
AddProductResponseModel({
|
||||||
required this.success,
|
required this.success,
|
||||||
required this.message,
|
|
||||||
required this.data,
|
required this.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -21,13 +19,11 @@ class AddProductResponseModel {
|
|||||||
factory AddProductResponseModel.fromMap(Map<String, dynamic> json) =>
|
factory AddProductResponseModel.fromMap(Map<String, dynamic> json) =>
|
||||||
AddProductResponseModel(
|
AddProductResponseModel(
|
||||||
success: json["success"],
|
success: json["success"],
|
||||||
message: json["message"],
|
|
||||||
data: Product.fromMap(json["data"]),
|
data: Product.fromMap(json["data"]),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
"success": success,
|
"success": success,
|
||||||
"message": message,
|
|
||||||
"data": data.toMap(),
|
"data": data.toMap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,91 +1,120 @@
|
|||||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
class CategroyResponseModel {
|
class CategoryResponseModel {
|
||||||
final String status;
|
final bool success;
|
||||||
final List<CategoryModel> data;
|
final CategoryData data;
|
||||||
|
final dynamic errors;
|
||||||
|
|
||||||
CategroyResponseModel({
|
CategoryResponseModel({
|
||||||
required this.status,
|
required this.success,
|
||||||
required this.data,
|
required this.data,
|
||||||
|
this.errors,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
factory CategoryResponseModel.fromMap(Map<String, dynamic> map) {
|
||||||
return <String, dynamic>{
|
return CategoryResponseModel(
|
||||||
'status': status,
|
success: map['success'] as bool,
|
||||||
'data': data.map((x) => x.toMap()).toList(),
|
data: CategoryData.fromMap(map['data'] as Map<String, dynamic>),
|
||||||
};
|
errors: map['errors'],
|
||||||
}
|
|
||||||
|
|
||||||
factory CategroyResponseModel.fromMap(Map<String, dynamic> map) {
|
|
||||||
return CategroyResponseModel(
|
|
||||||
status: map['status'] as String,
|
|
||||||
data: List<CategoryModel>.from(
|
|
||||||
(map['data']).map<CategoryModel>(
|
|
||||||
(x) => CategoryModel.fromMap(x as Map<String, dynamic>),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory CategroyResponseModel.fromJson(String str) =>
|
factory CategoryResponseModel.fromJson(String str) =>
|
||||||
CategroyResponseModel.fromMap(json.decode(str));
|
CategoryResponseModel.fromMap(json.decode(str));
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
class CategoryModel {
|
|
||||||
int? id;
|
|
||||||
String? name;
|
|
||||||
int? categoryId;
|
|
||||||
int? isSync;
|
|
||||||
String? image;
|
|
||||||
// DateTime createdAt;
|
|
||||||
// DateTime updatedAt;
|
|
||||||
|
|
||||||
CategoryModel({this.id, this.name, this.categoryId, this.isSync, this.image});
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return <String, dynamic>{
|
return {
|
||||||
// 'id': id,
|
'success': success,
|
||||||
'name': name,
|
'data': data.toMap(),
|
||||||
'is_sync': isSync ?? 1,
|
'errors': errors,
|
||||||
'category_id': id,
|
|
||||||
'image': image
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
class CategoryData {
|
||||||
|
final List<CategoryModel> categories;
|
||||||
|
final int totalCount;
|
||||||
|
final int page;
|
||||||
|
final int limit;
|
||||||
|
final int totalPages;
|
||||||
|
|
||||||
|
CategoryData({
|
||||||
|
required this.categories,
|
||||||
|
required this.totalCount,
|
||||||
|
required this.page,
|
||||||
|
required this.limit,
|
||||||
|
required this.totalPages,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory CategoryData.fromMap(Map<String, dynamic> map) {
|
||||||
|
return CategoryData(
|
||||||
|
categories: List<CategoryModel>.from(
|
||||||
|
(map['categories'] as List).map((x) => CategoryModel.fromMap(x)),
|
||||||
|
),
|
||||||
|
totalCount: map['total_count'] as int,
|
||||||
|
page: map['page'] as int,
|
||||||
|
limit: map['limit'] as int,
|
||||||
|
totalPages: map['total_pages'] as int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'categories': categories.map((x) => x.toMap()).toList(),
|
||||||
|
'total_count': totalCount,
|
||||||
|
'page': page,
|
||||||
|
'limit': limit,
|
||||||
|
'total_pages': totalPages,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CategoryModel {
|
||||||
|
String id;
|
||||||
|
final String organizationId;
|
||||||
|
final String name;
|
||||||
|
final String? description;
|
||||||
|
final String businessType;
|
||||||
|
final Map<String, dynamic> metadata;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
|
||||||
|
CategoryModel({
|
||||||
|
required this.id,
|
||||||
|
required this.organizationId,
|
||||||
|
required this.name,
|
||||||
|
this.description,
|
||||||
|
required this.businessType,
|
||||||
|
required this.metadata,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
factory CategoryModel.fromMap(Map<String, dynamic> map) {
|
factory CategoryModel.fromMap(Map<String, dynamic> map) {
|
||||||
return CategoryModel(
|
return CategoryModel(
|
||||||
id: map['id'] as int?,
|
id: map['id'] as String,
|
||||||
name: map['name'] as String?,
|
organizationId: map['organization_id'] as String,
|
||||||
isSync: map['is_sync'] as int?,
|
name: map['name'] as String,
|
||||||
categoryId: map['id'],
|
description: map['description'] as String?,
|
||||||
image: map['image']);
|
businessType: map['business_type'] as String,
|
||||||
|
metadata: Map<String, dynamic>.from(map['metadata'] ?? {}),
|
||||||
|
createdAt: DateTime.parse(map['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(map['updated_at'] as String),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory CategoryModel.fromJson(String str) =>
|
Map<String, dynamic> toMap() {
|
||||||
CategoryModel.fromMap(json.decode(str));
|
return {
|
||||||
|
'id': id,
|
||||||
String toJson() => json.encode(toMap());
|
'organization_id': organizationId,
|
||||||
|
'name': name,
|
||||||
@override
|
'description': description,
|
||||||
bool operator ==(covariant CategoryModel other) {
|
'business_type': businessType,
|
||||||
if (identical(this, other)) return true;
|
'metadata': metadata,
|
||||||
|
'created_at': createdAt.toIso8601String(),
|
||||||
return other.id == id &&
|
'updated_at': updatedAt.toIso8601String(),
|
||||||
other.name == name &&
|
};
|
||||||
other.categoryId == categoryId &&
|
|
||||||
other.isSync == isSync &&
|
|
||||||
other.image == image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return id.hashCode ^
|
|
||||||
name.hashCode ^
|
|
||||||
categoryId.hashCode ^
|
|
||||||
isSync.hashCode ^
|
|
||||||
image.hashCode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
154
lib/data/models/response/file_response_model.dart
Normal file
154
lib/data/models/response/file_response_model.dart
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
class FileResponseModel {
|
||||||
|
final FileModel data;
|
||||||
|
final String message;
|
||||||
|
final bool success;
|
||||||
|
|
||||||
|
FileResponseModel({
|
||||||
|
required this.data,
|
||||||
|
required this.message,
|
||||||
|
required this.success,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory FileResponseModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return FileResponseModel(
|
||||||
|
data: FileModel.fromJson(json['data']),
|
||||||
|
message: json['message'] as String,
|
||||||
|
success: json['success'] as bool,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'data': data.toJson(),
|
||||||
|
'message': message,
|
||||||
|
'success': success,
|
||||||
|
};
|
||||||
|
|
||||||
|
factory FileResponseModel.fromMap(Map<String, dynamic> map) =>
|
||||||
|
FileResponseModel.fromJson(map);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() => toJson();
|
||||||
|
|
||||||
|
FileResponseModel copyWith({
|
||||||
|
FileModel? data,
|
||||||
|
String? message,
|
||||||
|
bool? success,
|
||||||
|
}) {
|
||||||
|
return FileResponseModel(
|
||||||
|
data: data ?? this.data,
|
||||||
|
message: message ?? this.message,
|
||||||
|
success: success ?? this.success,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'FileResponseModel(data: $data, message: $message, success: $success)';
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileModel {
|
||||||
|
final String id;
|
||||||
|
final String organizationId;
|
||||||
|
final String userId;
|
||||||
|
final String fileName;
|
||||||
|
final String originalName;
|
||||||
|
final String fileUrl;
|
||||||
|
final int fileSize;
|
||||||
|
final String mimeType;
|
||||||
|
final String fileType;
|
||||||
|
final String uploadPath;
|
||||||
|
final bool isPublic;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
|
||||||
|
FileModel({
|
||||||
|
required this.id,
|
||||||
|
required this.organizationId,
|
||||||
|
required this.userId,
|
||||||
|
required this.fileName,
|
||||||
|
required this.originalName,
|
||||||
|
required this.fileUrl,
|
||||||
|
required this.fileSize,
|
||||||
|
required this.mimeType,
|
||||||
|
required this.fileType,
|
||||||
|
required this.uploadPath,
|
||||||
|
required this.isPublic,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory FileModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return FileModel(
|
||||||
|
id: json['id'] as String,
|
||||||
|
organizationId: json['organization_id'] as String,
|
||||||
|
userId: json['user_id'] as String,
|
||||||
|
fileName: json['file_name'] as String,
|
||||||
|
originalName: json['original_name'] as String,
|
||||||
|
fileUrl: json['file_url'] as String,
|
||||||
|
fileSize: json['file_size'] as int,
|
||||||
|
mimeType: json['mime_type'] as String,
|
||||||
|
fileType: json['file_type'] as String,
|
||||||
|
uploadPath: json['upload_path'] as String,
|
||||||
|
isPublic: json['is_public'] as bool,
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'id': id,
|
||||||
|
'organization_id': organizationId,
|
||||||
|
'user_id': userId,
|
||||||
|
'file_name': fileName,
|
||||||
|
'original_name': originalName,
|
||||||
|
'file_url': fileUrl,
|
||||||
|
'file_size': fileSize,
|
||||||
|
'mime_type': mimeType,
|
||||||
|
'file_type': fileType,
|
||||||
|
'upload_path': uploadPath,
|
||||||
|
'is_public': isPublic,
|
||||||
|
'created_at': createdAt.toIso8601String(),
|
||||||
|
'updated_at': updatedAt.toIso8601String(),
|
||||||
|
};
|
||||||
|
|
||||||
|
factory FileModel.fromMap(Map<String, dynamic> map) =>
|
||||||
|
FileModel.fromJson(map);
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() => toJson();
|
||||||
|
|
||||||
|
FileModel copyWith({
|
||||||
|
String? id,
|
||||||
|
String? organizationId,
|
||||||
|
String? userId,
|
||||||
|
String? fileName,
|
||||||
|
String? originalName,
|
||||||
|
String? fileUrl,
|
||||||
|
int? fileSize,
|
||||||
|
String? mimeType,
|
||||||
|
String? fileType,
|
||||||
|
String? uploadPath,
|
||||||
|
bool? isPublic,
|
||||||
|
DateTime? createdAt,
|
||||||
|
DateTime? updatedAt,
|
||||||
|
}) {
|
||||||
|
return FileModel(
|
||||||
|
id: id ?? this.id,
|
||||||
|
organizationId: organizationId ?? this.organizationId,
|
||||||
|
userId: userId ?? this.userId,
|
||||||
|
fileName: fileName ?? this.fileName,
|
||||||
|
originalName: originalName ?? this.originalName,
|
||||||
|
fileUrl: fileUrl ?? this.fileUrl,
|
||||||
|
fileSize: fileSize ?? this.fileSize,
|
||||||
|
mimeType: mimeType ?? this.mimeType,
|
||||||
|
fileType: fileType ?? this.fileType,
|
||||||
|
uploadPath: uploadPath ?? this.uploadPath,
|
||||||
|
isPublic: isPublic ?? this.isPublic,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'FileModel(id: $id, organizationId: $organizationId, userId: $userId, fileName: $fileName, originalName: $originalName, fileUrl: $fileUrl, fileSize: $fileSize, mimeType: $mimeType, fileType: $fileType, uploadPath: $uploadPath, isPublic: $isPublic, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'package:enaklo_pos/core/constants/theme.dart';
|
import 'package:enaklo_pos/core/constants/theme.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/customer_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/customer_remote_datasource.dart';
|
||||||
|
import 'package:enaklo_pos/data/datasources/file_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/outlet_remote_data_source.dart';
|
import 'package:enaklo_pos/data/datasources/outlet_remote_data_source.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/table_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/table_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/user_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/user_remote_datasource.dart';
|
||||||
@ -14,6 +15,7 @@ import 'package:enaklo_pos/presentation/home/bloc/user_update_outlet/user_update
|
|||||||
import 'package:enaklo_pos/presentation/refund/bloc/refund_bloc.dart';
|
import 'package:enaklo_pos/presentation/refund/bloc/refund_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/sales/blocs/order_loader/order_loader_bloc.dart';
|
import 'package:enaklo_pos/presentation/sales/blocs/order_loader/order_loader_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/sales/blocs/payment_form/payment_form_bloc.dart';
|
import 'package:enaklo_pos/presentation/sales/blocs/payment_form/payment_form_bloc.dart';
|
||||||
|
import 'package:enaklo_pos/presentation/setting/bloc/upload_file/upload_file_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/void/bloc/void_order_bloc.dart';
|
import 'package:enaklo_pos/presentation/void/bloc/void_order_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
|
||||||
@ -265,6 +267,9 @@ class _MyAppState extends State<MyApp> {
|
|||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => UserUpdateOutletBloc(UserRemoteDatasource()),
|
create: (context) => UserUpdateOutletBloc(UserRemoteDatasource()),
|
||||||
),
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => UploadFileBloc(FileRemoteDataSource()),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
|
||||||
|
|
||||||
part 'add_product_event.dart';
|
part 'add_product_event.dart';
|
||||||
part 'add_product_state.dart';
|
part 'add_product_state.dart';
|
||||||
@ -18,21 +14,12 @@ class AddProductBloc extends Bloc<AddProductEvent, AddProductState> {
|
|||||||
) : super(const _Initial()) {
|
) : super(const _Initial()) {
|
||||||
on<_AddProduct>((event, emit) async {
|
on<_AddProduct>((event, emit) async {
|
||||||
emit(const _Loading());
|
emit(const _Loading());
|
||||||
final requestData = ProductRequestModel(
|
final response = await datasource.addProduct(event.product);
|
||||||
name: event.product.name!,
|
|
||||||
price: event.product.price!,
|
|
||||||
stock: 0,
|
|
||||||
categoryId: 0,
|
|
||||||
isBestSeller: 0,
|
|
||||||
image: event.image,
|
|
||||||
);
|
|
||||||
log("requestData: ${requestData.toString()}");
|
|
||||||
final response = await datasource.addProduct(requestData);
|
|
||||||
// products.add(newProduct);
|
// products.add(newProduct);
|
||||||
response.fold(
|
response.fold(
|
||||||
(l) => emit(_Error(l)),
|
(l) => emit(_Error(l)),
|
||||||
(r) {
|
(r) {
|
||||||
emit(_Success('Add Product Success'));
|
emit(_Success('Produk berhasil ditambahkan'));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -19,19 +19,19 @@ mixin _$AddProductEvent {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() started,
|
required TResult Function() started,
|
||||||
required TResult Function(Product product, XFile image) addProduct,
|
required TResult Function(ProductRequestModel product) addProduct,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? started,
|
TResult? Function()? started,
|
||||||
TResult? Function(Product product, XFile image)? addProduct,
|
TResult? Function(ProductRequestModel product)? addProduct,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? started,
|
TResult Function()? started,
|
||||||
TResult Function(Product product, XFile image)? addProduct,
|
TResult Function(ProductRequestModel product)? addProduct,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -119,7 +119,7 @@ class _$StartedImpl implements _Started {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() started,
|
required TResult Function() started,
|
||||||
required TResult Function(Product product, XFile image) addProduct,
|
required TResult Function(ProductRequestModel product) addProduct,
|
||||||
}) {
|
}) {
|
||||||
return started();
|
return started();
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ class _$StartedImpl implements _Started {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? started,
|
TResult? Function()? started,
|
||||||
TResult? Function(Product product, XFile image)? addProduct,
|
TResult? Function(ProductRequestModel product)? addProduct,
|
||||||
}) {
|
}) {
|
||||||
return started?.call();
|
return started?.call();
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class _$StartedImpl implements _Started {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? started,
|
TResult Function()? started,
|
||||||
TResult Function(Product product, XFile image)? addProduct,
|
TResult Function(ProductRequestModel product)? addProduct,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (started != null) {
|
if (started != null) {
|
||||||
@ -188,7 +188,7 @@ abstract class _$$AddProductImplCopyWith<$Res> {
|
|||||||
_$AddProductImpl value, $Res Function(_$AddProductImpl) then) =
|
_$AddProductImpl value, $Res Function(_$AddProductImpl) then) =
|
||||||
__$$AddProductImplCopyWithImpl<$Res>;
|
__$$AddProductImplCopyWithImpl<$Res>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({Product product, XFile image});
|
$Res call({ProductRequestModel product});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -205,17 +205,12 @@ class __$$AddProductImplCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? product = null,
|
Object? product = null,
|
||||||
Object? image = null,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_$AddProductImpl(
|
return _then(_$AddProductImpl(
|
||||||
null == product
|
null == product
|
||||||
? _value.product
|
? _value.product
|
||||||
: product // ignore: cast_nullable_to_non_nullable
|
: product // ignore: cast_nullable_to_non_nullable
|
||||||
as Product,
|
as ProductRequestModel,
|
||||||
null == image
|
|
||||||
? _value.image
|
|
||||||
: image // ignore: cast_nullable_to_non_nullable
|
|
||||||
as XFile,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,16 +218,14 @@ class __$$AddProductImplCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$AddProductImpl implements _AddProduct {
|
class _$AddProductImpl implements _AddProduct {
|
||||||
const _$AddProductImpl(this.product, this.image);
|
const _$AddProductImpl(this.product);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Product product;
|
final ProductRequestModel product;
|
||||||
@override
|
|
||||||
final XFile image;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AddProductEvent.addProduct(product: $product, image: $image)';
|
return 'AddProductEvent.addProduct(product: $product)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -240,12 +233,11 @@ class _$AddProductImpl implements _AddProduct {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$AddProductImpl &&
|
other is _$AddProductImpl &&
|
||||||
(identical(other.product, product) || other.product == product) &&
|
(identical(other.product, product) || other.product == product));
|
||||||
(identical(other.image, image) || other.image == image));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, product, image);
|
int get hashCode => Object.hash(runtimeType, product);
|
||||||
|
|
||||||
/// Create a copy of AddProductEvent
|
/// Create a copy of AddProductEvent
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -259,29 +251,29 @@ class _$AddProductImpl implements _AddProduct {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() started,
|
required TResult Function() started,
|
||||||
required TResult Function(Product product, XFile image) addProduct,
|
required TResult Function(ProductRequestModel product) addProduct,
|
||||||
}) {
|
}) {
|
||||||
return addProduct(product, image);
|
return addProduct(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function()? started,
|
TResult? Function()? started,
|
||||||
TResult? Function(Product product, XFile image)? addProduct,
|
TResult? Function(ProductRequestModel product)? addProduct,
|
||||||
}) {
|
}) {
|
||||||
return addProduct?.call(product, image);
|
return addProduct?.call(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? started,
|
TResult Function()? started,
|
||||||
TResult Function(Product product, XFile image)? addProduct,
|
TResult Function(ProductRequestModel product)? addProduct,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (addProduct != null) {
|
if (addProduct != null) {
|
||||||
return addProduct(product, image);
|
return addProduct(product);
|
||||||
}
|
}
|
||||||
return orElse();
|
return orElse();
|
||||||
}
|
}
|
||||||
@ -319,11 +311,10 @@ class _$AddProductImpl implements _AddProduct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class _AddProduct implements AddProductEvent {
|
abstract class _AddProduct implements AddProductEvent {
|
||||||
const factory _AddProduct(final Product product, final XFile image) =
|
const factory _AddProduct(final ProductRequestModel product) =
|
||||||
_$AddProductImpl;
|
_$AddProductImpl;
|
||||||
|
|
||||||
Product get product;
|
ProductRequestModel get product;
|
||||||
XFile get image;
|
|
||||||
|
|
||||||
/// Create a copy of AddProductEvent
|
/// Create a copy of AddProductEvent
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
|||||||
@ -3,6 +3,6 @@ part of 'add_product_bloc.dart';
|
|||||||
@freezed
|
@freezed
|
||||||
class AddProductEvent with _$AddProductEvent {
|
class AddProductEvent with _$AddProductEvent {
|
||||||
const factory AddProductEvent.started() = _Started;
|
const factory AddProductEvent.started() = _Started;
|
||||||
const factory AddProductEvent.addProduct(Product product, XFile image) =
|
const factory AddProductEvent.addProduct(ProductRequestModel product) =
|
||||||
_AddProduct;
|
_AddProduct;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/category_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/category_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/category_response_model.dart';
|
import 'package:enaklo_pos/data/models/response/category_response_model.dart';
|
||||||
@ -15,11 +14,11 @@ class GetCategoriesBloc extends Bloc<GetCategoriesEvent, GetCategoriesState> {
|
|||||||
) : super(const _Initial()) {
|
) : super(const _Initial()) {
|
||||||
on<_Fetch>((event, emit) async {
|
on<_Fetch>((event, emit) async {
|
||||||
emit(const _Loading());
|
emit(const _Loading());
|
||||||
final result = await datasource.getCategories();
|
final result = await datasource.getCategories(limit: 50);
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => emit(_Error(l)),
|
(l) => emit(_Error(l)),
|
||||||
(r) async {
|
(r) async {
|
||||||
emit(_Success(r.data));
|
emit(_Success(r.data.categories));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
|
|
||||||
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/product_remote_datasource.dart';
|
||||||
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
import 'package:enaklo_pos/data/models/request/product_request_model.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
|
||||||
|
|
||||||
part 'update_product_event.dart';
|
part 'update_product_event.dart';
|
||||||
part 'update_product_state.dart';
|
part 'update_product_state.dart';
|
||||||
@ -21,61 +18,11 @@ class UpdateProductBloc extends Bloc<UpdateProductEvent, UpdateProductState> {
|
|||||||
emit(const _Loading());
|
emit(const _Loading());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validate required fields
|
final response = await datasource.updateProduct(event.product);
|
||||||
if (event.product.name == null || event.product.name!.isEmpty) {
|
|
||||||
emit(_Error('Product name is required'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.product.price == null || event.product.price == 0) {
|
|
||||||
emit(_Error('Product price is required'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (event.product.stock == null) {
|
|
||||||
// emit(_Error('Product stock is required'));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (event.product.categoryId == null) {
|
|
||||||
emit(_Error('Product category is required'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse price safely
|
|
||||||
final price = event.product.price!;
|
|
||||||
if (price == 0) {
|
|
||||||
emit(_Error('Invalid price format'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final requestData = ProductRequestModel(
|
|
||||||
id: event.product.id,
|
|
||||||
name: event.product.name!,
|
|
||||||
price: price,
|
|
||||||
stock: 0,
|
|
||||||
categoryId: 0,
|
|
||||||
isBestSeller: 0, // Default to 0 if null
|
|
||||||
image: event.image,
|
|
||||||
printerType: 'kitchen', // Default to kitchen if null
|
|
||||||
);
|
|
||||||
|
|
||||||
log("Update requestData: ${requestData.toString()}");
|
|
||||||
log("Request map: ${requestData.toMap()}");
|
|
||||||
|
|
||||||
final response = await datasource.updateProduct(requestData);
|
|
||||||
response.fold(
|
response.fold(
|
||||||
(l) => emit(_Error(l)),
|
(l) => emit(_Error(l)),
|
||||||
(r) async {
|
(r) async {
|
||||||
// Update local database after successful API update
|
emit(_Success('Product berhasil diupdate'));
|
||||||
try {
|
|
||||||
await ProductLocalDatasource.instance
|
|
||||||
.updateProduct(event.product);
|
|
||||||
log("Local product updated successfully");
|
|
||||||
} catch (e) {
|
|
||||||
log("Error updating local product: $e");
|
|
||||||
}
|
|
||||||
emit(_Success('Update Product Success'));
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@ -16,21 +16,20 @@ final _privateConstructorUsedError = UnsupportedError(
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$UpdateProductEvent {
|
mixin _$UpdateProductEvent {
|
||||||
Product get product => throw _privateConstructorUsedError;
|
ProductRequestModel get product => throw _privateConstructorUsedError;
|
||||||
XFile? get image => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function(Product product, XFile? image) updateProduct,
|
required TResult Function(ProductRequestModel product) updateProduct,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function(Product product, XFile? image)? updateProduct,
|
TResult? Function(ProductRequestModel product)? updateProduct,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function(Product product, XFile? image)? updateProduct,
|
TResult Function(ProductRequestModel product)? updateProduct,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@ -64,7 +63,7 @@ abstract class $UpdateProductEventCopyWith<$Res> {
|
|||||||
UpdateProductEvent value, $Res Function(UpdateProductEvent) then) =
|
UpdateProductEvent value, $Res Function(UpdateProductEvent) then) =
|
||||||
_$UpdateProductEventCopyWithImpl<$Res, UpdateProductEvent>;
|
_$UpdateProductEventCopyWithImpl<$Res, UpdateProductEvent>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({Product product, XFile? image});
|
$Res call({ProductRequestModel product});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -83,17 +82,12 @@ class _$UpdateProductEventCopyWithImpl<$Res, $Val extends UpdateProductEvent>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? product = null,
|
Object? product = null,
|
||||||
Object? image = freezed,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
product: null == product
|
product: null == product
|
||||||
? _value.product
|
? _value.product
|
||||||
: product // ignore: cast_nullable_to_non_nullable
|
: product // ignore: cast_nullable_to_non_nullable
|
||||||
as Product,
|
as ProductRequestModel,
|
||||||
image: freezed == image
|
|
||||||
? _value.image
|
|
||||||
: image // ignore: cast_nullable_to_non_nullable
|
|
||||||
as XFile?,
|
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +100,7 @@ abstract class _$$UpdateProductImplCopyWith<$Res>
|
|||||||
__$$UpdateProductImplCopyWithImpl<$Res>;
|
__$$UpdateProductImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({Product product, XFile? image});
|
$Res call({ProductRequestModel product});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -123,17 +117,12 @@ class __$$UpdateProductImplCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? product = null,
|
Object? product = null,
|
||||||
Object? image = freezed,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_$UpdateProductImpl(
|
return _then(_$UpdateProductImpl(
|
||||||
null == product
|
null == product
|
||||||
? _value.product
|
? _value.product
|
||||||
: product // ignore: cast_nullable_to_non_nullable
|
: product // ignore: cast_nullable_to_non_nullable
|
||||||
as Product,
|
as ProductRequestModel,
|
||||||
freezed == image
|
|
||||||
? _value.image
|
|
||||||
: image // ignore: cast_nullable_to_non_nullable
|
|
||||||
as XFile?,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,16 +130,14 @@ class __$$UpdateProductImplCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$UpdateProductImpl implements _UpdateProduct {
|
class _$UpdateProductImpl implements _UpdateProduct {
|
||||||
const _$UpdateProductImpl(this.product, this.image);
|
const _$UpdateProductImpl(this.product);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final Product product;
|
final ProductRequestModel product;
|
||||||
@override
|
|
||||||
final XFile? image;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'UpdateProductEvent.updateProduct(product: $product, image: $image)';
|
return 'UpdateProductEvent.updateProduct(product: $product)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -158,12 +145,11 @@ class _$UpdateProductImpl implements _UpdateProduct {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$UpdateProductImpl &&
|
other is _$UpdateProductImpl &&
|
||||||
(identical(other.product, product) || other.product == product) &&
|
(identical(other.product, product) || other.product == product));
|
||||||
(identical(other.image, image) || other.image == image));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, product, image);
|
int get hashCode => Object.hash(runtimeType, product);
|
||||||
|
|
||||||
/// Create a copy of UpdateProductEvent
|
/// Create a copy of UpdateProductEvent
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -176,27 +162,27 @@ class _$UpdateProductImpl implements _UpdateProduct {
|
|||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function(Product product, XFile? image) updateProduct,
|
required TResult Function(ProductRequestModel product) updateProduct,
|
||||||
}) {
|
}) {
|
||||||
return updateProduct(product, image);
|
return updateProduct(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
TResult? Function(Product product, XFile? image)? updateProduct,
|
TResult? Function(ProductRequestModel product)? updateProduct,
|
||||||
}) {
|
}) {
|
||||||
return updateProduct?.call(product, image);
|
return updateProduct?.call(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function(Product product, XFile? image)? updateProduct,
|
TResult Function(ProductRequestModel product)? updateProduct,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
if (updateProduct != null) {
|
if (updateProduct != null) {
|
||||||
return updateProduct(product, image);
|
return updateProduct(product);
|
||||||
}
|
}
|
||||||
return orElse();
|
return orElse();
|
||||||
}
|
}
|
||||||
@ -231,13 +217,11 @@ class _$UpdateProductImpl implements _UpdateProduct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class _UpdateProduct implements UpdateProductEvent {
|
abstract class _UpdateProduct implements UpdateProductEvent {
|
||||||
const factory _UpdateProduct(final Product product, final XFile? image) =
|
const factory _UpdateProduct(final ProductRequestModel product) =
|
||||||
_$UpdateProductImpl;
|
_$UpdateProductImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Product get product;
|
ProductRequestModel get product;
|
||||||
@override
|
|
||||||
XFile? get image;
|
|
||||||
|
|
||||||
/// Create a copy of UpdateProductEvent
|
/// Create a copy of UpdateProductEvent
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
|||||||
@ -2,5 +2,6 @@ part of 'update_product_bloc.dart';
|
|||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class UpdateProductEvent with _$UpdateProductEvent {
|
class UpdateProductEvent with _$UpdateProductEvent {
|
||||||
const factory UpdateProductEvent.updateProduct(Product product, XFile? image) = _UpdateProduct;
|
const factory UpdateProductEvent.updateProduct(ProductRequestModel product) =
|
||||||
|
_UpdateProduct;
|
||||||
}
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:enaklo_pos/data/datasources/file_remote_datasource.dart';
|
||||||
|
import 'package:enaklo_pos/data/models/response/file_response_model.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'upload_file_event.dart';
|
||||||
|
part 'upload_file_state.dart';
|
||||||
|
part 'upload_file_bloc.freezed.dart';
|
||||||
|
|
||||||
|
class UploadFileBloc extends Bloc<UploadFileEvent, UploadFileState> {
|
||||||
|
final FileRemoteDataSource _fileRemoteDataSource;
|
||||||
|
UploadFileBloc(this._fileRemoteDataSource)
|
||||||
|
: super(UploadFileState.initial()) {
|
||||||
|
on<_Upload>((event, emit) async {
|
||||||
|
emit(_Loading());
|
||||||
|
final result = await _fileRemoteDataSource.uploadFile(
|
||||||
|
filePath: event.filePath,
|
||||||
|
fileType: 'image',
|
||||||
|
description: 'Product Image',
|
||||||
|
);
|
||||||
|
|
||||||
|
result.fold((l) {
|
||||||
|
emit(_Error(l));
|
||||||
|
}, (r) {
|
||||||
|
emit(_Success(r.data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,845 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'upload_file_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$UploadFileEvent {
|
||||||
|
String get filePath => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function(String filePath) upload,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(String filePath)? upload,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function(String filePath)? upload,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Upload value) upload,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Upload value)? upload,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Upload value)? upload,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$UploadFileEventCopyWith<UploadFileEvent> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $UploadFileEventCopyWith<$Res> {
|
||||||
|
factory $UploadFileEventCopyWith(
|
||||||
|
UploadFileEvent value, $Res Function(UploadFileEvent) then) =
|
||||||
|
_$UploadFileEventCopyWithImpl<$Res, UploadFileEvent>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String filePath});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$UploadFileEventCopyWithImpl<$Res, $Val extends UploadFileEvent>
|
||||||
|
implements $UploadFileEventCopyWith<$Res> {
|
||||||
|
_$UploadFileEventCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? filePath = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
filePath: null == filePath
|
||||||
|
? _value.filePath
|
||||||
|
: filePath // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$UploadImplCopyWith<$Res>
|
||||||
|
implements $UploadFileEventCopyWith<$Res> {
|
||||||
|
factory _$$UploadImplCopyWith(
|
||||||
|
_$UploadImpl value, $Res Function(_$UploadImpl) then) =
|
||||||
|
__$$UploadImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({String filePath});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$UploadImplCopyWithImpl<$Res>
|
||||||
|
extends _$UploadFileEventCopyWithImpl<$Res, _$UploadImpl>
|
||||||
|
implements _$$UploadImplCopyWith<$Res> {
|
||||||
|
__$$UploadImplCopyWithImpl(
|
||||||
|
_$UploadImpl _value, $Res Function(_$UploadImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? filePath = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$UploadImpl(
|
||||||
|
null == filePath
|
||||||
|
? _value.filePath
|
||||||
|
: filePath // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$UploadImpl implements _Upload {
|
||||||
|
const _$UploadImpl(this.filePath);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String filePath;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UploadFileEvent.upload(filePath: $filePath)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$UploadImpl &&
|
||||||
|
(identical(other.filePath, filePath) ||
|
||||||
|
other.filePath == filePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, filePath);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$UploadImplCopyWith<_$UploadImpl> get copyWith =>
|
||||||
|
__$$UploadImplCopyWithImpl<_$UploadImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function(String filePath) upload,
|
||||||
|
}) {
|
||||||
|
return upload(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(String filePath)? upload,
|
||||||
|
}) {
|
||||||
|
return upload?.call(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function(String filePath)? upload,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (upload != null) {
|
||||||
|
return upload(filePath);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Upload value) upload,
|
||||||
|
}) {
|
||||||
|
return upload(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Upload value)? upload,
|
||||||
|
}) {
|
||||||
|
return upload?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Upload value)? upload,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (upload != null) {
|
||||||
|
return upload(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Upload implements UploadFileEvent {
|
||||||
|
const factory _Upload(final String filePath) = _$UploadImpl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get filePath;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$UploadImplCopyWith<_$UploadImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$UploadFileState {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() loading,
|
||||||
|
required TResult Function(FileModel file) success,
|
||||||
|
required TResult Function(String message) error,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? initial,
|
||||||
|
TResult? Function()? loading,
|
||||||
|
TResult? Function(FileModel file)? success,
|
||||||
|
TResult? Function(String message)? error,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? loading,
|
||||||
|
TResult Function(FileModel file)? success,
|
||||||
|
TResult Function(String message)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_Loading value) loading,
|
||||||
|
required TResult Function(_Success value) success,
|
||||||
|
required TResult Function(_Error value) error,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Initial value)? initial,
|
||||||
|
TResult? Function(_Loading value)? loading,
|
||||||
|
TResult? Function(_Success value)? success,
|
||||||
|
TResult? Function(_Error value)? error,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_Loading value)? loading,
|
||||||
|
TResult Function(_Success value)? success,
|
||||||
|
TResult Function(_Error value)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $UploadFileStateCopyWith<$Res> {
|
||||||
|
factory $UploadFileStateCopyWith(
|
||||||
|
UploadFileState value, $Res Function(UploadFileState) then) =
|
||||||
|
_$UploadFileStateCopyWithImpl<$Res, UploadFileState>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$UploadFileStateCopyWithImpl<$Res, $Val extends UploadFileState>
|
||||||
|
implements $UploadFileStateCopyWith<$Res> {
|
||||||
|
_$UploadFileStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$InitialImplCopyWith<$Res> {
|
||||||
|
factory _$$InitialImplCopyWith(
|
||||||
|
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
|
||||||
|
__$$InitialImplCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$InitialImplCopyWithImpl<$Res>
|
||||||
|
extends _$UploadFileStateCopyWithImpl<$Res, _$InitialImpl>
|
||||||
|
implements _$$InitialImplCopyWith<$Res> {
|
||||||
|
__$$InitialImplCopyWithImpl(
|
||||||
|
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$InitialImpl implements _Initial {
|
||||||
|
const _$InitialImpl();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UploadFileState.initial()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$InitialImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() loading,
|
||||||
|
required TResult Function(FileModel file) success,
|
||||||
|
required TResult Function(String message) error,
|
||||||
|
}) {
|
||||||
|
return initial();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? initial,
|
||||||
|
TResult? Function()? loading,
|
||||||
|
TResult? Function(FileModel file)? success,
|
||||||
|
TResult? Function(String message)? error,
|
||||||
|
}) {
|
||||||
|
return initial?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? loading,
|
||||||
|
TResult Function(FileModel file)? success,
|
||||||
|
TResult Function(String message)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (initial != null) {
|
||||||
|
return initial();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_Loading value) loading,
|
||||||
|
required TResult Function(_Success value) success,
|
||||||
|
required TResult Function(_Error value) error,
|
||||||
|
}) {
|
||||||
|
return initial(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Initial value)? initial,
|
||||||
|
TResult? Function(_Loading value)? loading,
|
||||||
|
TResult? Function(_Success value)? success,
|
||||||
|
TResult? Function(_Error value)? error,
|
||||||
|
}) {
|
||||||
|
return initial?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_Loading value)? loading,
|
||||||
|
TResult Function(_Success value)? success,
|
||||||
|
TResult Function(_Error value)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (initial != null) {
|
||||||
|
return initial(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Initial implements UploadFileState {
|
||||||
|
const factory _Initial() = _$InitialImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$LoadingImplCopyWith<$Res> {
|
||||||
|
factory _$$LoadingImplCopyWith(
|
||||||
|
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
|
||||||
|
__$$LoadingImplCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$LoadingImplCopyWithImpl<$Res>
|
||||||
|
extends _$UploadFileStateCopyWithImpl<$Res, _$LoadingImpl>
|
||||||
|
implements _$$LoadingImplCopyWith<$Res> {
|
||||||
|
__$$LoadingImplCopyWithImpl(
|
||||||
|
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$LoadingImpl implements _Loading {
|
||||||
|
const _$LoadingImpl();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UploadFileState.loading()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$LoadingImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() loading,
|
||||||
|
required TResult Function(FileModel file) success,
|
||||||
|
required TResult Function(String message) error,
|
||||||
|
}) {
|
||||||
|
return loading();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? initial,
|
||||||
|
TResult? Function()? loading,
|
||||||
|
TResult? Function(FileModel file)? success,
|
||||||
|
TResult? Function(String message)? error,
|
||||||
|
}) {
|
||||||
|
return loading?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? loading,
|
||||||
|
TResult Function(FileModel file)? success,
|
||||||
|
TResult Function(String message)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (loading != null) {
|
||||||
|
return loading();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_Loading value) loading,
|
||||||
|
required TResult Function(_Success value) success,
|
||||||
|
required TResult Function(_Error value) error,
|
||||||
|
}) {
|
||||||
|
return loading(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Initial value)? initial,
|
||||||
|
TResult? Function(_Loading value)? loading,
|
||||||
|
TResult? Function(_Success value)? success,
|
||||||
|
TResult? Function(_Error value)? error,
|
||||||
|
}) {
|
||||||
|
return loading?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_Loading value)? loading,
|
||||||
|
TResult Function(_Success value)? success,
|
||||||
|
TResult Function(_Error value)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (loading != null) {
|
||||||
|
return loading(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Loading implements UploadFileState {
|
||||||
|
const factory _Loading() = _$LoadingImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$SuccessImplCopyWith<$Res> {
|
||||||
|
factory _$$SuccessImplCopyWith(
|
||||||
|
_$SuccessImpl value, $Res Function(_$SuccessImpl) then) =
|
||||||
|
__$$SuccessImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({FileModel file});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$SuccessImplCopyWithImpl<$Res>
|
||||||
|
extends _$UploadFileStateCopyWithImpl<$Res, _$SuccessImpl>
|
||||||
|
implements _$$SuccessImplCopyWith<$Res> {
|
||||||
|
__$$SuccessImplCopyWithImpl(
|
||||||
|
_$SuccessImpl _value, $Res Function(_$SuccessImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? file = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$SuccessImpl(
|
||||||
|
null == file
|
||||||
|
? _value.file
|
||||||
|
: file // ignore: cast_nullable_to_non_nullable
|
||||||
|
as FileModel,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$SuccessImpl implements _Success {
|
||||||
|
const _$SuccessImpl(this.file);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final FileModel file;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UploadFileState.success(file: $file)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$SuccessImpl &&
|
||||||
|
(identical(other.file, file) || other.file == file));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, file);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$SuccessImplCopyWith<_$SuccessImpl> get copyWith =>
|
||||||
|
__$$SuccessImplCopyWithImpl<_$SuccessImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() loading,
|
||||||
|
required TResult Function(FileModel file) success,
|
||||||
|
required TResult Function(String message) error,
|
||||||
|
}) {
|
||||||
|
return success(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? initial,
|
||||||
|
TResult? Function()? loading,
|
||||||
|
TResult? Function(FileModel file)? success,
|
||||||
|
TResult? Function(String message)? error,
|
||||||
|
}) {
|
||||||
|
return success?.call(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? loading,
|
||||||
|
TResult Function(FileModel file)? success,
|
||||||
|
TResult Function(String message)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (success != null) {
|
||||||
|
return success(file);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_Loading value) loading,
|
||||||
|
required TResult Function(_Success value) success,
|
||||||
|
required TResult Function(_Error value) error,
|
||||||
|
}) {
|
||||||
|
return success(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Initial value)? initial,
|
||||||
|
TResult? Function(_Loading value)? loading,
|
||||||
|
TResult? Function(_Success value)? success,
|
||||||
|
TResult? Function(_Error value)? error,
|
||||||
|
}) {
|
||||||
|
return success?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_Loading value)? loading,
|
||||||
|
TResult Function(_Success value)? success,
|
||||||
|
TResult Function(_Error value)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (success != null) {
|
||||||
|
return success(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Success implements UploadFileState {
|
||||||
|
const factory _Success(final FileModel file) = _$SuccessImpl;
|
||||||
|
|
||||||
|
FileModel get file;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$SuccessImplCopyWith<_$SuccessImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$ErrorImplCopyWith<$Res> {
|
||||||
|
factory _$$ErrorImplCopyWith(
|
||||||
|
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
|
||||||
|
__$$ErrorImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({String message});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$ErrorImplCopyWithImpl<$Res>
|
||||||
|
extends _$UploadFileStateCopyWithImpl<$Res, _$ErrorImpl>
|
||||||
|
implements _$$ErrorImplCopyWith<$Res> {
|
||||||
|
__$$ErrorImplCopyWithImpl(
|
||||||
|
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? message = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$ErrorImpl(
|
||||||
|
null == message
|
||||||
|
? _value.message
|
||||||
|
: message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$ErrorImpl implements _Error {
|
||||||
|
const _$ErrorImpl(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UploadFileState.error(message: $message)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$ErrorImpl &&
|
||||||
|
(identical(other.message, message) || other.message == message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, message);
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
|
||||||
|
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() loading,
|
||||||
|
required TResult Function(FileModel file) success,
|
||||||
|
required TResult Function(String message) error,
|
||||||
|
}) {
|
||||||
|
return error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? initial,
|
||||||
|
TResult? Function()? loading,
|
||||||
|
TResult? Function(FileModel file)? success,
|
||||||
|
TResult? Function(String message)? error,
|
||||||
|
}) {
|
||||||
|
return error?.call(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? loading,
|
||||||
|
TResult Function(FileModel file)? success,
|
||||||
|
TResult Function(String message)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (error != null) {
|
||||||
|
return error(message);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_Loading value) loading,
|
||||||
|
required TResult Function(_Success value) success,
|
||||||
|
required TResult Function(_Error value) error,
|
||||||
|
}) {
|
||||||
|
return error(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_Initial value)? initial,
|
||||||
|
TResult? Function(_Loading value)? loading,
|
||||||
|
TResult? Function(_Success value)? success,
|
||||||
|
TResult? Function(_Error value)? error,
|
||||||
|
}) {
|
||||||
|
return error?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_Loading value)? loading,
|
||||||
|
TResult Function(_Success value)? success,
|
||||||
|
TResult Function(_Error value)? error,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (error != null) {
|
||||||
|
return error(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Error implements UploadFileState {
|
||||||
|
const factory _Error(final String message) = _$ErrorImpl;
|
||||||
|
|
||||||
|
String get message;
|
||||||
|
|
||||||
|
/// Create a copy of UploadFileState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
part of 'upload_file_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class UploadFileEvent with _$UploadFileEvent {
|
||||||
|
const factory UploadFileEvent.upload(String filePath) = _Upload;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
part of 'upload_file_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class UploadFileState with _$UploadFileState {
|
||||||
|
const factory UploadFileState.initial() = _Initial;
|
||||||
|
const factory UploadFileState.loading() = _Loading;
|
||||||
|
const factory UploadFileState.success(FileModel file) = _Success;
|
||||||
|
const factory UploadFileState.error(String message) = _Error;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -58,18 +58,18 @@ class _SyncDataPageState extends State<SyncDataPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loaded: (productResponseModel) async {
|
loaded: (productResponseModel) async {
|
||||||
await ProductLocalDatasource.instance
|
// await ProductLocalDatasource.instance
|
||||||
.deleteAllProducts();
|
// .deleteAllProducts();
|
||||||
await ProductLocalDatasource.instance
|
// await ProductLocalDatasource.instance
|
||||||
.insertProducts(
|
// .insertProducts(
|
||||||
productResponseModel.data!.products!,
|
// productResponseModel.data!.products!,
|
||||||
);
|
// );
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
// const SnackBar(
|
||||||
content: Text('Sync Product Success2'),
|
// content: Text('Sync Product Success2'),
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: Colors.green,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -127,12 +127,12 @@ class _SyncDataPageState extends State<SyncDataPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
loaded: () {
|
loaded: () {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
// const SnackBar(
|
||||||
content: Text('Sync Order Success'),
|
// content: Text('Sync Order Success'),
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: Colors.green,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -366,6 +366,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
dropdown_search:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dropdown_search
|
||||||
|
sha256: "55106e8290acaa97ed15bea1fdad82c3cf0c248dd410e651f5a8ac6870f783ab"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.6"
|
||||||
esc_pos_utils_plus:
|
esc_pos_utils_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -62,6 +62,7 @@ dependencies:
|
|||||||
dio: ^5.8.0+1
|
dio: ^5.8.0+1
|
||||||
awesome_dio_interceptor: ^1.3.0
|
awesome_dio_interceptor: ^1.3.0
|
||||||
another_flushbar: ^1.12.30
|
another_flushbar: ^1.12.30
|
||||||
|
dropdown_search: ^5.0.6
|
||||||
# imin_printer: ^0.6.10
|
# imin_printer: ^0.6.10
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user