Home Garden App Development Project
Home Garden App Development Project
Supervision
Dr. Anand Deva Durai C
ii
Abstract
The Home Garden App (Green Thumb) is a mobile application designed to assist users
in planting and caring for plants at home. It offers a variety of features, including a planting
calendar, plant care tips, plant growth tracking, plant identification, a rich plant database,
a personal plant library, disease and pest diagnosis, plant care reminders, and guidance on
preparing and maintaining a home garden. The app is designed to be user-friendly and
intuitive, with a clean interface that displays plant information, gardening tips, and other
relevant data.
iii
Table of Contents
Acknowledgement .............................................................................................................. ii
Abstract .............................................................................................................................. iii
Table of Contents ............................................................................................................... iv
List of Tables ..................................................................................................................... vi
List of Figures ................................................................................................................... vii
Chapter (1): Introduction .................................................................................................... 1
1.1 Aim of the Project ................................................................................................ 1
1.2 Project Scope ........................................................................................................ 2
1.3 Objectives ............................................................................................................. 2
1.4 Problem Definition ............................................................................................... 2
1.5 Proposed Solution ................................................................................................ 3
1.6 Project Plan .......................................................................................................... 4
Chapter (2): Literature Review ........................................................................................... 6
2.1 General Overview ................................................................................................ 6
2.2 Similar Systems .................................................................................................... 7
2.2.1 PlantNet ........................................................................................................... 7
2.2.2 Planter Garden Planner .................................................................................... 8
2.2.3 iNaturalist ........................................................................................................ 9
2.2.4 Planta ............................................................................................................. 10
2.3 Systems’ Comparison ......................................................................................... 11
2.4 Limitations ......................................................................................................... 12
2.5 Features of the Proposed System ....................................................................... 13
Chapter (3): System Analysis ........................................................................................... 14
3.1 Technical Requirements ..................................................................................... 14
3.1.1 Hardware Requirements ................................................................................ 14
3.1.2 Software Requirements ................................................................................. 15
3.2 Functional Requirements.................................................................................... 15
3.3 Non-Functional Requirements ........................................................................... 16
3.4 Logic Steps of the Flowchart ............................................................................. 18
3.5 Plant Identification Algorithm ........................................................................... 19
Chapter (4): System Design .............................................................................................. 20
4.1 Requirement Elicitation...................................................................................... 20
4.2 Personas .............................................................................................................. 21
4.3 System Models ................................................................................................... 22
4.3.1 Use Case Diagram ......................................................................................... 22
4.3.2 Sequence Diagram ......................................................................................... 22
4.3.3 Activity Diagram ........................................................................................... 25
iv
4.3.4 Class Diagram ............................................................................................... 26
4.4 Product Features ................................................................................................. 27
4.5 User Interface ..................................................................................................... 27
4.6 Data Storage ....................................................................................................... 32
4.7 High Level Design ............................................................................................. 34
Chapter (5): System Implementation ................................................................................ 36
5.1 Technologies Used In Implementation .............................................................. 36
5.2 Database Structure.............................................................................................. 37
5.3 Programing Languages ....................................................................................... 39
5.4 Interface Design and Coding .............................................................................. 39
Chapter (6): Testing and Evaluation ................................................................................. 82
6.1 Testing Goals...................................................................................................... 82
6.2 Testing Scope ..................................................................................................... 83
6.3 Testing Strategy.................................................................................................. 84
6.4 Testing Verification............................................................................................ 84
6.5 Stages of Testing ................................................................................................ 85
6.6 Interface & Database Testing ............................................................................. 85
Chapter (7): Conclusion & Recommendation................................................................... 91
7.1 Conclusion.......................................................................................................... 91
7.2 Recommendations and Future Works ................................................................ 91
References ......................................................................................................................... 93
v
List of Tables
vi
List of Figures
vii
Chapter (1): Introduction
In today's fast-paced world, people are increasingly turning to nature for relaxation and
stress relief. Home gardening has become a popular hobby, allowing individuals to connect
with the natural world and grow their own food. However, gardening can be challenging,
especially for beginners who may lack the knowledge or experience to care for plants
properly. The Home Garden App aims to address this challenge by providing users with a
comprehensive platform for learning about and practicing home gardening. The app offers
a variety of features that make gardening easier and more enjoyable, such as a planting
calendar to help users choose the right plants for their climate and soil conditions, plant
care tips to ensure healthy growth, and a plant database to learn about different plant
species. By combining these features with a user-friendly interface, the Home Garden App
is designed to make home gardening accessible to everyone, regardless of their level of
experience.
The primary aim of the Home Garden App is to simplify and enhance the home
gardening experience for users of all levels. By providing comprehensive information,
tools, and guidance, the app seeks to:
Educate users about various plant species, their care requirements, and common
gardening techniques.
Assist users in planning and managing their home gardens, including selecting
appropriate plants, creating planting schedules, and tracking plant growth.
Promote healthy plant growth and development by offering tips on disease and pest
prevention, proper watering, and fertilization.
Inspire individuals to connect with nature and enjoy the benefits of gardening, such
as improved mental health, physical well-being, and a sense of accomplishment.
1
1.2 Project Scope
The Home Garden App will focus on providing the following core features:
1.3 Objectives
Provide a user-friendly and informative platform for home gardeners of all levels.
Empower users to make informed decisions about plant selection, care, and
maintenance.
Promote sustainable and environmentally friendly gardening practices.
Foster a sense of community and connection among gardening enthusiasts.
Contribute to the overall well-being and quality of life of users.
The Home Garden App addresses the following key challenges faced by home
gardeners:
2
Lack of knowledge and information: Many home gardeners struggle to find
reliable information about plant care, disease prevention, and gardening techniques.
Difficulty in planning and managing gardens: Organizing planting schedules,
tracking plant growth, and ensuring proper care can be time-consuming and
complex.
Environmental concerns: Many home gardeners are interested in sustainable and
eco-friendly gardening practices but may lack the knowledge or resources to
implement them.
By providing a comprehensive and user-friendly platform, the Home Garden App aims
to address these challenges and help home gardeners achieve their gardening goals.
The Home Garden App offers a comprehensive solution to the challenges faced by
home gardeners. By providing a variety of features and functionalities, the app aims to:
Educate and inform users: The app will offer a wealth of information on plant
species, care requirements, gardening techniques, and environmental sustainability.
Simplify garden planning and management: Users can easily create planting
schedules, track plant growth, and receive personalized care recommendations.
Promote sustainable gardening practices: The app will provide guidance on eco-
friendly gardening techniques, such as composting, rainwater harvesting, and
natural pest control.
In summary, the Home Garden App is designed to be a one-stop resource for home
gardeners, providing the tools and information they need to create beautiful and thriving
gardens.
3
1.6 Project Plan
The Gantt chart is a specialized bar chart used to provide a graphical overview and
schedule of all tasks or to indicate the work elements and dependencies of project. This is
a chart with rectangular bars. The length of each bar is proportional to the time value
necessary for each task on the work breakdown structure. The following are the steps of
planed tasks to be achieved within the project: -
4
9- Presentation: - it is about the final presentation of what is been achieved in the
project.
5
Chapter (2): Literature Review
The Home Garden App is a mobile application designed to assist individuals in planting
and caring for plants at home. This literature review explores existing research and studies
related to home gardening, mobile applications, and the potential benefits of combining
these two areas. By examining the current state of knowledge, this review aims to provide
a solid foundation for the development and implementation of the Home Garden App.
Home gardening has gained significant popularity in recent years, driven by a growing
interest in sustainable living, healthy eating, and stress reduction. Engaging in gardening
activities has been linked to numerous physical and mental health benefits, including:
Despite the numerous benefits of home gardening, it can be challenging for individuals
to maintain healthy and thriving gardens, especially those with limited experience or
knowledge. This is where mobile applications can play a crucial role. Mobile applications
have become an integral part of our daily lives, offering a wide range of functionalities and
services. In the context of home gardening, these applications can provide valuable tools
and resources to assist users in the following:
6
Learning about plants: Accessing information on plant species, care
requirements, and growth habits.
Planning gardens: Creating planting schedules, selecting appropriate plants for
different climates and soil conditions, and tracking plant growth.
Receiving expert advice: Connecting with gardening communities, seeking advice
from experts, and diagnosing plant problems.
Promoting sustainable practices: Learning about eco-friendly gardening
techniques and accessing information on organic fertilizers and pest control
methods.
By leveraging the power of mobile technology, a Home Garden App can address the
challenges faced by home gardeners, providing a convenient and informative platform that
supports their gardening endeavors.
Several existing mobile applications offer features related to home gardening. While
they may not provide the exact same functionalities as the proposed Home Garden App,
they can serve as valuable references and potential competitors.
2.2.1 PlantNet
Features:
7
Detailed plant information
Care tips and recommendations
Distribution maps
Community features
Garden Planner is a versatile application that allows users to create virtual gardens and
experiment with different layouts. Users can add plants to their garden, customize their
appearance, and track their growth over time. The app also provides planting calendars
tailored to specific locations and offers reminders for various gardening tasks, such as
8
watering, fertilizing, and pruning. Additionally, Garden Planner can generate shopping lists
based on the plants in the user's garden.
Features:
2.2.3 iNaturalist
iNaturalist is a popular citizen science platform that encourages users to document and
share observations of plants and other organisms. Users can upload photos and descriptions
of their observations, which can then be identified by other users or experts. iNaturalist
fosters a strong sense of community and collaboration among nature enthusiasts, allowing
users to connect with like-minded individuals and contribute to scientific research.
9
Features:
2.2.4 Planta
Features:
The following table summarizes the key features and functionalities of the similar
systems and the proposed Home Garden App:
11
Garden planning No Yes No No Yes
Community features Yes No Yes No No
Citizen science No No Yes No Yes
Personalized No No No Yes Yes
recommendations
Based on this comparison, the Home Garden App offers a more comprehensive set of
features than the existing systems. It combines the strengths of plant identification,
personalized care recommendations, garden planning, community engagement, and citizen
science contributions into a single platform. This unique combination differentiates the
Home Garden App from its competitors and positions it as a more comprehensive and
versatile solution for home gardeners.
2.4 Limitations
While the system offers a comprehensive solution for home gardeners, it is important
to acknowledge certain limitations:
12
and the value proposition of the app will play a crucial role in determining its
adoption rate.
Addressing these limitations will be essential to ensure the long-term success and
effectiveness of the Home Garden App.
The system will offer a comprehensive set of features designed to assist home gardeners
in planning, managing, and maintaining their gardens. These features include:
13
Chapter (3): System Analysis
This chapter provides a detailed analysis of the hardware and software requirements
for the system. By understanding these requirements, we can ensure that the app is designed
and developed to meet the needs of users and function effectively on various devices and
platforms.
This subject outlines the technical requirements for the system, providing a detailed
specification of the hardware, software, and infrastructure needed to develop, deploy, and
maintain the application. By understanding these requirements, we can ensure that the app
is built on a solid foundation and meets the performance, scalability, and security needs of
its users.
The Home Garden App is designed to be compatible with a wide range of mobile
devices, including smartphones and tablets. To ensure optimal performance and
functionality, the following hardware requirements are recommended:
14
Personal Computer with the following specifications:-
In addition to the hardware requirements, the Home Garden App will require the
following software components:
These specifications will provide sufficient processing power, memory, and storage for
efficient development and testing. By carefully considering these hardware and software
requirements, we can ensure that the system is developed on a solid foundation and
provides a seamless user experience across different devices and platforms.
Admin User
The admin should be able to create, edit, and delete user accounts.
15
The admin should be able to manage plant information, including adding, editing,
and deleting plant species.
The admin should be able to create and customize plant care tips and
recommendations.
The admin should be able to monitor user activity and engagement within the app.
The admin should be able to manage the app's settings and configuration.
Gardener User
The gardener should be able to create a personal profile and customize preferences.
The gardener should be able to search for and view plant information.
The gardener should be able to receive personalized plant care recommendations
based on their location, climate, and plant choices.
The gardener should be able to track the growth and development of the plants.
The gardener should be able to access and follow gardening tips and advice.
These functional requirements outline the key actions and capabilities that both admin
and gardener users will need to perform within the system.
Performance
The app should load quickly and respond promptly to user input, even on lower-
end devices.
The app should be optimized for efficient use of resources, such as battery life and
data consumption.
16
Usability
Security
The app should protect user data and privacy, ensuring that personal information is
securely stored and transmitted.
The app should be regularly updated to address security vulnerabilities and protect
against potential threats.
Reliability
The app should be stable and reliable, with minimal crashes or errors.
The app should be regularly updated with bug fixes and improvements.
Compatibility
The app should be compatible with a wide range of devices and operating systems
(iOS, Android).
The app should adapt to different screen sizes and resolutions.
Scalability
The app should be able to handle a growing user base and increasing data loads.
The app's infrastructure should be scalable to accommodate future growth and
expansion.
These non-functional requirements ensure that the system meets the expectations of
users in terms of performance, usability, security, reliability, compatibility, and scalability.
By addressing these factors, we can create a high-quality app that provides a positive user
experience.
17
3.4 Logic Steps of the Flowchart
Admin User
1. Login: The admin enters the credentials (username and password) to access the
admin dashboard.
2. User Management: The admin can create, edit, or delete user accounts.
3. Plant Management: The admin can add, edit, or delete plant species, including
information such as plant name, description, care requirements, and images.
4. Tip Management: The admin can create, edit, or delete plant care tips and
recommendations.
5. Analytics: The admin can view user activity and engagement data, such as number
of users, popular plant species, and app usage patterns.
Gardener User
1. Login: The gardener enters the credentials (username and password) to access the
app.
2. Profile: The gardener can create or edit their profile, including personal
information and preferences.
3. Plant Search: The gardener can search for plant species by name or category.
4. Garden Planning: The gardener can create and customize their garden plans,
including selecting plants, arranging layout, and tracking plant growth.
5. Plant Care: The gardener can view personalized plant care recommendations
based on their location, climate, and plant choices.
6. Notifications: The gardener can receive notifications for important updates, such
as plant care reminders or community activities.
These logic steps represent the core functionalities and interactions that will be
included in the Home Garden App. The flowchart will visually represent these steps,
showing the flow of control and decision points within the app.
18
3.5 Plant Identification Algorithm
How it Works:
1. Image Capture: The user captures an image of the plant using the device's
camera.
2. Image Preprocessing: The captured image undergoes preprocessing to
enhance its quality and extract relevant features. This may involve resizing,
cropping, and noise reduction.
3. API Integration: The preprocessed image is sent to a plant identification
API, such as PlantNet or PlantSnap.
4. Feature Extraction: The API employs advanced computer vision
techniques to extract features from the image, such as color, texture, and
shape.
5. Image Matching: The extracted features are compared to a vast database
of plant images and their associated metadata. Similarity measures, such as
Euclidean distance or cosine similarity, are used to identify the closest
matches.
6. Result Analysis: The API returns a list of potential plant species, along
with their scientific names, common names, and relevant information. The
app may further refine the results based on user-provided context, such as
location or plant type.
7. User Interface Display: The app displays the identified plant species,
along with additional details such as care tips, growth habits, and potential
pests and diseases.
19
Chapter (4): System Design
This chapter delves into the technical architecture and design of the Home Garden App.
It presents a comprehensive overview of the system's components, their interactions, and
the underlying technologies employed. By examining the system design, we can gain
insights into how the app will function and how it will meet the requirements outlined in
previous chapters.
Domain Analysis:
Identifying the core functionalities required for the app, such as plant identification,
personalized care recommendations, garden planning, and educational resources.
Defining the user interactions and system responses for each functionality.
Identifying the quality attributes that the app must possess, such as performance,
usability, security, reliability, scalability, and compatibility.
20
Defining the specific metrics and standards that will be used to measure these
attributes.
4.2 Personas
Personas are fictional characters that represent the different types of users who will
interact with the Home Garden App. By creating detailed personas, we can gain a deeper
understanding of our target audience and tailor the app's design and functionality to their
specific needs and preferences. Key Personas for the Home Garden App:
Goals: Learn about gardening, grow healthy plants, and create a beautiful garden.
Needs: Simple, clear instructions, personalized recommendations, and a supportive
community.
Challenges: Lack of knowledge and experience.
Goals: Expand their gardening knowledge, experiment with new plants, and
optimize their gardening practices.
Needs: Advanced features, data-driven insights, and a community of like-minded
gardeners.
Challenges: Time constraints and complex gardening tasks.
21
Needs: Tips for container gardening, advice on selecting suitable plants and
solutions for common urban gardening challenges.
Challenges: Limited space and exposure to pests and diseases.
By understanding the needs and motivations of these personas, we can design an app
that caters to a diverse range of users and provides a truly valuable gardening experience.
System models are essential tools for visualizing and understanding the structure,
behavior, and interactions within a software system. By creating various system models,
we can ensure that the system is well designed, efficient, and meets the needs of its users.
It is a visual representation of the interactions between users (actors) and the system. It
helps to identify the functional requirements and the system's boundaries.
Actors:
Gardener: The primary user of the app who interacts with various features to
manage their garden.
Admin: A system administrator who manages the app's backend, including plant
data, user accounts, and system settings.
By analyzing the use cases, we can gain a clear understanding of the system's
functionality and how it will meet the needs of its users.
22
order in which they occur. In the context of the Home Garden App, sequence diagrams can
be used to model the interactions between the user, the app, and the backend systems.
23
Figure 4. 2 sequence Diagram
24
4.3.3 Activity Diagram
25
4.3.4 Class Diagram
A Class Diagram is a static structure diagram that shows the classes, their attributes,
and their relationships. In the context of the Home Garden App, a class diagram can be
used to model the different entities within the system, such as plants, users, and gardens. It
can also show the relationships between these entities, such as inheritance, association, and
aggregation.
26
4.4 Product Features
This section outlines the key features of the Home Garden App, which are designed to
meet the needs of home gardeners of all levels. These features include:
By providing these features, the Home Garden App empowers users to cultivate healthy
and thriving gardens.
The user interface (UI) of the Home Garden App plays a crucial role in providing a
seamless and enjoyable user experience. A well-designed UI not only enhances the app's
functionality but also creates a visually appealing and intuitive interface. This section
delves into the design principles and guidelines that will be followed to create a user-
friendly and engaging UI. The following are some of the system interfaces designs as
prototype.
27
Figure 4. 5 System Interfaces (1)
28
Figure 4. 6 System Interfaces (2)
29
Figure 4. 7 System Interfaces (3)
30
Figure 4. 8 System Interfaces (4)
31
Figure 4. 9 System Interfaces (5)
This section outlines the data storage requirements for the Home Garden App. The
app will utilize a relational database to store and manage various types of data, including
user information, plant data, and gardening tips. Here is a breakdown of the database
schema.
Table 4. 1 Users
32
Table 4. 2 Plants
Table 4. 3 Categories
Table 4. 4 Locations
33
Table 4. 5 UserPlants
1. Presentation Layer
User Interface: Responsible for the visual elements and user interactions.
User Experience: Focuses on creating a seamless and intuitive user experience.
Framework: Utilizes a cross-platform framework like React Native to build the
mobile app.
Core Functionality: Handles the core business logic, such as plant identification,
personalized recommendations, and garden planning.
Data Access: Interacts with the database to retrieve and store data.
Service Layer: Provides reusable services for common tasks, such as user
authentication, data validation, and error handling.
34
3. Data Access Layer
By adopting a layered architecture, the Home Garden App can be easily maintained,
tested, and extended in the future.
35
Chapter (5): System Implementation
This chapter details the practical steps and methodologies involved in bringing the
Home Garden App from its design phase into a functional reality. It outlines the
technologies, tools, and processes employed during the development lifecycle, including
the selection of programming languages, frameworks, and deployment strategies.
Furthermore, this chapter will discuss the approach to building the various features of the
application, emphasizing the integration of different modules and the testing procedures
implemented to ensure a robust and reliable final product.
The Home Garden App was developed using a set of modern and efficient technologies
chosen for their capabilities in building cross-platform mobile applications and scalable
backend services. The key technologies employed during the implementation phase
include:
Hardware:
- Developer Machines: a computer running an operating system compatible
with the software tools.
- Mobile Devices (Physical): a device running Android for testing the React
Native application.
- Servers (Firebase/Cloud Provider): The hardware infrastructure that
supports the Firebase services. However, with Firebase, the direct
management of this hardware is abstracted away.
Software:
- Visual Studio Code (VSCode): A lightweight yet powerful source code
editor used as the primary Integrated Development Environment (IDE) for
writing and managing the application's codebase. VSCode offers excellent
36
support for JavaScript, React Native, and [Link], along with features like
debugging, and code completion, enhancing developer productivity.
- Expo: A framework and a set of tools built around React Native. Expo
simplifies the development, building, deployment, and updating of React
Native applications by providing pre-configured tools and services, such as
build services and access to native device features.
- [Link]: A JavaScript runtime environment used for building the backend
services and APIs that power the application. [Link] is known for its event-
driven, non-blocking architecture, making it highly efficient for handling
concurrent requests and real-time applications.
The Home Garden App utilizes Firebase's NoSQL Realtime Database to store and
manage application data. This flexible and scalable database structure allows for real-time
data synchronization and efficient data retrieval. The primary data structures within the
Firebase Realtime Database are organized as follows (aligning with the conceptual model
and class diagram):
37
b. Plant Table Structure
users (Node):
Key: uid (User ID)
Fields: username, email, role, isAnonymous, name, etc.
Description: Stores information about each user of the app.
plants (Node):
Key: plantId (Unique Plant ID)
Fields: commonName, scientificName, category, description, careTips (object), images (object with image URLs),
watering, light, etc.
Description: Stores detailed information about different plant species.
38
5.3 Programing Languages
The Home Garden App was primarily developed using JavaScript, leveraging its
versatility for both mobile application development (with React Native and Expo) and
backend services (with [Link]).
- JavaScript: Served as the core programming language across the entire project,
enabling code sharing and a consistent development paradigm between the frontend
and backend.
- React Native: A JavaScript framework allowed for building native-like mobile
applications for both iOS and Android platforms from a single codebase,
maximizing development efficiency and reach.
The development of the Home Garden App involved a focus on creating an intuitive
and engaging user interface (UI) while ensuring clean and maintainable code.
Figure 5. 3 AuthScreen
39
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import {Platform, Image, Text, TextInput, TouchableOpacity, View, StyleSheet, KeyboardAvoidingView, Alert } from
'react-native';
// import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
// import firebase from '../firebase/config';
import { signInValidation, signUpValidation } from '../helpers/formValidation';
import visibleIcon from '../assets/images/[Link]';
import invisibleIcon from '../assets/images/[Link]';
import Colors from '../constants/Colors';
import { updateUser } from '../firebase';
import { auth, db } from '../firebase/config';
import { signInWithEmailAndPassword, createUserWithEmailAndPassword } from 'firebase/auth';
import { doc, getDoc, setDoc } from 'firebase/firestore';
const AuthScreen = ({ navigation }) => {
const dispatch = useDispatch();
const [fullName, setFullName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [displaySignup, setDisplaySignup] = useState(false);
const [passwordVisible, setPasswordVisible] = useState(false);
const [confirmVisible, setConfirmVisible] = useState(false);
const [disable, setDisable] = useState(false);
const onFooterLinkPress = () => {
setDisplaySignup(!displaySignup);
};
const buttonPress = (isSignUp) => {
return isSignUp ? signupHandler() : signinHandler();
};
const authFooterText = (isSignUp) => {
return (
<>
{isSignUp ? 'Already have an account? ' : "Don't have an account? "}
<Text onPress={onFooterLinkPress} style={[Link]}>
{isSignUp ? 'Sign In' : 'Sign Up'}
</Text>
</>
);
};
const signinHandler = async () => {
setDisable(true)
try {
const response = await signInWithEmailAndPassword(auth, email, password);
const { uid } = [Link];
// Reference to Firestore user document
const userRef = doc(db, 'users', uid);
const userDoc = await getDoc(userRef);
if (![Link]()) {
[Link]('User does not exist anymore.');
return;
}
const userData = [Link]();
[Link]('User data:', userData);
setDisable(false)
dispatch({ type: 'ADD_USER', payload: { user: userData } });
dispatch(updateUser(uid));
[Link]({
40
index: 0,
routes: [{ name: "MainTab" }],
});
} catch (error) {
41
message = 'That email address is invalid!';
}
if ([Link] === 'auth/invalid-credential') {
message = 'That password is invalid!';
}
if ([Link] === 'auth/weak-password') {
message = "Password should be at least 6 characters";
}
if ([Link] === 'auth/operation-not-allowed') {
message = 'Enable anonymous in your firebase console.';
}
[Link]('Oops', message);
}
};
const toggleVisibility = () => {
setPasswordVisible(!passwordVisible);
};
const toggleConfirmVisibility = () => {
setConfirmVisible(!confirmVisible);
};
return (
<View style={[Link]}>
{/* <KeyboardAwareScrollView
style={{ flex: 1, width: '100%' }}
contentContainerStyle={[Link]}
keyboardShouldPersistTaps="always"> */}
42
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TouchableOpacity
activeOpacity={0.8}
style={[Link]}
onPress={toggleVisibility}>
<Image source={passwordVisible ? visibleIcon : invisibleIcon} style={[Link]} />
</TouchableOpacity>
</View>
{displaySignup && (
<View style={[Link]}>
<TextInput
style={[Link]}
placeholderTextColor={[Link]}
secureTextEntry={!confirmVisible}
placeholder="Confirm Password"
onChangeText={(text) => setConfirmPassword(text)}
value={confirmPassword}
underlineColorAndroid="transparent"
autoCapitalize="none"
/>
<TouchableOpacity
activeOpacity={0.8}
style={[Link]}
onPress={toggleConfirmVisibility}>
<Image
source={confirmVisible ? visibleIcon : invisibleIcon}
style={[Link]}
/>
</TouchableOpacity>
</View>
)}
<TouchableOpacity style={[Link]} onPress={() => buttonPress(displaySignup)} disabled={disable}>
<Text style={[Link]}> {displaySignup ? 'SIGN UP' : 'SIGN IN'} </Text>
</TouchableOpacity>
<View style={[Link]}>
<Text style={[Link]}> {authFooterText(displaySignup)} </Text>
</View>
</KeyboardAvoidingView>
</View>
);
};
43
// },
input: {
height: 48,
borderRadius: 5,
overflow: 'hidden',
backgroundColor: [Link],
color: [Link],
marginTop: 10,
marginBottom: 10,
marginLeft: 30,
marginRight: 30,
paddingLeft: 16,
},
button: {
backgroundColor: [Link],
marginLeft: 30,
marginRight: 30,
marginTop: 20,
height: 48,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
buttonTitle: {
color: [Link],
fontSize: 16,
},
footerView: {
flex: 1,
alignItems: 'center',
marginTop: 20,
},
footerText: {
fontSize: 16,
color: [Link],
},
footerLink: {
color: [Link],
fontSize: 16,
},
passwordContainer: {
position: 'relative',
alignSelf: 'stretch',
},
btnImage: {
position: 'absolute',
right: 35,
width: 30,
resizeMode: 'contain',
},
visibilityBtn: {
position: 'absolute',
top: -12,
right: 3,
height: 70,
width: 35,
},});
export default AuthScreen;
44
Figure 5. 4 CameraScreen
45
// '[Link]': [Link],
// })
// .then(() => {
// [Link]('My Plant');
// });
// }
const permissionResult = await [Link]();
if ([Link] === false) {
alert('Permission to access camera roll is required!');
return;
}
try {
const pickerResult = await [Link]();
if (![Link]) {
[Link](pickerResult)
46
style={{ flex: 1, justifyContent: 'flex-end' }}
facing={type}
flash={flash}
ref={(ref) => {
setCameraRef(ref);
}}>
<View style={{ position: 'absolute', bottom: 100, left: 35 }}>
<TouchableOpacity onPress={openImagePickerAsync}>
<Ionicons name="images" size={50} color={[Link]} />
</TouchableOpacity>
</View>
<View
style={{
backgroundColor: '#00000099',
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 15,
paddingHorizontal: 35,
}}>
<TouchableOpacity
style={{
width: 40,
alignItems: 'center',
paddingTop: 10,
}}
onPress={() => {
setFlash(
flash === 'off'
? 'on'
: 'off'
);
}}>
{flash === 'off' ? (
<Ionicons name="flash-off" size={35} color={[Link]} />
):(
<Ionicons name="flash" size={35} color={[Link]} />
)}
</TouchableOpacity>
<TouchableOpacity
onPress={async () => {
setProcessing(true);
if (cameraRef) {
// Taken photo is here
let photo = await [Link]({
exif: true,
});
photo = await [Link](
[Link],
[
{
rotate: 0,
},
{
resize: {
width: [Link],
height: [Link],
},
},
47
],
{ compress: 1,
} );
// We can use the uri property from photo to reach the taken picture and do what we want.
// const userplantsRef = [Link]().collection('plants').doc(plantId);
// userplantsRef
// .update({
// '[Link]': [Link],
// })
// .then(() => {
// setProcessing(false);
// [Link]('My Plant');
// });
try {
if ([Link]) {
const plantRef = doc(db, "plants", plantId); // Reference to the document
await updateDoc(plantRef, {
"[Link]": [Link], // Update the picture field
});
[Link]("Picture updated successfully!");
[Link]("My Plant",{plantId:plantId}); // Navigate after updating
}
} catch (error) {
[Link]("Error updating picture:", error);
}
}
}}>
{processing ? (
<ActivityIndicator size={80} />
):(
<View
style={{
borderWidth: 2,
borderColor: [Link],
borderRadius: 50,
height: 50,
width: 50,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
<View
style={{
borderWidth: 2,
borderRadius: 50,
borderColor: [Link],
height: 40,
width: 40,
backgroundColor: [Link],
}}
/>
</View>
)}
</TouchableOpacity>
<TouchableOpacity
style={{
width: 40,
alignItems: 'center',
48
paddingTop: 10,
}}
onPress={() => {
setType(
type === "back"
? "front"
: "back"
);
}}>
<Ionicons name="camera-reverse" size={35} color={[Link]} />
</TouchableOpacity>
</View>
</CameraView>
</View>
);
};
export default CameraScreen;
Figure 5. 5 MyGardenScreen
49
import plantData from '../data/[Link]';
import {
BottomSheetModal,
BottomSheetView,
BottomSheetModalProvider,
} from '@gorhom/bottom-sheet';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const MyGardenScreen = ({ navigation }) => {
const plants = useSelector((state) => [Link]);
[Link]("plants===>>",plants)
const dispatch = useDispatch();
const [modalVisibles, setModalVisibles] = [Link](false);
const bsSettings = [Link](null);
const fall = useSharedValue(1); // Correct way to declare animated value
// Derived value for opacity
const opacity = useDerivedValue(() => 0.4 + [Link] * 1.0);
50
</View>
)
}
// ref
const bottomSheetModalRef = [Link](null);
// callbacks
const handlePresentModalPress = [Link](() => {
[Link]?.present();
}, []);
const handleSheetChanges = [Link]((index) => {
[Link]('handleSheetChanges', index);
}, []);
const handleCloseModalPress = [Link](() => {
[Link]?.dismiss();
}, []);
[Link](modalVisibles)
return (
<>
<View>
{modalVisibles && <Modal visible={modalVisibles} animationType="slide"
onBackdropPress={() => setModalVisibles(false)}
onRequestClose={() => {
setModalVisibles(!modalVisibles);
}}>
<SearchFieldModal plantData={plantData} setModalVisibles={setModalVisibles} dispatch={dispatch} />
</Modal>}
</View>
<GestureHandlerRootView>
<BottomSheetModalProvider>
<BottomSheetModal
ref={bottomSheetModalRef}
onChange={handleSheetChanges}
>
<BottomSheetView style={[Link]}>
<AddPlantSettings />
</BottomSheetView>
</BottomSheetModal>
{/* <BottomSheet
ref={bsSettings}
snapPoints={[200, 500]}
renderContent={addPlantSettings}
renderHeader={renderHeader}
initialSnap={1}
callbackNode={fall}
enabledGestureInteraction
/> */}
<[Link]
style={{ minHeight: '100%', opacity: opacity }}>
<ImageBackground source={background} style={[Link]} />
{plants?.length > 0 ? (
<ScrollView contentContainerStyle={[Link]}>
<GreenthumbOpacity onPress={() => handlePresentModalPress()}>
<NeuMorph>
<View style={{ alignSelf: 'flex-end', marginTop: 15, marginRight: 15 }}>
<LinearGradient
colors={[[Link], [Link], [Link]]}
start={[0.0, 0.0]}
end={[1.0, 1.0]}
51
style={{ width: 180, borderRadius: 17, padding: 10, elevation: 3 }}>
<Text
style={{
textAlign: 'center',
fontSize: 16,
color: [Link],
fontWeight: '600',
}}>
Add Plant
</Text>
</LinearGradient>
</View>
</NeuMorph>
</GreenthumbOpacity>
<View style={[Link]}>
{[Link]((plant) => {
return <BasicCard plant={plant} key={[Link]} />;
})}
</View>
</ScrollView>
):(
<View style={[Link]}>
<GreenthumbOpacity onPress={() => handlePresentModalPress()}>
<NeuMorph>
<View
style={{
alignSelf: 'flex-end',
margin: 20,
}}>
<LinearGradient
colors={[[Link], [Link], [Link]]}
start={[0.0, 0.0]}
end={[1.0, 1.0]}
style={{ width: 180, borderRadius: 17, padding: 10, elevation: 3 }}>
<Text
style={{
textAlign: 'center',
fontSize: 16,
color: [Link],
fontWeight: '600',
}}>
Add Plant
</Text>
</LinearGradient>
</View>
</NeuMorph>
</GreenthumbOpacity>
<GreenthumbOpacity activeOpacity={1} onPress={() => handleCloseModalPress()}>
<View style={[Link]}>
<Image
source={{
uri:
'[Link]
}}
style={[Link]}
/>
<Text style={[Link]}>There are no plants in your garden yet.</Text>
</View>
52
</GreenthumbOpacity>
</View>
)}
</[Link]>
</BottomSheetModalProvider>
</GestureHandlerRootView>
</>
);
};
const styles = [Link]({
topShadow: {
shadowOffset: {
width: -2,
height: -2,
},
shadowOpacity: 0.5,
shadowRadius: 3,
shadowColor: [Link],
},
bottomShadow: {
shadowOffset: {
width: 3,
height: 3,
},
shadowOpacity: 0.8,
shadowRadius: 3,
shadowColor: [Link],
},
// bottom sheet settings styles
settingsContainer: {
padding: 20,
backgroundColor: [Link],
height: '100%',
},
settingsBtns: {
borderRadius: 10,
backgroundColor: [Link],
marginVertical: 3,
marginHorizontal: 5,
},
settingsBtnTitle: {
textAlign: 'center',
paddingVertical: 15,
fontSize: 16,
color: [Link],
fontWeight: '600',
},
cancelSettingsBtn: {
borderRadius: 10,
backgroundColor: [Link],
marginHorizontal: 5,
marginVertical: 3,
},
settingsHandleContainer: {
backgroundColor: [Link],
paddingTop: 20,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
53
},
settingsHeader: {
alignItems: 'center',
},
settingsHandle: {
width: 40,
height: 6,
borderRadius: 4,
backgroundColor: [Link],
marginBottom: 10,
},
// ======================
container: {
flexDirection: 'column',
alignItems: 'center',
marginVertical: 10,
},
wrapperWhenNoPlants: {
minHeight: '100%',
backgroundColor: [Link],
},
imageWrapper: {
height: '90%',
justifyContent: 'center',
},
plantsIconIcon: {
height: 320,
width: 320,
marginBottom: 10,
alignSelf: 'center',
},
errorMsg: {
fontSize: 20,
marginTop: 10,
alignSelf: 'center',
},
background: {
width: '100%',
height: '100%',
resizeMode: 'cover',
position: 'absolute',
zIndex: 0,
opacity: 0.8,
},
});
export default MyGardenScreen;
54
Figure 5. 6 MyPlantScreen
55
import { GestureHandlerRootView , ScrollView} from 'react-native-gesture-handler';
import { useSelector } from 'react-redux';
import Modal from 'react-native-modal';
import firebase from '../firebase';
import Colors from '../constants/Colors';
import GreenthumbOpacity from '../components/GreenthumbOpacity';
import ModalConfigPopup from '../components/ModalConfigPopup';
import ModalListPopup from '../components/ModalListPopup';
import { doc, deleteDoc, updateDoc } from "firebase/firestore";
import { db } from "../firebase/config"; // Import Firestore instance
const MyPlantScreen = ({ route, navigation }) => {
const bsSettings = [Link](null);
const bsInfo = [Link](null);
// const fall = new [Link](1);
const fall = useSharedValue(1); // Correct way to declare animated value
const { plantId } = [Link];
const plant = useSelector((state) =>
[Link]?.[Link]((plantToFind) => [Link] === plantId)
);
[Link]("plant===",plant)
// const transition = <[Link] interpolation="easeInOut" />;
const [deg, setDeg] = useState(0);
const ref = useRef();
const [rename, setRename] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [value, onChangeText] = useState(plant?.custom?.title ?? plant?.commonName);
const renamePlant = async (selectedPlant,value) => {
// const userplantsRef = [Link]().collection('plants').doc([Link]);
// [Link]({
// '[Link]': value,
// });
[Link]("****",value)
try {
const plantRef = doc(db, "plants", [Link]); // Reference to the document
await updateDoc(plantRef, {
"[Link]": value, // Update the specific field
});
onChangeText(value)
[Link]("Title updated successfully!");
} catch (error) {
[Link]("Error updating title:", error);
}
};
const deletePlantHandler = async (selectedPlant) => {
// firebase
// .firestore()
// .collection('plants')
// .doc([Link])
// .delete()
// .then(() => {
// [Link]('MyGarden');
// });
try {
const plantRef = doc(db, "plants", [Link]); // Reference to the document
56
// [Link]("MyGarden"); // Navigate after deletion
} catch (error) {
[Link]("Error deleting plant:", error);
}
};
const RenderInner = () => {
return( <View style={[Link]}>
<GreenthumbOpacity
style={[Link]}
onPress={() => {
[Link]('Camera', { plantId });
closeBottomSheet()
}}>
<Text style={[Link]}>Take Photo</Text>
</GreenthumbOpacity>
<GreenthumbOpacity style={[Link]} onPress={() => setModalOpen(true)}>
<Text style={[Link]}>Rename Plant</Text>
</GreenthumbOpacity>
<Modal
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-evenly',
alignItems: 'center',
height: 130,
width: '80%',
position: 'absolute',
top: '30%',
alignSelf: 'center',
backgroundColor: [Link],
borderRadius: 10,
}}
isVisible={modalOpen}
onBackdropPress={() => setModalOpen(false)}
backdropTransitionOutTiming={40}>
<TextInput
style={{
width: '90%',
borderWidth: 1,
borderColor: [Link],
borderRadius: 11,
textAlign: 'center',
height: '40%',
color: [Link],
margin: 20,
backgroundColor: [Link],
}}
// onChangeText={(text) => onChangeText(text)}
// value={value}
defaultValue={value}
onSubmitEditing={({nativeEvent: {text, eventCount, target}}) => {
[Link]("*********",text)
if (text) {
renamePlant(plant, text);
setRename(false);
setModalOpen(false);
}
}}
57
/>
<View style={[Link]}>
<DefaultTouch
onPress={() => {
setRename(false);
setModalOpen(false);
}}>
<AntDesign
style={[Link]}
name="closecircle"
size={35}
color={[Link]}
/>
</DefaultTouch>
<DefaultTouch
onPress={() => {
setModalOpen(false);
[Link]();
renamePlant(plant, value);
}}>
<AntDesign
style={[Link]}
name="checkcircle"
size={35}
color={[Link]}
/>
</DefaultTouch>
</View>
</Modal>
<GreenthumbOpacity style={[Link]} onPress={() => deletePlantHandler(plant)}>
<Text style={[Link]}>Delete Plant</Text>
</GreenthumbOpacity>
<GreenthumbOpacity style={[Link]} onPress={() => closeBottomSheet()}>
<Text style={[Link]}>Cancel</Text>
</GreenthumbOpacity>
</View>)
};
const renderHeader = () => (
<View style={[Link]}>
<View style={[Link]}>
<View style={[Link]} />
</View>
</View>
);
const RenderMainInfo = () => {
return(<View style={[Link]}>
{/* <[Link]
ref={ref}
layout={[Link]([Link]([Link]))}
style={{ alignItems: 'center' }}
>
<Ionicons
name="chevron-up"
size={24}
color={[Link]}
/>
</[Link]> */}
58
<View style={[Link]}>
<ModalConfigPopup
plantName={plant?.custom?.title ? [Link] : plant?.commonName}
plantId={plant?.id && [Link]}
/>
<View style={[Link]}>
{plant?.custom?.notifications?.length > 0 && (
<ModalListPopup
notifications={plant?.custom?.notifications && [Link]}
plantId={plant?.id && [Link]}
/>
)}
</View>
</View>
<ScrollView style={[Link]}>
<View style={[Link]}>
<View style={[Link]}>
<View style={[Link]}>
<Text style={[Link]}>Poisonous:</Text>
<AntDesign style={[Link]} name="warning" size={30} />
</View>
<View style={[Link]}>
<Text style={[Link]}>{plant?.poisonousForPets}</Text>
</View>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Text style={[Link]}>Growth:</Text>
<Entypo style={[Link]} name="tree" size={30} />
</View>
<View style={[Link]}>
<Text style={[Link]}>{plant?.maxGrowth}</Text>
</View>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Text style={[Link]}>Origin:</Text>
<Entypo style={[Link]} name="globe" size={30} />
</View>
<View style={[Link]}>
<Text style={[Link]}>{plant?.origin}</Text>
</View>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Text style={[Link]}>Family:</Text>
<Entypo style={[Link]} name="price-tag" size={30} />
</View>
<View style={[Link]}>
<Text style={[Link]}>{plant?.familyName}</Text>
</View>
</View>
</View>
<View style={[Link]}>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="drop" size={14} color={[Link]} style={[Link]} />
<Text style={[Link]}>Water</Text>
59
</View>
<Text style={[Link]}>{plant?.watering}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="light-up" size={20} color={[Link]} />
<Text style={[Link]}>Light</Text>
</View>
<Text style={[Link]}>{plant?.light}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons
name="temperature-celsius"
size={20}
color={[Link]}
/>
<Text style={[Link]}>Temperature</Text>
</View>
<Text style={[Link]}>{plant?.temperature}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons name="pot" size={20} color={[Link]} />
<Text style={[Link]}>Soil</Text>
</View>
<Text style={[Link]}>{plant?.soil}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="bucket" size={20} color={[Link]} />
<Text style={[Link]}>Re-Potting</Text>
</View>
<Text style={[Link]}>{plant?.rePotting}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons name="spray-bottle" size={20} color={[Link]} />
<Text style={[Link]}>Fertilizer</Text>
</View>
<Text style={[Link]}>{plant?.fertilizer}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="water" size={20} color={[Link]} />
<Text style={[Link]}>Humidity</Text>
</View>
<Text style={[Link]}>{plant?.humidity}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<FontAwesome5 name="seedling" size={20} color={[Link]} />
<Text style={[Link]}>Propagation</Text>
</View>
<Text style={[Link]}>{plant?.propagation}</Text>
</View>
</View>
</ScrollView>
60
</View>)
};
[Link](() => {
// Automatically open the bottom sheet on mount
handleOpen()
}, []);
const closeBottomSheet = [Link](() => {
[Link]?.dismiss();
}, []);
const openBottomSheet = [Link](() => {
[Link]?.present();
}, []);
// Function to open the Bottom Sheet
const handleOpen = [Link](() => {
[Link]?.present();
setDeg(180);
}, []);
// Function to close the Bottom Sheet
const handleClose = [Link](() => {
[Link]?.dismiss();
setDeg(0);
}, []);
const opacity = useDerivedValue(() => 0.4 + [Link] * 1.0);
const [activeSnap, setActiveSnap] = useState(0); // Default index
const snapPoints = ['45%', '45%'];
const snapPointsInfo = ['50%', '78%'];
return (
<GestureHandlerRootView>
<BottomSheetModalProvider>
{/* Bottom Sheet Modal */}
<BottomSheetModal
ref={bsSettings}
snapPoints={snapPoints}
onDismiss={closeBottomSheet}
handleStyle={{ backgroundColor: [Link], borderRadius:30, }} // Custom handle color
backgroundStyle={{ backgroundColor: [Link] }} // Custom sheet color
handleIndicatorStyle={{ backgroundColor: [Link] }}
handleComponent={renderHeader}
backdropComponent={(props) => (
<BottomSheetBackdrop
{...props}
opacity={0.7} // Adjust overlay transparency
disappearsOnIndex={-1}
appearsOnIndex={0}
style={{ backgroundColor: '#444444' }} // Full black overlay
/>
)}
>
<BottomSheetView style={[Link]}>
<RenderInner />
</BottomSheetView>
</BottomSheetModal>
<View style={[Link]}>
{/* <BottomSheet
ref={bsSettings}
snapPoints={[330, 0]}
renderContent={renderInner}
renderHeader={renderHeader}
61
initialSnap={1}
callbackNode={fall}
enabledGestureInteraction
/> */}
<[Link]
style={{
height: '100%',
backgroundColor: [Link],
opacity: opacity
}}>
<DefaultTouch style={[Link]} onPress={() => openBottomSheet()}>
<View
style={{
backgroundColor: [Link],
width: 35,
height: 35,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
}}>
<Entypo name="dots-three-vertical" size={22} color={[Link]} />
</View>
</DefaultTouch>
<DefaultTouch
style={{ height: [Link] === 'ios' ? '59%' : '55%' }}
onPress={() => {
// [Link](0);
// [Link](1);
closeBottomSheet()
handleOpen()
}}
activeOpacity={1}>
<Svg height="90%" width="100%">
<ClipPath id="clip">
<Circle r="85%" cx="50%" />
</ClipPath>
<Image
href={plant?.custom?.picture ? [Link] : plant?.images?.imagePrimary}
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
clipPath="url(#clip)"
/>
</Svg>
<View style={[Link]}>
<View>
{plant?.custom?.title ? (
<Text style={[Link]}>{plant?.custom?.title}</Text>
):(
<View />
)}
</View>
<View style={[Link]}>
<Text style={[Link]}>{plant?.commonName}</Text>
</View>
<View>
<Text style={[Link]}>
Botanical name: <Text style={[Link]}>{plant?.scientificName} </Text>
62
</Text>
</View>
</View>
</DefaultTouch>
{/* <BottomSheet
ref={bsInfo}
snapPoints={['45%', '78%']}
renderContent={renderMainInfo}
initialSnap={0}
enabledBottomClamp
enabledGestureInteraction
onOpenEnd={() => {
[Link]();
setDeg(180);
}}
onCloseEnd={() => {
[Link]();
setDeg(0);
}}
/> */}
</[Link]>
</View>
<BottomSheetModal
enableDynamicSizing={false}
ref={bsInfo}
snapPoints={snapPointsInfo}
onDismiss={handleClose}
handleStyle={{ backgroundColor: [Link] }} // Custom handle color
backgroundStyle={{ backgroundColor: [Link] }} // Custom sheet color
handleIndicatorStyle={{ backgroundColor: [Link] }}
index={0}
enablePanDownToClose={false}
onChange={(index) => setActiveSnap(index)} // Track active snap point
handleComponent={() => (
<[Link]
ref={ref}
layout={[Link]([Link]([Link]))}
style={{ alignItems: 'center',marginTop:10 }}
>
<Ionicons
name={activeSnap === 1 ? 'chevron-down' : 'chevron-up'}
size={24}
color={[Link]}
/>
</[Link]>
)}
>
<BottomSheetView style={[Link]}>
<RenderMainInfo />
</BottomSheetView>
</BottomSheetModal>
</BottomSheetModalProvider>
</GestureHandlerRootView>
);
};
const styles = [Link]({
opacityContainer: {
63
backgroundColor: [Link],
},
settingsContainer: {
padding: 20,
backgroundColor: [Link],
height: '100%',
display: 'flex',
justifyContent: 'space-evenly',
},
settingsBtns: {
borderRadius: 10,
backgroundColor: [Link],
marginVertical: [Link] === 'ios' ? 3 : 7,
marginHorizontal: 5,
},
settingsBtnTitle: {
textAlign: 'center',
paddingVertical: 15,
fontSize: 16,
color: [Link],
fontWeight: '600',
},
renameIconWrapper: {
display: 'flex',
flexDirection: 'row',
height: 60,
},
renameIcon: {
marginHorizontal: 20,
},
deleteSettingsBtns: {
borderRadius: 10,
backgroundColor: [Link],
marginVertical: [Link] === 'ios' ? 3 : 7,
marginHorizontal: 5,
},
settingsBtnDelete: {
textAlign: 'center',
paddingVertical: 15,
fontSize: 16,
color: [Link],
fontWeight: '600',
},
cancelSettingsBtn: {
borderRadius: 10,
backgroundColor: [Link],
marginHorizontal: 5,
marginVertical: 25,
},
settingsHandleContainer: {
backgroundColor: [Link],
shadowColor: [Link],
shadowOffset: { width: -1, height: -3 },
shadowRadius: 2,
shadowOpacity: 0.4,
paddingTop: 20,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
64
},
settingsHeader: {
alignItems: 'center',
},
settingsHandle: {
width: 40,
height: 6,
borderRadius: 4,
backgroundColor: [Link],
marginBottom: 10,
},
plantSettings: {
position: 'absolute',
height: 50,
width: 50,
top: [Link] === 'ios' ? 100 : 110,
right: 0,
zIndex: 100,
},
myPlantContainer: {
display: 'flex',
height: '100%',
backgroundColor: [Link],
paddingTop:0,
paddingHorizontal: 10,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
},
customPlantName: {
fontWeight: '600',
fontSize: 18,
color: [Link],
alignSelf: 'center',
marginBottom: 5,
},
nameContainer: {
width: '80%',
backgroundColor: [Link],
position: 'absolute',
top: '63%',
alignSelf: 'center',
borderRadius: 10,
elevation: 3,
shadowColor: [Link],
shadowOpacity: 0.3,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 3,
display: 'flex',
padding: 10,
},
commonName: {
fontWeight: '600',
fontSize: 18,
color: [Link],
alignSelf: 'center',
marginBottom: 8,
},
commonNameContainer: {
65
marginBottom: 10,
borderBottomWidth: 1,
borderBottomColor: [Link],
},
botName: {
color: [Link],
fontWeight: '300',
alignSelf: 'center',
},
botNameInner: {
marginLeft: 5,
fontWeight: '400',
},
gearContainer: {
width: 33,
},
reminderBtnContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 10,
position: 'relative',
},
plantInfoWrapper: {
paddingTop: 10,
paddingHorizontal: 5,
},
smallContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
flexWrap: 'wrap',
},
smallInfoWrapper: {
backgroundColor: [Link],
borderRadius: 15,
width: '48%',
marginBottom: 15,
height: 110,
},
smallInfoHeaderWrapper: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
backgroundColor: [Link],
paddingVertical: 10,
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
height: '50%',
},
smallInfoHeader: {
color: [Link],
fontSize: 20,
paddingVertical: 5,
},
smallInfoIcon: {
66
position: 'absolute',
opacity: 0.2,
color: [Link],
},
smallBodyContainer: {
backgroundColor: [Link],
height: '50%',
width: '100%',
borderRadius: 15,
paddingHorizontal: 3,
alignItems: 'center',
justifyContent: 'center',
},
smallInfoBody: {
textAlign: 'center',
color: [Link],
},
infoContainer: {
marginTop: 30,
marginBottom: 20,
},
infoWrapper: {
display: 'flex',
alignItems: 'flex-start',
marginBottom: 15,
},
infoHeaderWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 3,
borderRadius: 5,
backgroundColor: [Link],
paddingVertical: 3,
flexShrink: 1,
},
infoHeader: {
fontSize: 20,
color: [Link],
paddingHorizontal: 10,
fontWeight: '500',
paddingVertical: 2,
},
infoBody: {
lineHeight: 28,
marginTop: 10,
marginBottom: 25,
color: [Link],
},
});
export default MyPlantScreen;
67
Figure 5. 7 PlantRecognitionScreen
68
return;
}
const pickerResult = await [Link]();
if (![Link]) {
[Link](pickerResult)
setProcessing(true);
recognizePlant(pickerResult?.assets[0], navigation, setProcessing);
}
};
const [permission, requestPermission] = useCameraPermissions();
[Link](permission)
if (!permission) {
// Camera permissions are still loading.
return <View />;
}
if (![Link]) {
// Camera permissions are not granted yet.
return (
<View style={{ flex: 1,
justifyContent: 'center',}}>
<Text>We need your permission to show the camera</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
);
}
// useEffect(() => {
// (async () => {
// const { status } = await [Link]();
// setHasPermission(status === 'granted');
// })();
// }, []);
// if (hasPermission === null) {
// return <View />;
// }
// if (hasPermission === false) {
// return <Text>No access to camera</Text>;
// }
return (
<View style={{ flex: 1 }}>
<CameraView
style={{ flex: 1, justifyContent: 'flex-end' }}
facing={type}
flash={flash}
ref={(ref) => {
setCameraRef(ref);
}}>
<View style={{ position: 'absolute', top: 60, alignSelf: 'center' }}>
<Text style={{ marginTop: 100, color: [Link], alignSelf: 'center' }}>
Please take a picture of your house plant
</Text>
<View
style={{
width: 300,
height: 350,
borderWidth: 2,
borderColor: [Link],
marginTop: 30,
}}
69
/>
</View>
<View style={{ position: 'absolute', bottom: 100, left: 35 }}>
<TouchableOpacity onPress={openImagePickerAsync}>
<Ionicons name="images" size={50} color={[Link]} />
</TouchableOpacity>
</View>
<View
style={{
backgroundColor: '#00000099',
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 15,
paddingHorizontal: 35,
}}>
<TouchableOpacity
style={{
width: 40,
alignItems: 'center',
paddingTop: 10,
}}
onPress={() => {
setFlash(current => (current === 'off' ? 'on' : 'off'));
}}>
{flash === 'off' ? (
<Ionicons name="flash-off" size={35} color={[Link]} />
):(
<Ionicons name="flash" size={35} color={[Link]} />
)}
</TouchableOpacity>
<TouchableOpacity
onPress={async () => {
setProcessing(true);
setTimeout(() => {
setStuck(true);
}, 10000);
if (cameraRef) {
// Taken photo is here
await [Link]({
skipProcessing: true,
onPictureSaved: async (photo) => {
[Link]("photo===",photo)
recognizePlant(photo, navigation, setProcessing, stuck);
},
});
// We can use the uri property from photo to reach the taken picture and do what we want.
// ImagePicker saves the taken photo to disk and returns a local URI to it
}
}}>
{processing ? (
<ActivityIndicator size="large" color={[Link]} />
):(
<View
style={{
borderWidth: 2,
borderColor: [Link],
borderRadius: 50,
height: 50,
70
width: 50,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
<View
style={{
borderWidth: 2,
borderRadius: 50,
borderColor: [Link],
height: 40,
width: 40,
backgroundColor: [Link],
}}
/> </View> )}
</TouchableOpacity>
<TouchableOpacity
style={{
width: 40,
alignItems: 'center',
paddingTop: 10, }}
onPress={() => {
setType(current => (current === 'back' ? 'front' : 'back')); }}>
<Ionicons name="camera-reverse" size={35} color={[Link]} />
</TouchableOpacity> </View> </CameraView> </View> );};
export default PlantRecognitionScreen;
Figure 5. 8 SearchScreen
71
import React from 'react';
import { StyleSheet, Modal, ImageBackground, View } from 'react-native';
import { SearchBar } from 'react-native-elements';
import { useDispatch, useSelector } from 'react-redux';
import { FontAwesome5 } from '@expo/vector-icons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import plantData from '../data/[Link]';
import photo from '../assets/images/[Link]';
import SearchFieldModal from '../components/SearchFieldModal';
import GreenthumbOpacity from '../components/GreenthumbOpacity';
import Colors from '../constants/Colors';
const SearchScreen = ({ navigation }) => {
const dispatch = useDispatch();
const [modalVisibles, setModalVisibles] = [Link](false);
return (
<>
<ImageBackground source={photo} style={[Link]}>
{modalVisibles && <Modal visible={modalVisibles} animationType="slide"
onBackdropPress={() => setModalVisibles(false)}
onRequestClose={() => {
setModalVisibles(!modalVisibles);
}}>
<SearchFieldModal plantData={plantData} setModalVisibles={setModalVisibles} dispatch={dispatch} />
</Modal>}
<SearchBar
disabled
round
containerStyle={{
position: 'absolute',
top: 50,
alignSelf: 'center',
width: 350,
borderColor: [Link],
backgroundColor: [Link],
borderBottomColor: [Link],
borderTopColor: [Link], }}
onPress={() => setModalVisibles(!modalVisibles)}
inputContainerStyle={{
backgroundColor: [Link],
position: 'absolute',
zIndex: 0, }}
searchIcon={{ backgroundColor: [Link], paddingLeft: 10 }}
placeholder="Search for plants" />
<GreenthumbOpacity
onPress={() => setModalVisibles(!modalVisibles)}
activeOpacity={0.7}
style={[Link]} />
<View style={[Link]}>
<TouchableOpacity
style={[Link]}
activeOpacity={0.8}
onPress={() => [Link]('Plant Recognition')}>
<FontAwesome5 name="camera" size={50} color={[Link]} />
</TouchableOpacity>
</View> </ImageBackground> </> );};
const styles = [Link]({
search: {
paddingTop: 100, },
72
touchableArea: {
marginTop: 20,
height: '25%',
alignItems: 'center', },
cameraButtonWrapper: {
position: 'absolute',
top: '50%',
alignSelf: 'center', },
cameraButton: {
alignSelf: 'center',
width: 107,
height: 107,
backgroundColor: [Link],
justifyContent: 'center',
alignItems: 'center',
borderRadius: 100,
borderWidth: 6,
borderColor: [Link],
opacity: 0.92, },
photo: {
width: '100%',
height: '100%',
resizeMode: 'cover',
position: 'absolute',
zIndex: 0, },});
export default SearchScreen;
Figure 5. 9 IndividualPlantScreen
73
import {
Entypo,
AntDesign,
FontAwesome5,
MaterialCommunityIcons,
Ionicons,
} from '@expo/vector-icons';
import React, { useRef, useState } from 'react';
// import BottomSheet from 'reanimated-bottom-sheet';
import {
BottomSheetModal,
BottomSheetView,
BottomSheetModalProvider,
} from '@gorhom/bottom-sheet';
import { useDispatch, useSelector } from 'react-redux';
import { StyleSheet, TouchableWithoutFeedback, Image, Text, View, TouchableOpacity } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, { Layout, Easing } from 'react-native-reanimated';
import { showMessage } from 'react-native-flash-message';
import { useNavigation } from '@react-navigation/native';
import GreenthumbOpacity from '../components/GreenthumbOpacity';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { updateUser } from '../firebase';
import { auth, db } from '../firebase/config';
import { doc, setDoc } from 'firebase/firestore';
import Colors from '../constants/Colors';
const IndividualPlantScreen = (navigation) => {
const dispatch = useDispatch();
const userID = useSelector((state) => [Link]);
const navigate = useNavigation();
// arrow transition for bottom sheet
// const transition = <[Link] interpolation="easeInOut" />;
[Link]("userID====",userID)
const [deg, setDeg] = useState(180);
const ref = useRef();
const plant = [Link];
[Link](plant)
const generateId = () => {
return "plant_" + [Link](); // Example: plant_1710354762000
};
const addPlantHandler = async (selectedPlant) => {
// TODO: Rename plants collection
// firebase
// .firestore()
// .collection('plants')
// .add({ ...selectedPlant, userID });
try {
const user = [Link]; // Get logged-in user
if (!user) {
throw new Error("User not authenticated"); }
const plantId = generateId();
const plantRef = doc(db, "plants", plantId); // Create a Firestore document reference
await setDoc(plantRef, { ...selectedPlant, userID: userID });
[Link]('Plant added successfully!');
dispatch(updateUser(userID));
showMessage({
message: 'Plant added',
74
description: 'Click here to go My Garden',
type: 'success',
animated: true,
icon: 'success',
onPress: () => [Link]("MainTab", { screen: "MyGarden" }),
});
} catch (error) {
[Link]("Error adding plant:", error);
}
};
<View>
<Text style={[Link]}>{plant?.commonName}</Text>
<Text style={[Link]}>{plant?.scientificName}</Text>
</View>
<View style={[Link]}>
<GreenthumbOpacity onPress={() => addPlantHandler(plant)}>
<NeuMorph>
<View style={{ marginBottom: 30 }}>
<LinearGradient
colors={[[Link], [Link], [Link]]}
start={[0.0, 0.0]}
end={[1.0, 1.0]}
style={{
width: 240,
borderRadius: 17,
padding: 10,
elevation: 3,
}}>
<Text
style={{
textAlign: 'center',
fontSize: 16,
color: [Link],
fontWeight: '600',
}}>
Add To My Garden
</Text>
</LinearGradient>
</View>
</NeuMorph>
</GreenthumbOpacity>
</View>
<ScrollView style={[Link]}>
75
<Text style={[Link]}>{plant?.description}</Text>
<View style={[Link]}>
<View style={[Link]}>
<Entypo
style={[Link]}
name="globe"
size={80}
color={[Link]}
/>
<Text style={[Link]}>Origin:</Text>
<Text style={[Link]}>{plant?.origin}</Text>
</View>
<View style={[Link]}>
<Entypo
style={[Link]}
name="price-tag"
size={80}
color={[Link]}
/>
<Text style={[Link]}>Family:</Text>
<Text style={[Link]}>{plant?.familyName}</Text>
</View>
<View style={[Link]}>
<Entypo
style={[Link]}
name="tree"
size={80}
color={[Link]}
/>
<Text style={[Link]}>Growth:</Text>
<Text style={[Link]}>{plant?.maxGrowth}</Text>
</View>
<View style={[Link]}>
<AntDesign
style={[Link]}
name="warning"
size={80}
color={[Link]}
/>
<Text style={[Link]}>Poisonous:</Text>
<Text style={[Link]}>{plant?.poisonousForPets}</Text>
</View>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons
name="temperature-celsius"
size={20}
color={[Link]}
/>
<Text style={[Link]}>Temperature</Text>
</View>
<Text style={[Link]}>{plant?.temperature}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="light-up" size={20} color={[Link]} />
<Text style={[Link]}>Light</Text>
76
</View>
<Text style={[Link]}>{plant?.light}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo
name="drop"
size={14}
color={[Link]}
style={[Link]}
/>
<Text style={[Link]}>Water</Text>
</View>
<Text style={[Link]}>{plant?.watering}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons name="pot" size={20} color={[Link]} />
<Text style={[Link]}>Soil</Text>
</View>
<Text style={[Link]}>{plant?.soil}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="bucket" size={20} color={[Link]} />
<Text style={[Link]}>Re-Potting</Text>
</View>
<Text style={[Link]}>{plant?.rePotting}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<MaterialCommunityIcons name="spray-bottle" size={20} color={[Link]} />
<Text style={[Link]}>Fertilizer</Text>
</View>
<Text style={[Link]}>{plant?.fertilizer}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<Entypo name="water" size={20} color={[Link]} />
<Text style={[Link]}>Humidity</Text>
</View>
<Text style={[Link]}>{plant?.humidity}</Text>
</View>
<View style={[Link]}>
<View style={[Link]}>
<FontAwesome5 name="seedling" size={20} color={[Link]} />
<Text style={[Link]}>Propagation</Text>
</View>
<Text style={[Link]}>{plant?.propagation}</Text>
</View>
</ScrollView>
</View>
</View>
)
};
const bs = [Link](null);
// Snap points
const snapPoints = ['39%', '85%'];
77
[Link](() => {
// Automatically open the bottom sheet on mount
[Link]?.present();
}, []);
return (
<GestureHandlerRootView>
<BottomSheetModalProvider>
{/* Bottom Sheet Modal */}
<BottomSheetModal
ref={bs}
snapPoints={snapPoints}
onDismiss={handleClose}
enableDynamicSizing={false}
handleStyle={{ backgroundColor: [Link] }} // Custom handle color
backgroundStyle={{ backgroundColor: [Link] }} // Custom sheet color
handleIndicatorStyle={{ backgroundColor: [Link] }}
index={0}
enablePanDownToClose={false}
onChange={(index) => setActiveSnap(index)} // Track active snap point
handleComponent={() => (
<[Link]
ref={ref}
layout={[Link]([Link]([Link]))}
style={{ alignItems: 'center',marginTop:20 }}
>
<Ionicons
name={activeSnap === 1 ? 'chevron-down' : 'chevron-up'}
size={24}
color={[Link]}
/>
</[Link]>
)}
>
<BottomSheetView style={[Link]}>
<RenderContent />
</BottomSheetView>
</BottomSheetModal>
<View style={[Link]}>
<TouchableWithoutFeedback onPress={() => handleOpen()}>
<Image style={[Link]} source={{ uri: plant?.images?.imagePrimary }} />
</TouchableWithoutFeedback>
78
</View>
</BottomSheetModalProvider>
</GestureHandlerRootView>
// <View style={[Link]}>
// <BottomSheet
// ref={bs}
// snapPoints={['39%', '85%']}
// initialSnap={0}
// renderContent={renderContent}
// enabledBottomClamp
// onOpenEnd={() => {
// [Link]();
// setDeg(180);
// }}
// onCloseEnd={() => {
// [Link]();
// setDeg(0);
// }}
// />
// <TouchableWithoutFeedback onPress={() => [Link](0)}>
// <Image style={[Link]} source={{ uri: plant?.images?.imagePrimary }} />
// </TouchableWithoutFeedback>
// </View>
);
};
export default IndividualPlantScreen;
const styles = [Link]({
topShadow: {
shadowOffset: {
width: -2,
height: -2,
},
shadowOpacity: 0.5,
shadowRadius: 3,
shadowColor: [Link],
},
bottomShadow: {
shadowOffset: {
width: 3,
height: 3,
},
shadowOpacity: 0.8,
shadowRadius: 3,
shadowColor: [Link],
},
container: {
flex:1
},
sheetContent: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
background: {
height: '64%',
width: '100%',
79
},
contentWrapper: {
height: '100%',
width: '100%',
},
content: {
backgroundColor: [Link],
borderTopRightRadius: 50,
paddingHorizontal: 20,
paddingTop: 10,
width: '100%',
flex: 1,
},
nameGeneric: {
color: [Link],
fontSize: 28,
marginBottom: 10,
},
nameScientific: {
color: [Link],
marginBottom: 20,
fontSize: 16,
fontStyle: 'italic',
},
btnContainer: {
flexDirection: 'row',
alignItems: 'center',
width: ' 100%',
},
text: {
color: [Link],
lineHeight: 28,
marginBottom: 15,
},
shortInfoContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
width: '100%',
marginBottom: 20,
},
shortInfoElement: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '44%',
backgroundColor: [Link],
height: 120,
borderRadius: 10,
margin: 9,
position: 'relative',
},
shortInfoIcon: {
position: 'absolute',
},
shortInfoHeadline: {
color: [Link],
80
fontWeight: 'bold',
fontSize: 16,
marginBottom: 5,
},
shortInfoText: {
color: [Link],
width: '90%',
textAlign: 'center',
},
infoWrapper: {
display: 'flex',
alignItems: 'flex-start',
},
infoHeaderWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
backgroundColor: [Link],
paddingVertical: 5,
paddingHorizontal: 15,
borderRadius: 5,
flexShrink: 1,
},
infoHeader: {
fontSize: 20,
color: [Link],
marginLeft: 10,
},
infoBody: {
color: [Link],
lineHeight: 28,
marginTop: 10,
marginBottom: 25,
},
});
81
Chapter (6): Testing and Evaluation
The primary goals of the testing phase for the Home Garden App were to:
Verify Functionality: Ensure that all implemented features of the app, such as
plant identification, personalized care recommendations, garden planning, and
educational resource viewing, function correctly and according to the defined
functional requirements.
Ensure Reliability: Confirm that the app operates consistently and without failure
under various conditions, including different network connectivity, device
specifications, and user load.
Validate Usability: Evaluate the app's user-friendliness, intuitiveness, and ease of
navigation, ensuring a positive and efficient experience for users of all technical
skill levels.
Confirm Performance: Assess the app's responsiveness, loading times, and
resource consumption to guarantee a smooth and efficient user experience without
excessive battery drain or data usage.
82
Verify Security: Ensure the security of user data, authentication processes, and
protection against potential vulnerabilities, especially concerning user accounts and
any sensitive information.
Validate Compatibility: Confirm that the app functions correctly and consistently
across a range of target devices and operating system versions (iOS and Android)
as specified in the non-functional requirements.
Identify and Resolve Defects: Systematically identify, document, and facilitate
the resolution of any bugs, errors, or inconsistencies found within the application.
Gather User Feedback: Collect feedback from testers (including potential end-
users) to identify areas for improvement in both functionality and user experience.
The Testing Scope of the Home Garden App defines what parts of the app we will test
and what parts we will not test. For this project, our testing will focus on making sure the
main features work correctly. This includes:
We will also test how well the app performs (how fast it loads and responds) and how
easy it is to use. Things that might be outside the scope of our initial testing could be very
specific edge cases, integrations with future hardware, or testing on extremely old or
uncommon devices. Our focus is on the core features that most users will interact with on
a daily basis.
83
6.3 Testing Strategy
Testing Strategy is like our plan for how we will test the app. It is the overall approach
we will take to make sure everything works well.
Testing different parts at different times: We will start by testing small pieces of
the app (like the login screen or the plant search) to make sure they work on their
own. Then we will test how these pieces work together.
Using different methods: We will have people try to use the app as regular
gardeners would (this is called user testing) to check if things are still working
correctly as we make changes.
Focusing on what is important: We will spend more time testing the features that
users will use the most and the parts that are most likely to have problems.
Fixing problems as we find them: When we find a bug or something that does not
work right, we will report it to the developers so they can fix it. We will then test
the fix to make sure it works.
Getting feedback from users: We will ask people who will actually use the app to
try it out and tell us what they think. This helps us make sure the app is easy to use
and meets their needs.
Our main goal with this testing strategy is to catch as many problems as possible
before we release the app to everyone, so it is a smooth and enjoyable experience for all
home gardeners.
Testing Verification is like checking if we built the app correctly. We look at what we
were supposed to build (the requirements) and then check if the actual app we built matches
those plans. It is about making sure we "did it right" according to what we said we would
84
do. For example, if the plan said the plant identification should show the plant's name,
verification is checking if the app actually shows the name after identifying a plant.
Stages of Testing are like the different steps we take to test the app. We don't just
test everything all at once. Think of it like this:
Small Piece Test (Unit Testing): We test each tiny part of the app by itself to see if
it works. Like checking if the "login button" does its job.
Putting Together Test (Integration Testing): We test if the different parts of the app
work well together. Like checking if the "login button" actually lets you into your
account.
Whole App Test (System Testing): We test the entire app as one complete thing to
see if all the features work as expected. Like trying to use all the gardening tools in
the app.
User Tryout (User Acceptance Testing): We let real users try the app to see if it's easy
to use and if it does what they need. Like asking a gardener if the app helps them.
These stages help us find problems early and make sure the app is good before
everyone uses it.
We need to check two main things: how the app looks and feels (the interface) and
how the app saves and uses information (the database).
Interface Testing is like checking if all the buttons are in the right place, if the
pictures look good, and if it is easy for gardeners to use the app.
Database Testing is like checking if the app saves all the plant info and user details
correctly, and if it can find that information again when it needs it. We want to
make sure no information is lost or mixed up.
85
6.6.1 Test Cases
1- Registration
The current module is about registration process. As the user need to get privileges to
log in to the system. So the form is filled with own information then pressing the “Submit”
button to confirm.
2- Authentication
The user need to authenticate with the given privileges. So in this form fills the needed
username and password then presses “Sign in” button to confirm.
86
3- Search
After authentication, the user search for a plant or add a new one.
4- Browsing a plant
The user as soon as choose to browse a plant, he can add it to his own garden profile.
87
5- My garden profile
Figure 6. 5 My Garden
This is a result of adding a plant to user garden profile. As the user choose the plant
then add it and presses the button “My Garden” to proceed to the list of garden plant.
6- Set Reminder
88
The current interface has some action described as follows:-
Step 1: Select Plant: Tap on the "Aloe Vera" button. Verify that this action
either displays a list of the user's plants to choose from or confirms that the
reminder will be set for the "Aloe Vera" plant currently being viewed.
Step 2: Choose Reminder Type: Tap on the "Water" button. Confirm that this
action either presents a list of reminder types (e.g., Water, Fertilize, Repot) or
indicates that "Water" has been selected as the reminder action.
Step 3: Adjust Date and Time: Tap on "April 25th, 5:15 am". Verify that a
calendar and time picker interface appears, allowing the user to modify the
date and time for the reminder.
Step 4: Set Reminder: After making selections (plant, reminder type,
date/time), tap on the "Set Reminder" button. Confirm that a notification or
visual confirmation appears indicating that the reminder has been successfully
set.
7- Notification
The user gets an notification as shown in the figure after confirming reminder. The
notification contains an alarm icon with the time and date specified with ability to be
cancelled.
89
6.6.2 Test Results
In short, our testing for the app is like having a group of helpers try out all the different
parts to make sure everything works like it should. We check if the buttons do what they
say, if the app is easy to use, and if it does not break. This helps us find and fix any mistakes
before we give the app to all the gardeners, so it is a good and helpful tool for them.
90
Chapter (7): Conclusion & Recommendation
7.1 Conclusion
We built this Home Garden App to help everyone who wants to grow plants at home.
We wanted to make it easy, even if you do not know much about gardening. After working
hard and testing everything, we think the app does a good job of what we planned. It can
help you figure out what plant you have, tell you how to take care of it, and even let you
talk to other gardeners. We learned a lot while making this app, and we think it can really
help people enjoy gardening more. It puts all the important plant info and tools right in
your pocket. We hope that people who use the app will find it helpful and that it will make
their gardening experience easier and more fun. We are happy with how it turned out, and
we think it is a good step towards helping everyone grow their own little green spaces.
Even though we think the app is good now, there are still ways we can make it even
better in the future:
Smarter Plant Helper: Maybe the app could learn what plants you have and where
you live and give you even more special advice, like telling you exactly when to
water based on the weather near you.
See Your Garden Grow: It would be cool if you could take pictures of your plants
over time and the app could show you how they are growing. Like a little plant
diary.
Talk to Local Gardeners: Maybe we could add a way to connect with other
gardeners who live close to you, so you can share tips that work in your area.
Help with Problems: If your plant looks sick, maybe you could take a picture and
the app could help you figure out what is wrong and how to fix it.
91
Remind You Better: We could make the reminders even smarter, so they do not just
tell you to water, but maybe how much water based on the plant and the weather.
More Plants: We can always add more plants to the app's library so it can help even
more people with different kinds of plants.
Making it Work with Other Tools: Maybe the app could connect to smart watering
cans or soil sensors to make taking care of plants even easier.
Helping You Find Plants: We could add a feature that helps you figure out what
plants would grow best in your garden based on the sunlight and soil you have.
Teaching You More: We could add more simple guides and videos to teach you the
basics of gardening.
Making it Look Even Nicer: We can always make the app look even better and
easier to use.
We want to keep making the Home Garden App more helpful and fun for everyone
who loves plants. We will listen to what people who use the app say and try to add the
things that would help them the most. Our goal is to make it the best gardening helper out
there.
92
References
[1] Skidmore, S. and Eva, M. (2003) Introducing systems development. Basingstoke: Palgrave
Macmillan.
[2] Satzinger. John, [Link] & Burd. Stephen. (2009). Systems Analysis and Design in
a Changing World, 6th Edition. USA.
[3] Fakhroutdinov, K. (2019). Unified Modeling Language (UML) description. [online] Uml-
[Link]. Available at: [Link] (Accessed: 08 October 2024).
[4] Meadows, D.H. and Wright, D. (2009) Thinking in systems: A Primer. London: Taylor &
Francis.
93