Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Binary file added Final_Result/add_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final_Result/cart_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final_Result/detail_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final_Result/filled_add_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Final_Result/main_page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 5 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,6 @@
# Task 3 - Book Store App
# Unicoding bootcamp - Book Store App

Task resolution process:

- Fork the repo
- Clone the forked repo to your local machine
- Resolve the task
- Commit your solution
- Push to GitHub
- create a pull request



### Task 3:
Build a book store mobile application. The store contain a list of available books with the ability to add custom books to the store as well as view, order them.

* Don't use pre-made widgets (packges).
* It's ok to use icons packages.
* Use Getx for state management.

## UI
### Main Page
The main page should contain a list of the available books. When tapping on a book, the second page (Book Details Page) will be navigated. Use Scrollable view for the list of books. ALso there is a simple search on the top of the page.


### Cart Page (Optional)
This page can view the ordered books.

### Details Page
This have the details of the book which is:
- Book name
- Author
- Desciption
- Image
- Rate (constant)

### Add Page
It is the page where you can add new books to the store.

## FLow
1. Build the UI (from figma design).
2. seperate the widgets to small and organized files.
3. Build models that contain the book data (You can build one model or more).
4. Try to seperate the logic (Functions and data) from the UI.

## Figma Design
https://www.figma.com/file/4BGkiFfTPT7b8K9pyFTBD6/Online-Book-Store-App-(2019)-(Community)?node-id=0%3A1
<p float="left">
<img src="https://github.com/Aya-Jafar/book_store_app/blob/master/WM-Screenshots-20220827212746.png" />
<img src="https://github.com/Aya-Jafar/book_store_app/blob/master/WM-Screenshots-20220827220411.png" />
</p>
Binary file added WM-Screenshots-20220827212746.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WM-Screenshots-20220827220411.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Vector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/article.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/msg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/pro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 5 additions & 6 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:book_store_app/views/main_page/home_page.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
runApp(const MyApp());
Expand All @@ -9,12 +11,9 @@ class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text("Book Store App"),
),
),
return const GetMaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
59 changes: 59 additions & 0 deletions lib/models/book_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:get/get.dart';

class Book {
String name;
String author;
double rate;
String description;
String price;

String? imgLink;

Book({
required this.name,
required this.author,
required this.description,
required String price,
String? imgLink,
}) : imgLink = (imgLink == null)
? 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Book-icon-bible.png/640px-Book-icon-bible.png'
: imgLink,
rate = 4.5,
price = '\$$price';

static RxList<Book> allBooks = <Book>[
Book(
name: 'Yves Saint Laurent',
author: 'Suzy Menkes',
price: '46.99',
imgLink:
'https://images-na.ssl-images-amazon.com/images/I/21KbioZVBDL._SX340_BO1,204,203,200_.jpg',
description:
"A spectacular visual journey through 40 years of haute couture from one of the best-known and most trend-setting brands in fashion."),
Book(
name: 'The Book of Signs',
author: 'Rudolf Koch',
price: '99.99',
description:
'A spectacular visual journey through 40 years of haute couture from one of the best-known and most trend-setting brands in fashion.',
imgLink:
'http://kbimages1-a.akamaihd.net/Images/0f23bd7a-4b80-49e8-a086-25fae5674dc4/255/400/False/image.jpg')
].obs;

static void addBook(
{required name,
required author,
required description,
required price,
String? imgLink}) {
allBooks.add(Book(
name: name,
author: author,
description: description,
price: price,
imgLink: imgLink));
}

static RxList<Book> addedToCardBooks = <Book>[].obs;
static RxBool isFiltered = false.obs;
}
103 changes: 103 additions & 0 deletions lib/views/adding_page/adding_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../models/book_model.dart';
import '../common_widgets/app_bar.dart';
import 'book_info_textfield.dart';

class BookBuilder extends StatelessWidget {
BookBuilder({Key? key}) : super(key: key);

final TextEditingController bookNameController = TextEditingController();
final TextEditingController authorController = TextEditingController();
final TextEditingController priceController = TextEditingController();
final TextEditingController imgController = TextEditingController();
final TextEditingController descController = TextEditingController();

@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Color.fromARGB(255, 245, 245, 245),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
child: ListView(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const MyAppBar(),
SizedBox(
height: 30,
),
Row(
children: [
Text('Add Book',
style:
TextStyle(fontSize: 24, fontWeight: FontWeight.w600)),
],
),
SizedBox(
height: 30,
),
BookInfoTextField(
controller: bookNameController, text: 'Book Name'),
BookInfoTextField(
controller: authorController, text: 'Author Name'),
BookInfoTextField(controller: priceController, text: 'Price'),
BookInfoTextField(controller: imgController, text: 'Image Link'),
TextField(
minLines: 4,
maxLines: 5,
controller: descController,
decoration: InputDecoration(
hintText: 'Desciption',
filled: true,
fillColor: Color.fromARGB(235, 252, 252, 252),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide.none,
),
),
),
SizedBox(
height: 15,
),
Container(
width: 285,
height: 60,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(22)),
child: ElevatedButton(
child: Text('Add'),
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(22.0),
)),
backgroundColor:
MaterialStateProperty.all(Colors.black)),
onPressed: () {
if ([
bookNameController.text,
authorController.text,
descController.text,
priceController.text
].every((element) => element.isNotEmpty)) {
Book.addBook(
name: bookNameController.text,
author: authorController.text,
description: descController.text,
imgLink: imgController.text,
price: priceController.text);
}
Get.back();
},
))
],
),
),
),
);
}
}
32 changes: 32 additions & 0 deletions lib/views/adding_page/book_info_textfield.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';

class BookInfoTextField extends StatelessWidget {
const BookInfoTextField({
Key? key,
required this.controller,
required this.text,
}) : super(key: key);

final String text;
final TextEditingController controller;

@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 20),
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: text,
hintStyle: TextStyle(color: Color(0xff84889E)),
filled: true,
fillColor: Color.fromARGB(235, 252, 252, 252),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide.none,
),
),
),
);
}
}
45 changes: 45 additions & 0 deletions lib/views/book_datail/book_info_column.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';

import '../../models/book_model.dart';

class BookInfo extends StatelessWidget {
const BookInfo({
Key? key,
required this.book,
}) : super(key: key);

final Book book;

@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
width: 216,
height: 320,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(book.imgLink!),
),
borderRadius: BorderRadius.circular(10)),
),
const SizedBox(
height: 15,
),
Text(book.name,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(
height: 7,
),
Text(book.author,
style: const TextStyle(
fontSize: 14,
color: const Color.fromARGB(255, 101, 101, 101))),
],
);
}
}
29 changes: 29 additions & 0 deletions lib/views/book_datail/button_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';

class ButtonBuilder extends StatelessWidget {
final IconData icon;
final String text;

const ButtonBuilder({Key? key, required this.icon, required this.text})
: super(key: key);

@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(154, 40),
primary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(icon, color: Colors.black),
Text(text, style: TextStyle(color: Colors.black))
],
));
}
}
Loading