diff --git a/.gitignore b/.gitignore
index 14106d4..9f0bb74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,26 +12,25 @@
/captures
.externalNativeBuild
.cxx
-local.properties
-
-#amplify-do-not-edit-begin
-amplify/\#current-cloud-backend
-amplify/.config/local-*
-amplify/logs
-amplify/mock-data
-amplify/backend/amplify-meta.json
-amplify/backend/awscloudformation
-amplify/backend/.temp
-build/
-dist/
-node_modules/
-aws-exports.js
-awsconfiguration.json
-amplifyconfiguration.json
-amplifyconfiguration.dart
-amplify-build-config.json
-amplify-gradle-config.json
-amplifytools.xcconfig
-.secret-*
-**.sample
-#amplify-do-not-edit-end
+local.properties
+
+#amplify-do-not-edit-begin
+amplify/\#current-cloud-backend
+amplify/.config/local-*
+amplify/logs
+amplify/mock-data
+amplify/backend/amplify-meta.json
+amplify/backend/.temp
+build/
+dist/
+node_modules/
+aws-exports.js
+awsconfiguration.json
+amplifyconfiguration.json
+amplifyconfiguration.dart
+amplify-build-config.json
+amplify-gradle-config.json
+amplifytools.xcconfig
+.secret-*
+**.sample
+#amplify-do-not-edit-end
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..9976b04
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Thrifty
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..772150e
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 34c1ecc..897d8a0 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,7 +3,23 @@
@@ -13,4 +29,11 @@
+
+
+
\ No newline at end of file
diff --git a/amplify/.config/project-config.json b/amplify/.config/project-config.json
deleted file mode 100644
index 83e29b3..0000000
--- a/amplify/.config/project-config.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "projectName": "Thrifty",
- "version": "3.1",
- "frontend": "android",
- "android": {
- "config": {
- "ResDir": "app/src/main/res"
- }
- },
- "providers": [
- "awscloudformation"
- ]
-}
\ No newline at end of file
diff --git a/amplify/README.md b/amplify/README.md
deleted file mode 100644
index 7c0a9e2..0000000
--- a/amplify/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Getting Started with Amplify CLI
-This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli).
-
-Helpful resources:
-- Amplify documentation: https://docs.amplify.aws
-- Amplify CLI documentation: https://docs.amplify.aws/cli
-- More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files
-- Join Amplify's community: https://amplify.aws/community/
diff --git a/amplify/backend/analytics/ThriftyOWUjV/parameters.json b/amplify/backend/analytics/ThriftyOWUjV/parameters.json
deleted file mode 100644
index 6ee94f9..0000000
--- a/amplify/backend/analytics/ThriftyOWUjV/parameters.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "appName": "ThriftyOWUjV",
- "roleName": "pinpointLambdaRolee733af87",
- "cloudformationPolicyName": "cloudformationPolicye733af87",
- "cloudWatchPolicyName": "cloudWatchPolicye733af87",
- "pinpointPolicyName": "pinpointPolicye733af87",
- "authPolicyName": "pinpoint_amplify_e733af87",
- "unauthPolicyName": "pinpoint_amplify_e733af87",
- "authRoleName": {
- "Ref": "AuthRoleName"
- },
- "unauthRoleName": {
- "Ref": "UnauthRoleName"
- },
- "authRoleArn": {
- "Fn::GetAtt": [
- "AuthRole",
- "Arn"
- ]
- },
- "appId": "f06bd624184f4c90bc7556672ddd9619"
-}
\ No newline at end of file
diff --git a/amplify/backend/analytics/ThriftyOWUjV/pinpoint-cloudformation-template.json b/amplify/backend/analytics/ThriftyOWUjV/pinpoint-cloudformation-template.json
deleted file mode 100644
index 27ff3d0..0000000
--- a/amplify/backend/analytics/ThriftyOWUjV/pinpoint-cloudformation-template.json
+++ /dev/null
@@ -1,590 +0,0 @@
-{
- "AWSTemplateFormatVersion": "2010-09-09",
- "Description": "Pinpoint resource stack creation using Amplify CLI",
- "Parameters": {
- "appName": {
- "Type": "String"
- },
- "appId": {
- "Type": "String",
- "Default": "NONE"
- },
- "roleName": {
- "Type": "String"
- },
- "cloudformationPolicyName": {
- "Type": "String"
- },
- "cloudWatchPolicyName": {
- "Type": "String"
- },
- "pinpointPolicyName": {
- "Type": "String"
- },
- "authPolicyName": {
- "Type": "String"
- },
- "unauthPolicyName": {
- "Type": "String"
- },
- "authRoleName": {
- "Type": "String"
- },
- "unauthRoleName": {
- "Type": "String"
- },
- "authRoleArn": {
- "Type": "String"
- },
- "env": {
- "Type": "String"
- }
- },
- "Metadata": {
- "AWS::CloudFormation::Interface": {
- "ParameterGroups": [
- {
- "Label": {
- "default": "Creating pinpoint app"
- },
- "Parameters": [
- "appName"
- ]
- }
- ]
- }
- },
- "Conditions": {
- "ShouldCreatePinpointApp": {
- "Fn::Equals": [
- {
- "Ref": "appId"
- },
- "NONE"
- ]
- },
- "ShouldNotCreateEnvResources": {
- "Fn::Equals": [
- {
- "Ref": "env"
- },
- "NONE"
- ]
- }
- },
- "Resources": {
- "LambdaExecutionRole": {
- "Condition": "ShouldCreatePinpointApp",
- "Type": "AWS::IAM::Role",
- "Properties": {
- "RoleName": {
- "Fn::If": [
- "ShouldNotCreateEnvResources",
- {
- "Ref": "roleName"
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Ref": "roleName"
- },
- "-",
- {
- "Ref": "env"
- }
- ]
- ]
- }
- ]
- },
- "AssumeRolePolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Principal": {
- "Service": [
- "lambda.amazonaws.com"
- ]
- },
- "Action": [
- "sts:AssumeRole"
- ]
- }
- ]
- },
- "Policies": [
- {
- "PolicyName": {
- "Ref": "cloudWatchPolicyName"
- },
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "logs:CreateLogGroup",
- "logs:CreateLogStream",
- "logs:PutLogEvents"
- ],
- "Resource": "arn:aws:logs:*:*:*"
- }
- ]
- }
- },
- {
- "PolicyName": {
- "Ref": "pinpointPolicyName"
- },
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "mobileanalytics:*",
- "mobiletargeting:*"
- ],
- "Resource": "*"
- }
- ]
- }
- },
- {
- "PolicyName": {
- "Ref": "cloudformationPolicyName"
- },
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "cloudformation:*"
- ],
- "Resource": "*"
- }
- ]
- }
- }
- ]
- }
- },
- "PinpointFunction": {
- "Type": "AWS::Lambda::Function",
- "Condition": "ShouldCreatePinpointApp",
- "Properties": {
- "Code": {
- "ZipFile": {
- "Fn::Join": [
- "\n",
- [
- "const response = require('cfn-response');",
- "const aws = require('aws-sdk');",
- "exports.handler = function(event, context) {",
- " if (event.RequestType == 'Delete') {",
- " const stackID = event.StackId;",
- " const cloudFormationClient = new aws.CloudFormation({ apiVersion: '2016-12-01', region: event.ResourceProperties.region });",
- " cloudFormationClient.describeStacks({ StackName: stackID }).promise()",
- " .then(describeStacksOutput => {",
- " let appId;",
- " if (describeStacksOutput.Stacks && describeStacksOutput.Stacks.length > 0) {",
- " const { Outputs } = describeStacksOutput.Stacks[0];",
- " const appIdOutput = Outputs.find((output)=>{ return output.OutputKey === 'Id'});",
- " appId = appIdOutput ? appIdOutput.OutputValue : undefined; ",
- " }",
- " return appId;",
- " })",
- " .then(appId => {",
- " if (appId) {",
- " const pinpointClient = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
- " const params = {",
- " ApplicationId: appId,",
- " };",
- " pinpointClient.deleteApp(params).promise();",
- " }",
- " })",
- " .then(()=>{",
- " response.send(event, context, response.SUCCESS, {'message': `Successfully deleted pinpoint project`});",
- " })",
- " .catch(e=>{",
- " response.send(event, context, response.FAILED, {'message': `Failed to deleted Pinpoint project`, 'exception': e});",
- " }); ",
- " }",
- " if (event.RequestType == 'Update') {",
- " response.send(event, context, response.SUCCESS);",
- " return;",
- " }",
- " if (event.RequestType == 'Create') {",
- " const appName = event.ResourceProperties.appName;",
- " let responseData = {};",
- " const params = {",
- " CreateApplicationRequest: {",
- " Name: appName",
- " }",
- " };",
- " const pinpoint = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
- " pinpoint.createApp(params).promise()",
- " .then((res) => {",
- " responseData = res.ApplicationResponse;",
- " response.send(event, context, response.SUCCESS, responseData);",
- " }).catch((err) => {",
- " console.log(err.stack);",
- " responseData = {Error: err};",
- " response.send(event, context, response.FAILED, responseData);",
- " throw err;",
- " });",
- " }",
- "};"
- ]
- ]
- }
- },
- "Handler": "index.handler",
- "Runtime": "nodejs12.x",
- "Timeout": 300,
- "Role": {
- "Fn::GetAtt": [
- "LambdaExecutionRole",
- "Arn"
- ]
- }
- }
- },
- "PinpointFunctionOutputs": {
- "Type": "Custom::LambdaCallout",
- "Condition": "ShouldCreatePinpointApp",
- "Properties": {
- "ServiceToken": {
- "Fn::GetAtt": [
- "PinpointFunction",
- "Arn"
- ]
- },
- "region": {
- "Ref": "AWS::Region"
- },
- "pingPointRegion": {
- "Fn::FindInMap": [
- "RegionMapping",
- {
- "Ref": "AWS::Region"
- },
- "pinpointRegion"
- ]
- },
- "appName": {
- "Fn::If": [
- "ShouldNotCreateEnvResources",
- {
- "Ref": "appName"
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Ref": "appName"
- },
- "-",
- {
- "Ref": "env"
- }
- ]
- ]
- }
- ]
- }
- },
- "DependsOn": "PinpointFunction"
- },
- "CognitoUnauthPolicy": {
- "Type": "AWS::IAM::Policy",
- "Condition": "ShouldCreatePinpointApp",
- "Properties": {
- "PolicyName": {
- "Ref": "unauthPolicyName"
- },
- "Roles": [
- {
- "Ref": "unauthRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "mobiletargeting:PutEvents",
- "mobiletargeting:UpdateEndpoint"
- ],
- "Resource": [
- {
- "Fn::If": [
- "ShouldCreatePinpointApp",
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:mobiletargeting:*:",
- {
- "Fn::Select": [
- "4",
- {
- "Fn::Split": [
- ":",
- {
- "Ref": "authRoleArn"
- }
- ]
- }
- ]
- },
- ":apps/",
- {
- "Fn::GetAtt": [
- "PinpointFunctionOutputs",
- "Id"
- ]
- },
- "*"
- ]
- ]
- },
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:mobiletargeting:*:",
- {
- "Fn::Select": [
- "4",
- {
- "Fn::Split": [
- ":",
- {
- "Ref": "authRoleArn"
- }
- ]
- }
- ]
- },
- ":apps/",
- {
- "Ref": "appId"
- },
- "*"
- ]
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "CognitoAuthPolicy": {
- "Type": "AWS::IAM::Policy",
- "Condition": "ShouldCreatePinpointApp",
- "Properties": {
- "PolicyName": {
- "Ref": "authPolicyName"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "mobiletargeting:PutEvents",
- "mobiletargeting:UpdateEndpoint"
- ],
- "Resource": [
- {
- "Fn::If": [
- "ShouldCreatePinpointApp",
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:mobiletargeting:*:",
- {
- "Fn::Select": [
- "4",
- {
- "Fn::Split": [
- ":",
- {
- "Ref": "authRoleArn"
- }
- ]
- }
- ]
- },
- ":apps/",
- {
- "Fn::GetAtt": [
- "PinpointFunctionOutputs",
- "Id"
- ]
- },
- "*"
- ]
- ]
- },
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:mobiletargeting:*:",
- {
- "Fn::Select": [
- "4",
- {
- "Fn::Split": [
- ":",
- {
- "Ref": "authRoleArn"
- }
- ]
- }
- ]
- },
- ":apps/",
- {
- "Ref": "appId"
- },
- "*"
- ]
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- }
- }
- },
- "Outputs": {
- "Region": {
- "Value": {
- "Fn::FindInMap": [
- "RegionMapping",
- {
- "Ref": "AWS::Region"
- },
- "pinpointRegion"
- ]
- }
- },
- "Id": {
- "Value": {
- "Fn::If": [
- "ShouldCreatePinpointApp",
- {
- "Fn::GetAtt": [
- "PinpointFunctionOutputs",
- "Id"
- ]
- },
- {
- "Ref": "appId"
- }
- ]
- }
- },
- "appName": {
- "Value": {
- "Fn::If": [
- "ShouldCreatePinpointApp",
- {
- "Fn::GetAtt": [
- "PinpointFunctionOutputs",
- "Name"
- ]
- },
- {
- "Ref": "appName"
- }
- ]
- }
- }
- },
- "Mappings": {
- "RegionMapping": {
- "us-east-1": {
- "pinpointRegion": "us-east-1"
- },
- "us-east-2": {
- "pinpointRegion": "us-east-1"
- },
- "sa-east-1": {
- "pinpointRegion": "us-east-1"
- },
- "ca-central-1": {
- "pinpointRegion": "ca-central-1"
- },
- "us-west-1": {
- "pinpointRegion": "us-west-2"
- },
- "us-west-2": {
- "pinpointRegion": "us-west-2"
- },
- "cn-north-1": {
- "pinpointRegion": "us-west-2"
- },
- "cn-northwest-1": {
- "pinpointRegion": "us-west-2"
- },
- "ap-south-1": {
- "pinpointRegion": "ap-south-1"
- },
- "ap-northeast-3": {
- "pinpointRegion": "us-west-2"
- },
- "ap-northeast-2": {
- "pinpointRegion": "ap-northeast-2"
- },
- "ap-southeast-1": {
- "pinpointRegion": "ap-southeast-1"
- },
- "ap-southeast-2": {
- "pinpointRegion": "ap-southeast-2"
- },
- "ap-northeast-1": {
- "pinpointRegion": "ap-northeast-1"
- },
- "eu-central-1": {
- "pinpointRegion": "eu-central-1"
- },
- "eu-north-1": {
- "pinpointRegion": "eu-central-1"
- },
- "eu-west-1": {
- "pinpointRegion": "eu-west-1"
- },
- "eu-west-2": {
- "pinpointRegion": "eu-west-2"
- },
- "eu-west-3": {
- "pinpointRegion": "eu-west-1"
- },
- "me-south-1": {
- "pinpointRegion": "ap-south-1"
- }
- }
- }
-}
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty/parameters.json b/amplify/backend/api/thrifty/parameters.json
deleted file mode 100644
index d315b5c..0000000
--- a/amplify/backend/api/thrifty/parameters.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "AppSyncApiName": "thrifty",
- "DynamoDBBillingMode": "PAY_PER_REQUEST",
- "DynamoDBEnableServerSideEncryption": false,
- "AuthCognitoUserPoolId": {
- "Fn::GetAtt": [
- "auththrifty21f6c364",
- "Outputs.UserPoolId"
- ]
- }
-}
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty/resolvers/README.md b/amplify/backend/api/thrifty/resolvers/README.md
deleted file mode 100644
index 89e564c..0000000
--- a/amplify/backend/api/thrifty/resolvers/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-Any resolvers that you add in this directory will override the ones automatically generated by Amplify CLI and will be directly copied to the cloud.
-For more information, visit [https://docs.amplify.aws/cli/graphql-transformer/resolvers](https://docs.amplify.aws/cli/graphql-transformer/resolvers)
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty/schema.graphql b/amplify/backend/api/thrifty/schema.graphql
deleted file mode 100644
index 5981bb6..0000000
--- a/amplify/backend/api/thrifty/schema.graphql
+++ /dev/null
@@ -1,20 +0,0 @@
-type Category @model {
- id: ID!
- name: String!
- products: [Product] @connection(keyName: "byCategory", fields: ["id"])
-}
-
-type Product @model @key(name: "byCategory", fields: ["categoryID"]) {
- id: ID!
- title: String!
- categoryID: ID!
- category: Category @connection(fields: ["categoryID"])
- comments: [Comment] @connection(keyName: "byProduct", fields: ["id"])
-}
-
-type Comment @model @key(name: "byProduct", fields: ["productID", "content"]) {
- id: ID!
- productID: ID!
- product: Product @connection(fields: ["productID"])
- content: String!
-}
diff --git a/amplify/backend/api/thrifty/stacks/CustomResources.json b/amplify/backend/api/thrifty/stacks/CustomResources.json
deleted file mode 100644
index f95feea..0000000
--- a/amplify/backend/api/thrifty/stacks/CustomResources.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "AWSTemplateFormatVersion": "2010-09-09",
- "Description": "An auto-generated nested stack.",
- "Metadata": {},
- "Parameters": {
- "AppSyncApiId": {
- "Type": "String",
- "Description": "The id of the AppSync API associated with this project."
- },
- "AppSyncApiName": {
- "Type": "String",
- "Description": "The name of the AppSync API",
- "Default": "AppSyncSimpleTransform"
- },
- "env": {
- "Type": "String",
- "Description": "The environment name. e.g. Dev, Test, or Production",
- "Default": "NONE"
- },
- "S3DeploymentBucket": {
- "Type": "String",
- "Description": "The S3 bucket containing all deployment assets for the project."
- },
- "S3DeploymentRootKey": {
- "Type": "String",
- "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
- }
- },
- "Resources": {
- "EmptyResource": {
- "Type": "Custom::EmptyResource",
- "Condition": "AlwaysFalse"
- }
- },
- "Conditions": {
- "HasEnvironmentParameter": {
- "Fn::Not": [
- {
- "Fn::Equals": [
- {
- "Ref": "env"
- },
- "NONE"
- ]
- }
- ]
- },
- "AlwaysFalse": {
- "Fn::Equals": ["true", "false"]
- }
- },
- "Outputs": {
- "EmptyOutput": {
- "Description": "An empty output. You may delete this if you have at least one resource above.",
- "Value": ""
- }
- }
-}
diff --git a/amplify/backend/api/thrifty/transform.conf.json b/amplify/backend/api/thrifty/transform.conf.json
deleted file mode 100644
index 98e1e19..0000000
--- a/amplify/backend/api/thrifty/transform.conf.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Version": 5,
- "ElasticsearchWarning": true
-}
\ No newline at end of file
diff --git a/amplify/backend/auth/thrifty21f6c364/parameters.json b/amplify/backend/auth/thrifty21f6c364/parameters.json
deleted file mode 100644
index 93c33f4..0000000
--- a/amplify/backend/auth/thrifty21f6c364/parameters.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "identityPoolName": "thrifty21f6c364_identitypool_21f6c364",
- "allowUnauthenticatedIdentities": true,
- "resourceNameTruncated": "thrift21f6c364",
- "userPoolName": "thrifty21f6c364_userpool_21f6c364",
- "autoVerifiedAttributes": [
- "email"
- ],
- "mfaConfiguration": "OFF",
- "mfaTypes": [
- "SMS Text Message"
- ],
- "smsAuthenticationMessage": "Your authentication code is {####}",
- "smsVerificationMessage": "Your verification code is {####}",
- "emailVerificationSubject": "Your verification code",
- "emailVerificationMessage": "Your verification code is {####}",
- "defaultPasswordPolicy": false,
- "passwordPolicyMinLength": 8,
- "passwordPolicyCharacters": [],
- "requiredAttributes": [
- "email"
- ],
- "aliasAttributes": [],
- "userpoolClientGenerateSecret": false,
- "userpoolClientRefreshTokenValidity": 30,
- "userpoolClientWriteAttributes": [
- "email"
- ],
- "userpoolClientReadAttributes": [
- "email"
- ],
- "userpoolClientLambdaRole": "thrift21f6c364_userpoolclient_lambda_role",
- "userpoolClientSetAttributes": false,
- "sharedId": "21f6c364",
- "resourceName": "thrifty21f6c364",
- "authSelections": "identityPoolAndUserPool",
- "authRoleArn": {
- "Fn::GetAtt": [
- "AuthRole",
- "Arn"
- ]
- },
- "unauthRoleArn": {
- "Fn::GetAtt": [
- "UnauthRole",
- "Arn"
- ]
- },
- "useDefault": "default",
- "usernameAttributes": [
- "email"
- ],
- "userPoolGroupList": [],
- "serviceName": "Cognito",
- "usernameCaseSensitive": false,
- "dependsOn": []
-}
\ No newline at end of file
diff --git a/amplify/backend/auth/thrifty21f6c364/thrifty21f6c364-cloudformation-template.yml b/amplify/backend/auth/thrifty21f6c364/thrifty21f6c364-cloudformation-template.yml
deleted file mode 100644
index 950de39..0000000
--- a/amplify/backend/auth/thrifty21f6c364/thrifty21f6c364-cloudformation-template.yml
+++ /dev/null
@@ -1,432 +0,0 @@
-
-AWSTemplateFormatVersion: 2010-09-09
-
-Parameters:
- env:
- Type: String
- authRoleArn:
- Type: String
- unauthRoleArn:
- Type: String
-
-
-
-
- identityPoolName:
- Type: String
-
-
-
- allowUnauthenticatedIdentities:
- Type: String
-
- resourceNameTruncated:
- Type: String
-
-
- userPoolName:
- Type: String
-
-
-
- autoVerifiedAttributes:
- Type: CommaDelimitedList
-
- mfaConfiguration:
- Type: String
-
-
-
- mfaTypes:
- Type: CommaDelimitedList
-
- smsAuthenticationMessage:
- Type: String
-
-
- smsVerificationMessage:
- Type: String
-
-
- emailVerificationSubject:
- Type: String
-
-
- emailVerificationMessage:
- Type: String
-
-
-
- defaultPasswordPolicy:
- Type: String
-
-
- passwordPolicyMinLength:
- Type: Number
-
-
- passwordPolicyCharacters:
- Type: CommaDelimitedList
-
-
- requiredAttributes:
- Type: CommaDelimitedList
-
-
- aliasAttributes:
- Type: CommaDelimitedList
-
-
- userpoolClientGenerateSecret:
- Type: String
-
-
- userpoolClientRefreshTokenValidity:
- Type: Number
-
-
- userpoolClientWriteAttributes:
- Type: CommaDelimitedList
-
-
- userpoolClientReadAttributes:
- Type: CommaDelimitedList
-
- userpoolClientLambdaRole:
- Type: String
-
-
-
- userpoolClientSetAttributes:
- Type: String
-
- sharedId:
- Type: String
-
-
- resourceName:
- Type: String
-
-
- authSelections:
- Type: String
-
-
-
-
- useDefault:
- Type: String
-
-
-
- usernameAttributes:
- Type: CommaDelimitedList
-
-
- userPoolGroupList:
- Type: CommaDelimitedList
-
- serviceName:
- Type: String
-
-
-
- usernameCaseSensitive:
- Type: String
-
-
- dependsOn:
- Type: CommaDelimitedList
-
-Conditions:
- ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
-
- ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ]
-
-
-Resources:
-
-
- # BEGIN SNS ROLE RESOURCE
- SNSRole:
- # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
- Type: AWS::IAM::Role
- Properties:
- RoleName: !If [ShouldNotCreateEnvResources, 'thrift21f6c364_sns-role', !Join ['',[ 'sns', '21f6c364', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
- AssumeRolePolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Sid: ""
- Effect: "Allow"
- Principal:
- Service: "cognito-idp.amazonaws.com"
- Action:
- - "sts:AssumeRole"
- Condition:
- StringEquals:
- sts:ExternalId: thrift21f6c364_role_external_id
- Policies:
- -
- PolicyName: thrift21f6c364-sns-policy
- PolicyDocument:
- Version: "2012-10-17"
- Statement:
- -
- Effect: "Allow"
- Action:
- - "sns:Publish"
- Resource: "*"
- # BEGIN USER POOL RESOURCES
- UserPool:
- # Created upon user selection
- # Depends on SNS Role for Arn if MFA is enabled
- Type: AWS::Cognito::UserPool
- UpdateReplacePolicy: Retain
- Properties:
- UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
-
-
- UsernameConfiguration:
- CaseSensitive: false
-
- Schema:
-
- -
- Name: email
- Required: true
- Mutable: true
-
-
-
-
- AutoVerifiedAttributes:
-
- - email
-
-
-
- EmailVerificationMessage: !Ref emailVerificationMessage
- EmailVerificationSubject: !Ref emailVerificationSubject
-
- Policies:
- PasswordPolicy:
- MinimumLength: !Ref passwordPolicyMinLength
- RequireLowercase: false
- RequireNumbers: false
- RequireSymbols: false
- RequireUppercase: false
-
- UsernameAttributes: !Ref usernameAttributes
-
-
- MfaConfiguration: !Ref mfaConfiguration
- SmsVerificationMessage: !Ref smsVerificationMessage
- SmsAuthenticationMessage: !Ref smsAuthenticationMessage
- SmsConfiguration:
- SnsCallerArn: !GetAtt SNSRole.Arn
- ExternalId: thrift21f6c364_role_external_id
-
-
- UserPoolClientWeb:
- # Created provide application access to user pool
- # Depends on UserPool for ID reference
- Type: "AWS::Cognito::UserPoolClient"
- Properties:
- ClientName: thrift21f6c364_app_clientWeb
-
- RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
- UserPoolId: !Ref UserPool
- DependsOn: UserPool
- UserPoolClient:
- # Created provide application access to user pool
- # Depends on UserPool for ID reference
- Type: "AWS::Cognito::UserPoolClient"
- Properties:
- ClientName: thrift21f6c364_app_client
-
- GenerateSecret: !Ref userpoolClientGenerateSecret
- RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
- UserPoolId: !Ref UserPool
- DependsOn: UserPool
- # BEGIN USER POOL LAMBDA RESOURCES
- UserPoolClientRole:
- # Created to execute Lambda which gets userpool app client config values
- Type: 'AWS::IAM::Role'
- Properties:
- RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', '21f6c364', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
- AssumeRolePolicyDocument:
- Version: '2012-10-17'
- Statement:
- - Effect: Allow
- Principal:
- Service:
- - lambda.amazonaws.com
- Action:
- - 'sts:AssumeRole'
- DependsOn: UserPoolClient
- UserPoolClientLambda:
- # Lambda which gets userpool app client config values
- # Depends on UserPool for id
- # Depends on UserPoolClientRole for role ARN
- Type: 'AWS::Lambda::Function'
- Properties:
- Code:
- ZipFile: !Join
- - |+
- - - 'const response = require(''cfn-response'');'
- - 'const aws = require(''aws-sdk'');'
- - 'const identity = new aws.CognitoIdentityServiceProvider();'
- - 'exports.handler = (event, context, callback) => {'
- - ' if (event.RequestType == ''Delete'') { '
- - ' response.send(event, context, response.SUCCESS, {})'
- - ' }'
- - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
- - ' const params = {'
- - ' ClientId: event.ResourceProperties.clientId,'
- - ' UserPoolId: event.ResourceProperties.userpoolId'
- - ' };'
- - ' identity.describeUserPoolClient(params).promise()'
- - ' .then((res) => {'
- - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
- - ' })'
- - ' .catch((err) => {'
- - ' response.send(event, context, response.FAILED, {err});'
- - ' });'
- - ' }'
- - '};'
- Handler: index.handler
- Runtime: nodejs12.x
- Timeout: 300
- Role: !GetAtt
- - UserPoolClientRole
- - Arn
- DependsOn: UserPoolClientRole
- UserPoolClientLambdaPolicy:
- # Sets userpool policy for the role that executes the Userpool Client Lambda
- # Depends on UserPool for Arn
- # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
- Type: 'AWS::IAM::Policy'
- Properties:
- PolicyName: thrift21f6c364_userpoolclient_lambda_iam_policy
- Roles:
- - !Ref UserPoolClientRole
- PolicyDocument:
- Version: '2012-10-17'
- Statement:
- - Effect: Allow
- Action:
- - 'cognito-idp:DescribeUserPoolClient'
- Resource: !GetAtt UserPool.Arn
- DependsOn: UserPoolClientLambda
- UserPoolClientLogPolicy:
- # Sets log policy for the role that executes the Userpool Client Lambda
- # Depends on UserPool for Arn
- # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
- Type: 'AWS::IAM::Policy'
- Properties:
- PolicyName: thrift21f6c364_userpoolclient_lambda_log_policy
- Roles:
- - !Ref UserPoolClientRole
- PolicyDocument:
- Version: 2012-10-17
- Statement:
- - Effect: Allow
- Action:
- - 'logs:CreateLogGroup'
- - 'logs:CreateLogStream'
- - 'logs:PutLogEvents'
- Resource: !Sub
- - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
- - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
- DependsOn: UserPoolClientLambdaPolicy
- UserPoolClientInputs:
- # Values passed to Userpool client Lambda
- # Depends on UserPool for Id
- # Depends on UserPoolClient for Id
- # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
- Type: 'Custom::LambdaCallout'
- Properties:
- ServiceToken: !GetAtt UserPoolClientLambda.Arn
- clientId: !Ref UserPoolClient
- userpoolId: !Ref UserPool
- DependsOn: UserPoolClientLogPolicy
-
-
-
-
-
-
-
- # BEGIN IDENTITY POOL RESOURCES
-
-
- IdentityPool:
- # Always created
- Type: AWS::Cognito::IdentityPool
- Properties:
- IdentityPoolName: !If [ShouldNotCreateEnvResources, 'thrifty21f6c364_identitypool_21f6c364', !Join ['',['thrifty21f6c364_identitypool_21f6c364', '__', !Ref env]]]
-
- CognitoIdentityProviders:
- - ClientId: !Ref UserPoolClient
- ProviderName: !Sub
- - cognito-idp.${region}.amazonaws.com/${client}
- - { region: !Ref "AWS::Region", client: !Ref UserPool}
- - ClientId: !Ref UserPoolClientWeb
- ProviderName: !Sub
- - cognito-idp.${region}.amazonaws.com/${client}
- - { region: !Ref "AWS::Region", client: !Ref UserPool}
-
- AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
-
-
- DependsOn: UserPoolClientInputs
-
-
- IdentityPoolRoleMap:
- # Created to map Auth and Unauth roles to the identity pool
- # Depends on Identity Pool for ID ref
- Type: AWS::Cognito::IdentityPoolRoleAttachment
- Properties:
- IdentityPoolId: !Ref IdentityPool
- Roles:
- unauthenticated: !Ref unauthRoleArn
- authenticated: !Ref authRoleArn
- DependsOn: IdentityPool
-
-
-Outputs :
-
- IdentityPoolId:
- Value: !Ref 'IdentityPool'
- Description: Id for the identity pool
- IdentityPoolName:
- Value: !GetAtt IdentityPool.Name
-
-
-
-
- UserPoolId:
- Value: !Ref 'UserPool'
- Description: Id for the user pool
- UserPoolArn:
- Value: !GetAtt UserPool.Arn
- Description: Arn for the user pool
- UserPoolName:
- Value: !Ref userPoolName
- AppClientIDWeb:
- Value: !Ref 'UserPoolClientWeb'
- Description: The user pool app client id for web
- AppClientID:
- Value: !Ref 'UserPoolClient'
- Description: The user pool app client id
- AppClientSecret:
- Value: !GetAtt UserPoolClientInputs.appSecret
- Condition: ShouldOutputAppClientSecrets
-
-
-
-
-
-
-
-
diff --git a/amplify/backend/backend-config.json b/amplify/backend/backend-config.json
deleted file mode 100644
index 4724ae5..0000000
--- a/amplify/backend/backend-config.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "api": {
- "thrifty": {
- "service": "AppSync",
- "providerPlugin": "awscloudformation",
- "output": {
- "authConfig": {
- "defaultAuthentication": {
- "authenticationType": "AMAZON_COGNITO_USER_POOLS",
- "userPoolConfig": {
- "userPoolId": "auththrifty21f6c364"
- }
- },
- "additionalAuthenticationProviders": []
- }
- }
- }
- },
- "auth": {
- "thrifty21f6c364": {
- "service": "Cognito",
- "providerPlugin": "awscloudformation",
- "dependsOn": [],
- "customAuth": false,
- "frontendAuthConfig": {
- "loginMechanisms": [
- "EMAIL"
- ],
- "signupAttributes": [
- "EMAIL"
- ],
- "passwordProtectionSettings": {
- "passwordPolicyMinLength": 8,
- "passwordPolicyCharacters": []
- },
- "mfaConfiguration": "OFF",
- "mfaTypes": [
- "SMS"
- ],
- "verificationMechanisms": [
- "EMAIL"
- ]
- }
- }
- },
- "storage": {
- "SSDStorage": {
- "service": "S3",
- "providerPlugin": "awscloudformation"
- }
- },
- "notifications": {
- "ThriftyOWUjV": {
- "service": "Pinpoint",
- "channels": [
- "FCM"
- ]
- }
- },
- "analytics": {
- "ThriftyOWUjV": {
- "service": "Pinpoint",
- "providerPlugin": "awscloudformation"
- }
- }
-}
\ No newline at end of file
diff --git a/amplify/backend/storage/SSDStorage/parameters.json b/amplify/backend/storage/SSDStorage/parameters.json
deleted file mode 100644
index 3ab7dad..0000000
--- a/amplify/backend/storage/SSDStorage/parameters.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "bucketName": "thrifty9ac428d5d3084fb499b8aaa6395680b8",
- "authPolicyName": "s3_amplify_2b6f0a5b",
- "unauthPolicyName": "s3_amplify_2b6f0a5b",
- "authRoleName": {
- "Ref": "AuthRoleName"
- },
- "unauthRoleName": {
- "Ref": "UnauthRoleName"
- },
- "selectedGuestPermissions": [
- "s3:GetObject",
- "s3:ListBucket"
- ],
- "selectedAuthenticatedPermissions": [
- "s3:PutObject",
- "s3:GetObject",
- "s3:ListBucket",
- "s3:DeleteObject"
- ],
- "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
- "s3PublicPolicy": "Public_policy_0e1bbdf5",
- "s3PermissionsAuthenticatedUploads": "s3:PutObject",
- "s3UploadsPolicy": "Uploads_policy_0e1bbdf5",
- "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
- "s3ProtectedPolicy": "Protected_policy_0e1bbdf5",
- "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
- "s3PrivatePolicy": "Private_policy_0e1bbdf5",
- "AuthenticatedAllowList": "ALLOW",
- "s3ReadPolicy": "read_policy_0e1bbdf5",
- "s3PermissionsGuestPublic": "DISALLOW",
- "s3PermissionsGuestUploads": "DISALLOW",
- "GuestAllowList": "DISALLOW",
- "triggerFunction": "NONE"
-}
\ No newline at end of file
diff --git a/amplify/backend/storage/SSDStorage/s3-cloudformation-template.json b/amplify/backend/storage/SSDStorage/s3-cloudformation-template.json
deleted file mode 100644
index 112e432..0000000
--- a/amplify/backend/storage/SSDStorage/s3-cloudformation-template.json
+++ /dev/null
@@ -1,657 +0,0 @@
-{
- "AWSTemplateFormatVersion": "2010-09-09",
- "Description": "S3 resource stack creation using Amplify CLI",
- "Parameters": {
- "bucketName": {
- "Type": "String"
- },
- "authPolicyName": {
- "Type": "String"
- },
- "unauthPolicyName": {
- "Type": "String"
- },
- "authRoleName": {
- "Type": "String"
- },
- "unauthRoleName": {
- "Type": "String"
- },
- "s3PublicPolicy": {
- "Type": "String",
- "Default" : "NONE"
- },
- "s3PrivatePolicy": {
- "Type": "String",
- "Default" : "NONE"
- },
- "s3ProtectedPolicy": {
- "Type": "String",
- "Default" : "NONE"
- },
- "s3UploadsPolicy": {
- "Type": "String",
- "Default" : "NONE"
- },
- "s3ReadPolicy": {
- "Type": "String",
- "Default" : "NONE"
- },
- "s3PermissionsAuthenticatedPublic": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "s3PermissionsAuthenticatedProtected": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "s3PermissionsAuthenticatedPrivate": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "s3PermissionsAuthenticatedUploads": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "s3PermissionsGuestPublic": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "s3PermissionsGuestUploads": {
- "Type": "String",
- "Default" : "DISALLOW" },
- "AuthenticatedAllowList": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "GuestAllowList": {
- "Type": "String",
- "Default" : "DISALLOW"
- },
- "selectedGuestPermissions": {
- "Type": "CommaDelimitedList",
- "Default" : "NONE"
- },
- "selectedAuthenticatedPermissions": {
- "Type": "CommaDelimitedList",
- "Default" : "NONE"
- },
- "env": {
- "Type": "String"
- },
- "triggerFunction": {
- "Type": "String"
- }
-
-
- },
- "Conditions": {
- "ShouldNotCreateEnvResources": {
- "Fn::Equals": [
- {
- "Ref": "env"
- },
- "NONE"
- ]
- },
- "CreateAuthPublic": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsAuthenticatedPublic"},
- "DISALLOW"
- ]
- }]
- },
- "CreateAuthProtected": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsAuthenticatedProtected"},
- "DISALLOW"
- ]
- }]
- },
- "CreateAuthPrivate": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsAuthenticatedPrivate"},
- "DISALLOW"
- ]
- }]
- },
- "CreateAuthUploads": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsAuthenticatedUploads"},
- "DISALLOW"
- ]
- }]
- },
- "CreateGuestPublic": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsGuestPublic"},
- "DISALLOW"
- ]
- }]
- },
- "CreateGuestUploads": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "s3PermissionsGuestUploads"},
- "DISALLOW"
- ]
- }]
- },
- "AuthReadAndList": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "AuthenticatedAllowList"},
- "DISALLOW"
- ]
- }]
- },
- "GuestReadAndList": {
- "Fn::Not" : [{
- "Fn::Equals" : [
- {"Ref" : "GuestAllowList"},
- "DISALLOW"
- ]
- }]
- }
- },
- "Resources": {
- "S3Bucket": {
- "Type": "AWS::S3::Bucket",
-
- "DeletionPolicy" : "Retain",
- "Properties": {
- "BucketName": {
- "Fn::If": [
- "ShouldNotCreateEnvResources",
- {
- "Ref": "bucketName"
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Ref": "bucketName"
- },
- {
- "Fn::Select": [
- 3,
- {
- "Fn::Split": [
- "-",
- {
- "Ref": "AWS::StackName"
- }
- ]
- }
- ]
- },
- "-",
- {
- "Ref": "env"
- }
- ]
- ]
- }
- ]
- },
-
- "CorsConfiguration": {
- "CorsRules": [
- {
- "AllowedHeaders": [
- "*"
- ],
- "AllowedMethods": [
- "GET",
- "HEAD",
- "PUT",
- "POST",
- "DELETE"
- ],
- "AllowedOrigins": [
- "*"
- ],
- "ExposedHeaders": [
- "x-amz-server-side-encryption",
- "x-amz-request-id",
- "x-amz-id-2",
- "ETag"
- ],
- "Id": "S3CORSRuleId1",
- "MaxAge": "3000"
- }
- ]
- }
- }
- },
-
-
- "S3AuthPublicPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateAuthPublic",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3PublicPolicy"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsAuthenticatedPublic"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/public/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3AuthProtectedPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateAuthProtected",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3ProtectedPolicy"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsAuthenticatedProtected"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/protected/${cognito-identity.amazonaws.com:sub}/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3AuthPrivatePolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateAuthPrivate",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3PrivatePolicy"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsAuthenticatedPrivate"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/private/${cognito-identity.amazonaws.com:sub}/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3AuthUploadPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateAuthUploads",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3UploadsPolicy"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsAuthenticatedUploads"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/uploads/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3AuthReadPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "AuthReadAndList",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3ReadPolicy"
- },
- "Roles": [
- {
- "Ref": "authRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "s3:GetObject"
- ],
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/protected/*"
- ]
- ]
- }
- ]
- },
- {
- "Effect": "Allow",
- "Action": [
- "s3:ListBucket"
- ],
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- }
- ]
- ]
- }
- ],
- "Condition": {
- "StringLike": {
- "s3:prefix": [
- "public/",
- "public/*",
- "protected/",
- "protected/*",
- "private/${cognito-identity.amazonaws.com:sub}/",
- "private/${cognito-identity.amazonaws.com:sub}/*"
- ]
- }
- }
- }
- ]
- }
- }
- },
- "S3GuestPublicPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateGuestPublic",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3PublicPolicy"
- },
- "Roles": [
- {
- "Ref": "unauthRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsGuestPublic"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/public/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3GuestUploadPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "CreateGuestUploads",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3UploadsPolicy"
- },
- "Roles": [
- {
- "Ref": "unauthRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": {
- "Fn::Split" : [ "," , {
- "Ref": "s3PermissionsGuestUploads"
- } ]
- },
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/uploads/*"
- ]
- ]
- }
- ]
- }
- ]
- }
- }
- },
- "S3GuestReadPolicy": {
- "DependsOn": [
- "S3Bucket"
- ],
- "Condition": "GuestReadAndList",
- "Type": "AWS::IAM::Policy",
- "Properties": {
- "PolicyName": {
- "Ref": "s3ReadPolicy"
- },
- "Roles": [
- {
- "Ref": "unauthRoleName"
- }
- ],
- "PolicyDocument": {
- "Version": "2012-10-17",
- "Statement": [
- {
- "Effect": "Allow",
- "Action": [
- "s3:GetObject"
- ],
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- },
- "/protected/*"
- ]
- ]
- }
- ]
- },
- {
- "Effect": "Allow",
- "Action": [
- "s3:ListBucket"
- ],
- "Resource": [
- {
- "Fn::Join": [
- "",
- [
- "arn:aws:s3:::",
- {
- "Ref": "S3Bucket"
- }
- ]
- ]
- }
- ],
- "Condition": {
- "StringLike": {
- "s3:prefix": [
- "public/",
- "public/*",
- "protected/",
- "protected/*"
- ]
- }
- }
- }
- ]
- }
- }
- }
- },
- "Outputs": {
- "BucketName": {
- "Value": {
- "Ref": "S3Bucket"
- },
- "Description": "Bucket name for the S3 bucket"
- },
- "Region": {
- "Value": {
- "Ref": "AWS::Region"
- }
- }
- }
-}
diff --git a/amplify/backend/storage/SSDStorage/storage-params.json b/amplify/backend/storage/SSDStorage/storage-params.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/amplify/backend/storage/SSDStorage/storage-params.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/amplify/backend/tags.json b/amplify/backend/tags.json
deleted file mode 100644
index b9321d7..0000000
--- a/amplify/backend/tags.json
+++ /dev/null
@@ -1,10 +0,0 @@
-[
- {
- "Key": "user:Stack",
- "Value": "{project-env}"
- },
- {
- "Key": "user:Application",
- "Value": "{project-name}"
- }
-]
\ No newline at end of file
diff --git a/amplify/cli.json b/amplify/cli.json
deleted file mode 100644
index 3440a11..0000000
--- a/amplify/cli.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "features": {
- "graphqltransformer": {
- "addmissingownerfields": true,
- "improvepluralization": false,
- "validatetypenamereservedwords": true,
- "useexperimentalpipelinedtransformer": false,
- "enableiterativegsiupdates": true,
- "secondarykeyasgsi": true,
- "skipoverridemutationinputtypes": true
- },
- "frontend-ios": {
- "enablexcodeintegration": true
- },
- "auth": {
- "enablecaseinsensitivity": true,
- "useinclusiveterminology": true,
- "breakcirculardependency": true,
- "forcealiasattributes": false
- },
- "codegen": {
- "useappsyncmodelgenplugin": true,
- "usedocsgeneratorplugin": true,
- "usetypesgeneratorplugin": true,
- "cleangeneratedmodelsdirectory": true,
- "retaincasestyle": true,
- "addtimestampfields": true,
- "handlelistnullabilitytransparently": true,
- "emitauthprovider": true,
- "generateindexrules": true,
- "enabledartnullsafety": true
- },
- "appsync": {
- "generategraphqlpermissions": true
- },
- "latestregionsupport": {
- "pinpoint": 1,
- "translate": 1,
- "transcribe": 1,
- "rekognition": 1,
- "textract": 1,
- "comprehend": 1
- }
- }
-}
\ No newline at end of file
diff --git a/amplify/hooks/README.md b/amplify/hooks/README.md
deleted file mode 100644
index 8fb601e..0000000
--- a/amplify/hooks/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Command Hooks
-
-Command hooks can be used to run custom scripts upon Amplify CLI lifecycle events like pre-push, post-add-function, etc.
-
-To get started, add your script files based on the expected naming convention in this directory.
-
-Learn more about the script file naming convention, hook parameters, third party dependencies, and advanced configurations at https://docs.amplify.aws/cli/usage/command-hooks
diff --git a/amplify/team-provider-info.json b/amplify/team-provider-info.json
deleted file mode 100644
index 96ab5ed..0000000
--- a/amplify/team-provider-info.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "dev": {
- "awscloudformation": {
- "AuthRoleName": "amplify-thrifty-dev-144858-authRole",
- "UnauthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty-dev-144858-unauthRole",
- "AuthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty-dev-144858-authRole",
- "Region": "eu-central-1",
- "DeploymentBucketName": "amplify-thrifty-dev-144858-deployment",
- "UnauthRoleName": "amplify-thrifty-dev-144858-unauthRole",
- "StackName": "amplify-thrifty-dev-144858",
- "StackId": "arn:aws:cloudformation:eu-central-1:459760485083:stack/amplify-thrifty-dev-144858/659b7da0-4f80-11ec-a95f-022ef605612a",
- "AmplifyAppId": "d2xhz0mn88sj6z"
- },
- "categories": {
- "auth": {
- "thrifty21f6c364": {}
- },
- "notifications": {
- "Pinpoint": {
- "Name": "ThriftyOWUjV-dev",
- "Id": "f06bd624184f4c90bc7556672ddd9619",
- "Region": "eu-central-1"
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 5067d4d..4e3c16a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,6 @@
plugins {
id 'com.android.application'
+ id 'com.google.gms.google-services'
}
android {
@@ -39,7 +40,20 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.room:room-common:2.3.0'
+ //noinspection GradleDependency
+ implementation 'com.google.firebase:firebase-database:19.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ implementation platform('com.google.firebase:firebase-bom:26.3.0')
+ implementation 'com.google.firebase:firebase-database-ktx'
+ implementation 'com.jakewharton:butterknife:10.2.3'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
+ implementation 'com.github.bumptech.glide:glide:4.12.0'
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
+ implementation "com.nex3z:notification-badge:1.0.4"
+ implementation "org.greenrobot:eventbus:3.2.0"
}
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..7db27b2
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,39 @@
+{
+ "project_info": {
+ "project_number": "393274024142",
+ "project_id": "thriftycart",
+ "storage_bucket": "thriftycart.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:393274024142:android:d4d380dc692738bc32f09f",
+ "android_client_info": {
+ "package_name": "com.example.thrifty"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "393274024142-5kr087vrbn9h2g1i2fbaoq5jgghh4uqt.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCh9gjGdT8xuEl29Eu_S8geN-9aF128clc"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "393274024142-5kr087vrbn9h2g1i2fbaoq5jgghh4uqt.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 316b66d..8cb7f46 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,23 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/thrifty/CartListener.java b/app/src/main/java/com/example/thrifty/CartListener.java
new file mode 100644
index 0000000..cf220a6
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/CartListener.java
@@ -0,0 +1,8 @@
+package com.example.thrifty;
+
+import java.util.List;
+
+public interface CartListener {
+ void onCartLoadSuccess(List cartModelList);
+ void onCartLoadFailed(String message);
+}
diff --git a/app/src/main/java/com/example/thrifty/CartModel.java b/app/src/main/java/com/example/thrifty/CartModel.java
new file mode 100644
index 0000000..35f4161
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/CartModel.java
@@ -0,0 +1,53 @@
+package com.example.thrifty;
+
+public class CartModel {
+ private String key;
+ private String name;
+ private String image;
+ private String price;
+ private float totalPrice;
+
+
+ public CartModel() {
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getImage() {
+ return image;
+ }
+
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ public String getPrice() {
+ return price;
+ }
+
+ public void setPrice(String price) {
+ this.price = price;
+ }
+
+ public float getTotalPrice() {
+ return totalPrice;
+ }
+
+ public void setTotalPrice(float totalPrice) {
+ this.totalPrice = totalPrice;
+ }
+}
diff --git a/app/src/main/java/com/example/thrifty/MainActivity.java b/app/src/main/java/com/example/thrifty/MainActivity.java
index 29ef16b..466438e 100644
--- a/app/src/main/java/com/example/thrifty/MainActivity.java
+++ b/app/src/main/java/com/example/thrifty/MainActivity.java
@@ -1,10 +1,11 @@
package com.example.thrifty;
import androidx.appcompat.app.AppCompatActivity;
-
+import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
-import android.widget.EditText;
+import android.view.View;
+import android.widget.Button;
import com.amplifyframework.AmplifyException;
import com.amplifyframework.analytics.pinpoint.AWSPinpointAnalyticsPlugin;
@@ -29,5 +30,14 @@ protected void onCreate(Bundle savedInstanceState) {
} catch (AmplifyException error) {
Log.e("MyAmplifyApp", "Could not initialize Amplify", error);
}
+
+ Button products = findViewById(R.id.productsButton);
+ products.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(MainActivity.this, ProductsActivity.class);
+ startActivity(intent);
+ }
+ });
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/thrifty/ProductAdapter.java b/app/src/main/java/com/example/thrifty/ProductAdapter.java
new file mode 100644
index 0000000..73b9098
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/ProductAdapter.java
@@ -0,0 +1,68 @@
+package com.example.thrifty;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
+public class ProductAdapter extends RecyclerView.Adapter {
+
+ private Context context;
+ List productModelList = new ArrayList<>();
+
+ public ProductAdapter(Context context, List productModelList) {
+ this.context = context;
+ this.productModelList = productModelList;
+ }
+
+ public class ProductViewHolder extends RecyclerView.ViewHolder{
+ @BindView(R.id.imageView)
+ ImageView imageView;
+ @BindView(R.id.txtName)
+ TextView txtName;
+ @BindView(R.id.txtPrice)
+ TextView txtPrice;
+ private Unbinder unbinder;
+ public ProductViewHolder(@NonNull View itemView) {
+ super(itemView);
+ unbinder = ButterKnife.bind(this, itemView);
+ }
+ }
+
+
+
+ @NonNull
+ @Override
+ public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
+ return new ProductViewHolder(LayoutInflater.from(context)
+ .inflate(R.layout.layout_product_item,parent,false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) {
+ Glide.with(context)
+ .load(productModelList.get(position).getImage())
+ .into(holder.imageView);
+ holder.txtPrice.setText(new StringBuilder("$").append(productModelList.get(position).getPrice()));
+ holder.txtName.setText(new StringBuilder().append(productModelList.get(position).getName()));
+ }
+
+ @Override
+ public int getItemCount() {
+ return productModelList.size();
+ }
+}
diff --git a/app/src/main/java/com/example/thrifty/ProductListener.java b/app/src/main/java/com/example/thrifty/ProductListener.java
new file mode 100644
index 0000000..f7cb2ed
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/ProductListener.java
@@ -0,0 +1,8 @@
+package com.example.thrifty;
+
+import java.util.List;
+
+public interface ProductListener {
+ void onProductLoadSuccess(List productModelList);
+ void onProductLoadFailed(String message);
+}
diff --git a/app/src/main/java/com/example/thrifty/ProductModel.java b/app/src/main/java/com/example/thrifty/ProductModel.java
new file mode 100644
index 0000000..372b977
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/ProductModel.java
@@ -0,0 +1,52 @@
+package com.example.thrifty;
+
+public class ProductModel {
+ public int id;
+ private String key;
+ private String name;
+ private String image;
+ private String price;
+
+ public ProductModel() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getImage() {
+ return image;
+ }
+
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ public String getPrice() {
+ return price;
+ }
+
+ public void setPrice(String price) {
+ this.price = price;
+ }
+}
diff --git a/app/src/main/java/com/example/thrifty/ProductsActivity.java b/app/src/main/java/com/example/thrifty/ProductsActivity.java
new file mode 100644
index 0000000..1188a12
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/ProductsActivity.java
@@ -0,0 +1,125 @@
+package com.example.thrifty;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.room.Database;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.ArrayAdapter;
+import android.widget.FrameLayout;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+
+import com.amplifyframework.datastore.generated.model.Product;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.firebase.database.DataSnapshot;
+import com.google.firebase.database.DatabaseError;
+import com.google.firebase.database.DatabaseReference;
+import com.google.firebase.database.FirebaseDatabase;
+import com.google.firebase.database.ValueEventListener;
+import com.nex3z.notificationbadge.NotificationBadge;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class ProductsActivity extends AppCompatActivity implements ProductListener, CartListener {
+ @BindView((R.id.recycler_product))
+ RecyclerView recyclerView;
+ @SuppressLint("NonConstantResourceId")
+ @BindView(R.id.productLayout)
+ RelativeLayout productLayout;
+ @SuppressLint("NonConstantResourceId")
+ @BindView(R.id.badge)
+ NotificationBadge badge;
+ @SuppressLint("NonConstantResourceId")
+ @BindView(R.id.btnCart)
+ FrameLayout btnCart;
+
+ ProductListener productListener;
+ CartListener cartListener;
+
+ private ListView listView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_products);
+
+// listView = findViewById(R.id.listView);
+
+ init();
+
+
+
+ DatabaseReference database = FirebaseDatabase.getInstance("https://thriftycart-default-rtdb.europe-west1.firebasedatabase.app").getReference().child("Drink");
+ List productModels = new ArrayList<>();
+ Log.i("Reference","Reference===>"+database);
+ database.addListenerForSingleValueEvent(new ValueEventListener() {
+
+// database.addValueEventListener(new ValueEventListener() {
+ @Override
+ public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
+ Log.i("Zeft","zafateeeeeeeeeeet"+recyclerView);
+
+ if (dataSnapshot.exists()) {
+ for (DataSnapshot productSnapshot:dataSnapshot.getChildren()) {
+ ProductModel productModel = productSnapshot.getValue(ProductModel.class);
+ Log.i("Heba","product one to add 5555555"+productModel);
+ productModel.setKey(productSnapshot.getKey());
+ Log.i("Jamal","product one to add 5555555"+productModel);
+ productModels.add(productModel);
+ Log.i("Khair","product one to add 9999999999"+productModel);
+ }
+ productListener.onProductLoadSuccess(productModels);
+ } else
+ Log.i("Nawal","product one to add 9999999999"+productModels);
+ productListener.onProductLoadFailed("can't find products");
+ }
+ @Override
+ public void onCancelled(@NonNull DatabaseError databaseError) {
+ productListener.onProductLoadFailed(databaseError.getMessage());
+ }
+ });
+
+ }
+
+ private void init() {
+ ButterKnife.bind(this);
+ productListener = this;
+ cartListener = this;
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
+ recyclerView.setLayoutManager(gridLayoutManager);
+ recyclerView.addItemDecoration(new SpaceItemDecoration());
+ }
+
+
+ @SuppressLint("NotifyDataSetChanged")
+ @Override
+ public void onProductLoadSuccess(List productModels) {
+ ProductAdapter adapter = new ProductAdapter(this, productModels);
+ recyclerView.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onProductLoadFailed(String message) {
+ Snackbar.make(productLayout,message, Snackbar.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onCartLoadSuccess(List cartModelList) {
+
+ }
+
+ @Override
+ public void onCartLoadFailed(String message) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/thrifty/SpaceItemDecoration.java b/app/src/main/java/com/example/thrifty/SpaceItemDecoration.java
new file mode 100644
index 0000000..1afc2b7
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/SpaceItemDecoration.java
@@ -0,0 +1,18 @@
+package com.example.thrifty;
+
+import android.graphics.Rect;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
+
+ @Override
+ public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
+ if(parent.getChildLayoutPosition(view) %2 != 0){
+ outRect.top = 50;
+ outRect.bottom = -50;
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_baseline_add_24.xml b/app/src/main/res/drawable/ic_baseline_add_24.xml
new file mode 100644
index 0000000..eb23254
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_add_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_delete_24.xml b/app/src/main/res/drawable/ic_baseline_delete_24.xml
new file mode 100644
index 0000000..3c4030b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_delete_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_navigate_before_24.xml b/app/src/main/res/drawable/ic_baseline_navigate_before_24.xml
new file mode 100644
index 0000000..09598f1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_navigate_before_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_remove_24.xml b/app/src/main/res/drawable/ic_baseline_remove_24.xml
new file mode 100644
index 0000000..791a2f8
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_remove_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_shopping_cart_24.xml b/app/src/main/res/drawable/ic_baseline_shopping_cart_24.xml
new file mode 100644
index 0000000..cf0dcc8
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_shopping_cart_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_heart_svgrepo_com.xml b/app/src/main/res/drawable/ic_heart_svgrepo_com.xml
new file mode 100644
index 0000000..41a1078
--- /dev/null
+++ b/app/src/main/res/drawable/ic_heart_svgrepo_com.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_heart_svgrepo_com.xml b/app/src/main/res/drawable/ic_outline_heart_svgrepo_com.xml
new file mode 100644
index 0000000..9b2b9ab
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_heart_svgrepo_com.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/item1.jpg b/app/src/main/res/drawable/item1.jpg
new file mode 100644
index 0000000..32d7b60
Binary files /dev/null and b/app/src/main/res/drawable/item1.jpg differ
diff --git a/app/src/main/res/drawable/selector_wishlist_item.xml b/app/src/main/res/drawable/selector_wishlist_item.xml
new file mode 100644
index 0000000..9d1bb50
--- /dev/null
+++ b/app/src/main/res/drawable/selector_wishlist_item.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 3acf237..9604de9 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -6,66 +6,41 @@
android:layout_height="match_parent"
tools:context=".MainActivity">
-
-
-
+ app:layout_constraintVertical_bias="0.0"
+ app:srcCompat="@drawable/item1" />
-
+ app:layout_constraintVertical_bias="0.272"
+ app:useMaterialThemeColors="false"
+ tools:ignore="MissingConstraints" />
-
+ app:layout_constraintVertical_bias="0.942" />
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_products.xml b/app/src/main/res/layout/activity_products.xml
new file mode 100644
index 0000000..07b56ef
--- /dev/null
+++ b/app/src/main/res/layout/activity_products.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_product_item.xml b/app/src/main/res/layout/layout_product_item.xml
new file mode 100644
index 0000000..3fc943e
--- /dev/null
+++ b/app/src/main/res/layout/layout_product_item.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1324c05..b800752 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,7 @@
Thrifty
+
+ Hello blank fragment
+ Home
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 78a0d25..f1ade60 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -13,4 +13,9 @@
- ?attr/colorPrimaryVariant
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index a5c0134..ef00b44 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,6 +7,9 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:7.0.3"
classpath 'com.amplifyframework:amplify-tools-gradle-plugin:1.0.2'
+ classpath 'com.google.gms:google-services:4.3.10'
+ classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
+
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files