diff --git a/first-cdk-deployment/app.py b/first-cdk-deployment/app.py index c3348b587..d804ff752 100644 --- a/first-cdk-deployment/app.py +++ b/first-cdk-deployment/app.py @@ -1,31 +1,8 @@ #!/usr/bin/env python3 import os - import aws_cdk as cdk - -from first_cdk_deployment.first_cdk_deployment_stack import FirstCdkDeploymentStack - +from first_cdk_deployment.first_cdk_deployment_stack import WebsiteStack app = cdk.App() -FirstCdkDeploymentStack(app, "FirstCdkDeploymentStack", - # If you don't specify 'env', this stack will be environment-agnostic. - # Account/Region-dependent features and context lookups will not work, - # but a single synthesized template can be deployed anywhere. - - # Uncomment the next line to specialize this stack for the AWS Account - # and Region that are implied by the current CLI configuration. - - #env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')), - - # Uncomment the next line if you know exactly what Account and Region you - # want to deploy the stack to. */ - - #env=cdk.Environment(account='123456789012', region='us-east-1'), - - # For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html - ) - +WebsiteStack(app, "WebsiteStack") app.synth() - - -#!/usr/bin/env python3 diff --git a/first-cdk-deployment/cdk.context.json b/first-cdk-deployment/cdk.context.json new file mode 100644 index 000000000..f4bc90c75 --- /dev/null +++ b/first-cdk-deployment/cdk.context.json @@ -0,0 +1,5 @@ +{ + "acknowledged-issue-numbers": [ + 32775 + ] +} diff --git a/first-cdk-deployment/first_cdk_deployment/first_cdk_deployment_stack.py b/first-cdk-deployment/first_cdk_deployment/first_cdk_deployment_stack.py index 7a43f163c..bae384dc5 100644 --- a/first-cdk-deployment/first_cdk_deployment/first_cdk_deployment_stack.py +++ b/first-cdk-deployment/first_cdk_deployment/first_cdk_deployment_stack.py @@ -1,24 +1,3 @@ -# from aws_cdk import ( -# # Duration, -# Stack, -# # aws_sqs as sqs, -# ) -# from constructs import Construct - -# class FirstCdkDeploymentStack(Stack): - -# def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: -# super().__init__(scope, construct_id, **kwargs) - -# # The code that defines your stack goes here - -# # example resource -# # queue = sqs.Queue( -# # self, "FirstCdkDeploymentQueue", -# # visibility_timeout=Duration.seconds(300), -# # ) - - from aws_cdk import ( Stack, aws_s3 as s3, @@ -29,32 +8,49 @@ RemovalPolicy ) from constructs import Construct -import os -class FirstCdkDeploymentStack(Stack): +class WebsiteStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) - # Create an S3 bucket to store the website files + # Create an S3 bucket to host the website website_bucket = s3.Bucket( self, - "ShopReactBucket", - block_public_access=s3.BlockPublicAccess.BLOCK_ALL, - removal_policy=RemovalPolicy.DESTROY, - auto_delete_objects=True + "WebsiteBucket", + removal_policy=RemovalPolicy.DESTROY, # NOT recommended for production + auto_delete_objects=True, # NOT recommended for production + block_public_access=s3.BlockPublicAccess.BLOCK_ALL ) - # Create CloudFront distribution - distribution = cloudfront.Distribution( + # Create Origin Access Identity for CloudFront + origin_access_identity = cloudfront.OriginAccessIdentity( self, - "ShopReactDistribution", + "OriginAccessIdentity", + comment="CloudFront access to S3" + ) + + # Grant read permissions for CloudFront + website_bucket.grant_read(origin_access_identity) + + # Create CloudFront Distribution + distribution = cloudfront.Distribution( + self, + "Distribution", default_behavior=cloudfront.BehaviorOptions( - origin=origins.S3Origin(website_bucket), + origin=origins.S3Origin( + website_bucket, + origin_access_identity=origin_access_identity + ), viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - cache_policy=cloudfront.CachePolicy.CACHING_OPTIMIZED, + cache_policy=cloudfront.CachePolicy.CACHING_OPTIMIZED ), default_root_object="index.html", error_responses=[ + cloudfront.ErrorResponse( + http_status=403, + response_http_status=200, + response_page_path="/index.html" + ), cloudfront.ErrorResponse( http_status=404, response_http_status=200, @@ -63,11 +59,11 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: ] ) - # Deploy site contents to S3 + # Deploy site contents to S3 bucket s3deploy.BucketDeployment( - self, - "DeployShopReact", - sources=[s3deploy.Source.asset(os.path.join(os.path.dirname(__file__), "..", "..", "dist"))], + self, + "DeployWebsite", + sources=[s3deploy.Source.asset("../dist")], # Adjust this path destination_bucket=website_bucket, distribution=distribution, distribution_paths=["/*"] @@ -75,7 +71,10 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: # Output the CloudFront URL CfnOutput( - self, - "DistributionDomainName", - value=distribution.distribution_domain_name + self, + "CloudFrontURL", + value=f"https://{distribution.distribution_domain_name}", + description="Website URL" ) + + diff --git a/first-cdk-deployment/requirements.txt b/first-cdk-deployment/requirements.txt index 20ba9d5fd..1d08a005f 100644 --- a/first-cdk-deployment/requirements.txt +++ b/first-cdk-deployment/requirements.txt @@ -1,2 +1,3 @@ -aws-cdk-lib==2.178.1 +aws-cdk-lib==2.124.0 constructs>=10.0.0,<11.0.0 +typeguard>=2.13.3 diff --git a/src/components/pages/PageProducts/components/Products.tsx b/src/components/pages/PageProducts/components/Products.tsx index 68eec6d69..9f986554d 100755 --- a/src/components/pages/PageProducts/components/Products.tsx +++ b/src/components/pages/PageProducts/components/Products.tsx @@ -32,6 +32,7 @@ export default function Products() { {product.title} + Available: {count} {formatAsPrice(product.price)} diff --git a/src/components/pages/admin/PageProductImport/components/CSVFileImport.tsx b/src/components/pages/admin/PageProductImport/components/CSVFileImport.tsx index d11028c96..c51153097 100755 --- a/src/components/pages/admin/PageProductImport/components/CSVFileImport.tsx +++ b/src/components/pages/admin/PageProductImport/components/CSVFileImport.tsx @@ -1,6 +1,8 @@ import React from "react"; import Typography from "@mui/material/Typography"; import Box from "@mui/material/Box"; +import axios from "axios"; +import { Button } from "@mui/material"; type CSVFileImportProps = { url: string; @@ -23,25 +25,62 @@ export default function CSVFileImport({ url, title }: CSVFileImportProps) { }; const uploadFile = async () => { - console.log("uploadFile to", url); - - // Get the presigned URL - // const response = await axios({ - // method: "GET", - // url, - // params: { - // name: encodeURIComponent(file.name), - // }, - // }); - // console.log("File to upload: ", file.name); - // console.log("Uploading to: ", response.data); - // const result = await fetch(response.data, { - // method: "PUT", - // body: file, - // }); - // console.log("Result: ", result); - // setFile(""); + if (!file) { + console.error("No file selected."); + return; + } + + console.log("uploadFile to to", url); + + try { + // Get the presigned URL + const response = await axios({ + method: "GET", + url, + params: { name: encodeURIComponent(file.name) }, + }); + + console.log("File to upload: ", file.name); + console.log("Uploading to: ", response.data); + + const result = await fetch(response.data, { + method: "PUT", + body: file, + headers: { + "Content-Type": "text/csv", + "Access-Control-Allow-Origin": "*", + }, + mode: 'cors' + }); + + console.log("Result: ", result); + setFile(undefined); // Clear the file after upload + } catch (error) { + console.error("Error uploading file:", error); + } }; + + + // const uploadFile = async () => { + // console.log("uploadFile to", url); + + // //Get the presigned URL + // const response = await axios({ + // method: "GET", + // url, + // params: { + // name: encodeURIComponent(file.name), + // }, + // }); + // console.log("File to upload: ", file.name); + // console.log("Uploading to: ", response.data); + // const result = await fetch(response.data, { + // method: "PUT", + // body: file, + // }); + // console.log("Result: ", result); + // setFile(""); + // }; return ( diff --git a/src/constants/apiPaths.ts b/src/constants/apiPaths.ts index 57e1c8f6b..6aff3863b 100755 --- a/src/constants/apiPaths.ts +++ b/src/constants/apiPaths.ts @@ -1,9 +1,11 @@ const API_PATHS = { //product: "https://.execute-api.eu-west-1.amazonaws.com/dev",https://pj8m5nmg5m.execute-api.us-east-1.amazonaws.com/prod/products/ //product: "https://i58jmttgyj.execute-api.us-east-1.amazonaws.com/prod/products",https://pj8m5nmg5m.execute-api.us-east-1.amazonaws.com/prod/products - product: "https://pj8m5nmg5m.execute-api.us-east-1.amazonaws.com/prod", + // product: "https://pj8m5nmg5m.execute-api.us-east-1.amazonaws.com/prod",https://c00aj28k2m.execute-api.us-east-1.amazonaws.com/prod/products + // import: "https://5uj67empu0.execute-api.us-east-1.amazonaws.com/prod", + product: "https://c00aj28k2m.execute-api.us-east-1.amazonaws.com/prod/", order: "https://.execute-api.eu-west-1.amazonaws.com/dev", - import: "https://.execute-api.eu-west-1.amazonaws.com/dev", + import: "https://tpv5ydqmbg.execute-api.us-east-1.amazonaws.com/prod/", bff: "https://.execute-api.eu-west-1.amazonaws.com/dev", cart: "https://.execute-api.eu-west-1.amazonaws.com/dev", }; diff --git a/src/queries/products.ts b/src/queries/products.ts index b24ce6d54..dd8f8651a 100644 --- a/src/queries/products.ts +++ b/src/queries/products.ts @@ -50,7 +50,7 @@ export function useRemoveProductCache() { export function useUpsertAvailableProduct() { return useMutation((values: AvailableProduct) => - axios.put(`${API_PATHS.bff}/product`, values, { + axios.put(`${API_PATHS.product}/product`, values, { headers: { Authorization: `Basic ${localStorage.getItem("authorization_token")}`, }, @@ -60,7 +60,7 @@ export function useUpsertAvailableProduct() { export function useDeleteAvailableProduct() { return useMutation((id: string) => - axios.delete(`${API_PATHS.bff}/product/${id}`, { + axios.delete(`${API_PATHS.product}/product/${id}`, { headers: { Authorization: `Basic ${localStorage.getItem("authorization_token")}`, },