Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions src/backend/functions/src/system/fakeDataPopulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import * as faker from 'faker';

// enable short hand for console.log()
function log(message: string) { console.log(`FakeDataPopulator | ${message}`); }

const FAKE_REGION_NAME = 'cape-town'
const NUMBER_OF_FAKE_MERCHANTS = 10
const NUMBER_OF_FAKE_PRODUCTS_PER_MERCHANTS = 30
const MERCHANTS_COLLECTION = 'merchants'
const REGIONS_COLLECTION = 'regions'
const PRODUCTS_COLLECTION = 'products'
/**
* A class that helps with populating a local firestore database
*/
Expand Down Expand Up @@ -35,16 +40,20 @@ export class FakeDataPopulator {
private async generateRegions() {
log('generateRegions');

await this.firestoreDatabase.collection('regions').doc('cape-town').set({});
await this.firestoreDatabase.collection(REGIONS_COLLECTION).doc(FAKE_REGION_NAME).set({});
}

private async generateMerchants() {
log('generateMerchants');

for (let index = 0; index < 30; index++) {
for (let index = 0; index < NUMBER_OF_FAKE_MERCHANTS; index++) {
let merchant = {
'name': faker.commerce.productName(),
'image': faker.image.imageUrl(640, 640, 'food'),
'images': [
faker.image.imageUrl(1024, 640, 'food',true),
faker.image.imageUrl(1024, 640, 'food',true),
faker.image.imageUrl(1024, 640, 'food',true),
],
'categories': [
faker.commerce.department(),
faker.commerce.department()
Expand All @@ -53,15 +62,16 @@ export class FakeDataPopulator {
'numberOfRatings': faker.datatype.number(200),
};

let merchantId = await this.createMerchantDocument(merchant);
let merchantId =
await this.createMerchantDocumentForSpecificRegion(merchant, FAKE_REGION_NAME);
await this.generateMerchantsProducts(merchantId);
}
}

private async generateMerchantsProducts(merchatId: string) {
log(`generateMerchantsProducts merchatId:${merchatId}`);
private async generateMerchantsProducts(merchantId: string) {
log(`generateMerchantsProducts merchatId:${merchantId}`);

for (let index = 0; index < 30; index++) {
for (let index = 0; index < NUMBER_OF_FAKE_PRODUCTS_PER_MERCHANTS; index++) {
let product = {
'name': faker.commerce.productName(),
'description': faker.lorem.paragraph(2),
Expand All @@ -70,17 +80,16 @@ export class FakeDataPopulator {
'price': faker.datatype.number(8999),
};

await this.createMerchantProduct(merchatId, product);
await this.createMerchantProductForSpecificRegion(merchantId, product);
}
}

private async createMerchantProduct(merchantId: string, product: any) {
await this.firestoreDatabase.collection('merchants').doc(merchantId).collection('products').add(product);
private async createMerchantDocumentForSpecificRegion(merchant: any, regionId: string): Promise<string> {
let documentReference = await this.firestoreDatabase.collection(REGIONS_COLLECTION).doc(regionId).collection(MERCHANTS_COLLECTION).add(merchant);
return documentReference.id;
}

private async createMerchantDocument(merchant: any): Promise<string> {
let documentReference = await this.firestoreDatabase.collection('merchants').add(merchant);
return documentReference.id;
private async createMerchantProductForSpecificRegion(merchantId: string, product: any) {
await this.firestoreDatabase.collection(REGIONS_COLLECTION).doc(FAKE_REGION_NAME).collection(MERCHANTS_COLLECTION).doc(merchantId).collection(PRODUCTS_COLLECTION).add(product)
}

private async createGenerateDocument(): Promise<void> {
Expand All @@ -91,4 +100,5 @@ export class FakeDataPopulator {
private getGenerateDocument(): firestore.DocumentReference {
return this.firestoreDatabase.collection('data').doc('generate');
}

}
35 changes: 35 additions & 0 deletions src/clients/box_ui/example/lib/example_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,46 @@ class ExampleView extends StatelessWidget {
...buttonWidgets,
...textWidgets,
...inputFields,
...largeRestaurantItems,
],
),
);
}

List<Widget> get largeRestaurantItems => [
verticalSpaceLarge,
BoxText.headline('LargeMerchantItem'),
verticalSpaceMedium,
LargeMerchantItem(
name: 'McDonald',
images: [
'https://baconmockup.com/640/360',
'https://baconmockup.com/641/360',
'https://baconmockup.com/639/360',
'https://baconmockup.com/638/360'
],
categories: ['Arabic', 'Turkish', 'Chinese'],
deliveryCost: 4.2,
deliveryInMinutes: 26,
rating: 3.4,
numberOfRatings: 41,
),
verticalSpaceMedium,
LargeMerchantItem(
name: 'McDonald',
images: [
'https://baconmockup.com/640/360',
'https://baconmockup.com/641/360',
'https://baconmockup.com/639/360',
'https://baconmockup.com/638/360'
],
categories: ['Arabic', 'Turkish', 'Chinese'],
deliveryCost: 0,
deliveryInMinutes: 26,
rating: 3.4,
numberOfRatings: 41,
)
];
List<Widget> get textWidgets => [
BoxText.headline('Text Styles'),
verticalSpaceMedium,
Expand Down
1 change: 1 addition & 0 deletions src/clients/box_ui/lib/box_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export 'src/widgets/box_text.dart';
export 'src/widgets/box_button.dart';
export 'src/widgets/box_input_field.dart';
export 'src/widgets/autocomplete_listItem.dart';
export 'src/widgets/large_merchants_item.dart';

// Colors Export
export 'src/shared/app_colors.dart';
Expand Down
2 changes: 2 additions & 0 deletions src/clients/box_ui/lib/src/shared/app_colors.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';

const Color kcPrimaryColor = Color(0xff22A45D);
const Color kcDeepGreyColor = Color(0xff010F07);
const Color kcMediumGreyColor = Color(0xff868686);
const Color kcSemiLightColor = Color(0xffD8D8D8);
const Color kcLightGreyColor = Color(0xffe5e5e5);
const Color kcVeryLightGreyColor = Color(0xfff2f2f2);
3 changes: 2 additions & 1 deletion src/clients/box_ui/lib/src/shared/ui_helpers.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Horizontal Spacing
import 'package:flutter/material.dart';

const Widget horizontalSpaceTiny = SizedBox(width: 5.0);
Expand All @@ -23,3 +22,5 @@ double screenHeightPercentage(BuildContext context, {double percentage = 1}) =>

double screenWidthPercentage(BuildContext context, {double percentage = 1}) =>
screenWidth(context) * percentage;

const double screenHorizontalPadding = 16;
96 changes: 96 additions & 0 deletions src/clients/box_ui/lib/src/widgets/large_merchants_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import 'package:box_ui/box_ui.dart';
import 'package:box_ui/src/shared/styles.dart';
import 'package:flutter/material.dart';

import 'large_merchants_item_images_carousel.dart';

class LargeMerchantItem extends StatelessWidget {
final List<String> images;
final String name;
final List<String> categories;
final double? rating;
final int? numberOfRatings;
final int? deliveryInMinutes;
final double? deliveryCost;
final bool isClosed;

const LargeMerchantItem(
{Key? key,
required this.images,
required this.name,
required this.categories,
this.deliveryInMinutes,
this.deliveryCost,
this.rating,
this.numberOfRatings,
this.isClosed = false})
: super(key: key);

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LargeMerchantsItemImagesCarsouel(
images: images,
),
verticalSpaceSmall,
BoxText.subheading(name),
verticalSpaceTiny,
BoxText.body(
categories.join(' • '),
color: kcMediumGreyColor,
),
verticalSpaceSmall,
Row(
children: [
if (rating != null) ...[
BoxText.caption(
rating.toString(),
),
horizontalSpaceTiny,
Icon(
Icons.star_rounded,
color: kcPrimaryColor,
size: 15,
),
horizontalSpaceTiny,
BoxText.caption(
numberOfRatings.toString() + ' Ratings',
),
horizontalSpaceTiny,
],
if (deliveryInMinutes != null) ...[
Icon(
Icons.watch_later_rounded,
color: Colors.black.withOpacity(0.6),
size: 15,
),
horizontalSpaceTiny,
BoxText.caption(
deliveryInMinutes.toString() + ' Min',
),
horizontalSpaceTiny,
],
if (deliveryCost != null) ...[
BoxText.body(
'•',
color: kcMediumGreyColor.withOpacity(0.5),
),
horizontalSpaceTiny,
Icon(
Icons.attach_money_rounded,
color: kcMediumGreyColor,
size: 15,
),
horizontalSpaceTiny,
BoxText.caption(
deliveryCost == 0.0 ? 'Free' : deliveryCost.toString(),
),
]
],
)
],
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'package:box_ui/src/shared/app_colors.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';

class LargeMerchantsItemImagesCarsouel extends StatefulWidget {
final List<String> images;
const LargeMerchantsItemImagesCarsouel({Key? key, required this.images})
: super(key: key);

@override
_LargeMerchantsItemImagesCarsouelState createState() =>
_LargeMerchantsItemImagesCarsouelState();
}

class _LargeMerchantsItemImagesCarsouelState
extends State<LargeMerchantsItemImagesCarsouel> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: CarouselSlider(
items: widget.images
.map((imageUrl) => Container(
width: double.infinity,
color: kcLightGreyColor,
child: Image.network(
imageUrl,
fit: BoxFit.cover,
),
))
.toList(),
options: CarouselOptions(
aspectRatio: 1.8,
viewportFraction: 1,
onPageChanged: (currentPageIndex, _) {
setState(() {
_currentIndex = currentPageIndex;
});
})),
),
Positioned(
bottom: 20,
right: 20,
child: Row(
children: [
...widget.images.asMap().entries.map((map) => Container(
margin: const EdgeInsets.only(right: 8),
width: 8,
height: 5,
decoration: BoxDecoration(
color: Colors.white
.withOpacity(_currentIndex == map.key ? 1 : 0.3),
borderRadius: BorderRadius.circular(32)),
))
],
),
),
],
);
}
}
2 changes: 1 addition & 1 deletion src/clients/box_ui/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ environment:
dependencies:
flutter:
sdk: flutter

carousel_slider: ^4.0.0
dev_dependencies:
flutter_test:
sdk: flutter
Expand Down
27 changes: 27 additions & 0 deletions src/clients/customer/lib/api/firestore_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,31 @@ class FirestoreApi {
CollectionReference getAddressCollectionForUser(String userId) {
return usersCollection.doc(userId).collection(AddressesFirestoreKey);
}

Future<List<Merchant>> getMerchantsCollectionForRegion(
{required String regionId}) async {
log.i('regionId:$regionId');
try {
final regionCollections =
await regionsCollection.doc(regionId).collection('merchants').get();
if (regionCollections.docs.isEmpty) {
log.v('We have no merchants in this region');
return [];
}

final regionCollectionsDocuments = regionCollections.docs;
log.v(
'for regionId: $regionId, Merchants fetched: $regionCollectionsDocuments');
List<Merchant> merchants = regionCollectionsDocuments.map((merchant) {
var data = merchant.data();
data.putIfAbsent('id', () => merchant.id);
return Merchant.fromJson(data);
}).toList();
return merchants;
} catch (error) {
throw FirestoreApiException(
message:
'An error ocurred while calling getMerchantsCollectionForRegion(): $error');
}
}
}
16 changes: 15 additions & 1 deletion src/clients/customer/lib/models/application_models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class User with _$User {
}

@freezed
abstract class Address with _$Address {
class Address with _$Address {
factory Address({
String? id,
required String placeId,
Expand All @@ -34,3 +34,17 @@ abstract class Address with _$Address {
factory Address.fromJson(Map<String, dynamic> json) =>
_$AddressFromJson(json);
}

@freezed
class Merchant with _$Merchant {
factory Merchant(
{required String id,
List<String>? categories,
List<String>? images,
String? name,
int? numberOfRatings,
double? rating}) = _Merchant;

factory Merchant.fromJson(Map<String, dynamic> json) =>
_$MerchantFromJson(json);
}
Loading