From 92fdf3f3f33b6bacf9ed2c4a67d314499f778b5d Mon Sep 17 00:00:00 2001 From: Chris-1010 <122332721@umail.ucc.ie> Date: Wed, 22 Jan 2025 22:39:33 +0000 Subject: [PATCH] Implemented Stripe Embedded Checkout Component; Inclusion of .env files; --- .env.example | 7 + .gitignore | 3 +- docker-compose.yml | 13 +- web_server/Dockerfile | 8 + web_server/backend/.env.example | 5 + web_server/backend/blueprints/__init__.py | 8 +- web_server/backend/blueprints/main.py | 2 +- web_server/backend/blueprints/stripe.py | 12 +- web_server/frontend/.env.example | 4 + web_server/frontend/package-lock.json | 43 ++++- web_server/frontend/package.json | 4 +- web_server/frontend/src/App.tsx | 22 ++- .../frontend/src/assets/styles/index.css | 18 ++ .../src/components/Checkout/CheckoutForm.tsx | 96 +++++++++- .../frontend/src/components/Layout/Button.tsx | 26 +-- .../frontend/src/pages/CheckoutPage.tsx | 10 - web_server/frontend/src/pages/HomePage.tsx | 17 +- web_server/frontend/src/pages/VideoPage.tsx | 27 ++- web_server/project_structure.txt | 178 ------------------ 19 files changed, 270 insertions(+), 233 deletions(-) create mode 100644 .env.example create mode 100644 web_server/backend/.env.example create mode 100644 web_server/frontend/.env.example delete mode 100644 web_server/project_structure.txt diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7f720ff --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# Flask Backend Variables +FLASK_SECRET_KEY=your_secret_key_here +STRIPE_SECRET_KEY=sk_test_51QikGl... + +# React Frontend Variables +VITE_API_URL=http://127.0.0.1:1234 +VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51112222... \ No newline at end of file diff --git a/.gitignore b/.gitignore index 750f716..65a5c38 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ wheels/ *.egg-info/ .installed.cfg *.egg -.env +*.env venv/ ENV/ .venv @@ -56,5 +56,6 @@ Thumbs.db hls/ sockets/ dev-env/ +project_structure.txt *.db flask_session/ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 82cc065..a1e7174 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3.9' + services: nginx: build: @@ -15,10 +15,15 @@ services: build: context: ./web_server ports: - - "5000" + - "5000:5000" networks: - app_network - + env_file: + - .env + environment: + - FLASK_APP=backend.blueprints.__init__ + - FLASK_DEBUG=True + networks: app_network: - driver: bridge + driver: bridge \ No newline at end of file diff --git a/web_server/Dockerfile b/web_server/Dockerfile index 9978c8c..0105e45 100644 --- a/web_server/Dockerfile +++ b/web_server/Dockerfile @@ -3,6 +3,14 @@ FROM python:3.10 # Set the working directory WORKDIR /web_server +# Args that can be passed during build +ARG FLASK_SECRET_KEY +ARG STRIPE_SECRET_KEY + +# Set as environment variables +ENV FLASK_SECRET_KEY=${FLASK_SECRET_KEY} +ENV STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} + # Install dependencies COPY requirements.txt requirements.txt RUN pip install --no-cache-dir -r requirements.txt diff --git a/web_server/backend/.env.example b/web_server/backend/.env.example new file mode 100644 index 0000000..20c4425 --- /dev/null +++ b/web_server/backend/.env.example @@ -0,0 +1,5 @@ +# Example backend variables (for git) + +FLASK_SECRET_KEY=your_secret_key_here +STRIPE_SECRET_KEY=sk_test_51112222... +DATABASE_URL=postgresql://user:password@localhost:5432/db_name \ No newline at end of file diff --git a/web_server/backend/blueprints/__init__.py b/web_server/backend/blueprints/__init__.py index 4259cd5..a45df00 100644 --- a/web_server/backend/blueprints/__init__.py +++ b/web_server/backend/blueprints/__init__.py @@ -2,10 +2,16 @@ from flask import Flask from flask_session import Session from backend.blueprints.utils import logged_in_user from flask_cors import CORS +import os + +print("Environment variables:") +print(f"FLASK_SECRET_KEY: {os.getenv('FLASK_SECRET_KEY')}") +print(f"STRIPE_SECRET_KEY: {os.getenv('STRIPE_SECRET_KEY')}") + def create_app(): app = Flask(__name__) - app.config["SECRET_KEY"] = "" + app.config["SECRET_KEY"] = os.getenv("FLASK_SECRET_KEY") app.config["SESSION_PERMANENT"] = False app.config["SESSION_TYPE"] = "filesystem" #! ↓↓↓ For development purposes only diff --git a/web_server/backend/blueprints/main.py b/web_server/backend/blueprints/main.py index 1d646d5..9c8f147 100644 --- a/web_server/backend/blueprints/main.py +++ b/web_server/backend/blueprints/main.py @@ -1,4 +1,4 @@ -from flask import render_template, Blueprint +from flask import Blueprint main_bp = Blueprint("app", __name__) diff --git a/web_server/backend/blueprints/stripe.py b/web_server/backend/blueprints/stripe.py index a3bcf71..a9371fa 100644 --- a/web_server/backend/blueprints/stripe.py +++ b/web_server/backend/blueprints/stripe.py @@ -1,13 +1,13 @@ -from flask import render_template, Blueprint, request, jsonify - -import stripe +from flask import Blueprint, request, jsonify +import os, stripe stripe_bp = Blueprint("stripe", __name__) -stripe.api_key = 'sk_test_51QikGlGk6yuk3uA8muEMPjMhUvbZWZiMCYQArZRXcFVn26hbt1kTz5yUVWkk3RQlltArbAXmVmkfEHU2z1Ch5Obv00Y03oT127' +stripe.api_key = os.getenv("STRIPE_SECRET_KEY") @stripe_bp.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): + print("Creating checkout session") try: session = stripe.checkout.Session.create( ui_mode = 'embedded', @@ -32,7 +32,3 @@ def session_status(): session = stripe.checkout.Session.retrieve(request.args.get('session_id')) return jsonify(status=session.status, customer_email=session.customer_details.email) - -@stripe_bp.route('/checkout', methods=['GET']) -def checkout(): - return render_template("checkout.html") \ No newline at end of file diff --git a/web_server/frontend/.env.example b/web_server/frontend/.env.example new file mode 100644 index 0000000..5820fa7 --- /dev/null +++ b/web_server/frontend/.env.example @@ -0,0 +1,4 @@ +# Example frontend variables (for git) + +VITE_API_URL=http://127.0.0.1:1234 +VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51112223... \ No newline at end of file diff --git a/web_server/frontend/package-lock.json b/web_server/frontend/package-lock.json index d69e062..8151d5a 100644 --- a/web_server/frontend/package-lock.json +++ b/web_server/frontend/package-lock.json @@ -8,6 +8,8 @@ "name": "frontend", "version": "0.0.0", "dependencies": { + "@stripe/react-stripe-js": "^3.1.1", + "@stripe/stripe-js": "^5.5.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^7.1.3" @@ -1356,6 +1358,29 @@ "win32" ] }, + "node_modules/@stripe/react-stripe-js": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-3.1.1.tgz", + "integrity": "sha512-+JzYFgUivVD7koqYV7LmLlt9edDMAwKH7XhZAHFQMo7NeRC+6D2JmQGzp9tygWerzwttwFLlExGp4rAOvD6l9g==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "@stripe/stripe-js": "^1.44.1 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "react": ">=16.8.0 <20.0.0", + "react-dom": ">=16.8.0 <20.0.0" + } + }, + "node_modules/@stripe/stripe-js": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-5.5.0.tgz", + "integrity": "sha512-lkfjyAd34aeMpTKKcEVfy8IUyEsjuAT3t9EXr5yZDtdIUncnZpedl/xLV16Dkd4z+fQwixScsCCDxSMNtBOgpQ==", + "license": "MIT", + "engines": { + "node": ">=12.16" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3106,7 +3131,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3443,6 +3467,17 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3499,6 +3534,12 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", diff --git a/web_server/frontend/package.json b/web_server/frontend/package.json index e3bbe4b..5721243 100644 --- a/web_server/frontend/package.json +++ b/web_server/frontend/package.json @@ -9,8 +9,10 @@ "lint": "eslint .", "preview": "vite preview" }, - "proxy": "http://localhost:5000", + "proxy": "http://127.0.0.1:8080", "dependencies": { + "@stripe/react-stripe-js": "^3.1.1", + "@stripe/stripe-js": "^5.5.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^7.1.3" diff --git a/web_server/frontend/src/App.tsx b/web_server/frontend/src/App.tsx index 3fcf1b0..009b0ca 100644 --- a/web_server/frontend/src/App.tsx +++ b/web_server/frontend/src/App.tsx @@ -1,10 +1,10 @@ -import { BrowserRouter, Routes, Route } from 'react-router-dom'; -import HomePage from './pages/HomePage'; -import VideoPage from './pages/VideoPage'; -import LoginPage from './pages/LoginPage'; -import SignupPage from './pages/SignupPage'; -import CheckoutPage from './pages/CheckoutPage'; -import NotFoundPage from './pages/NotFoundPage'; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import HomePage from "./pages/HomePage"; +import VideoPage from "./pages/VideoPage"; +import LoginPage from "./pages/LoginPage"; +import SignupPage from "./pages/SignupPage"; +// import CheckoutPage from "./pages/CheckoutPage"; +import NotFoundPage from "./pages/NotFoundPage"; function App() { return ( @@ -14,11 +14,15 @@ function App() { } /> } /> } /> - } /> + {/* } /> */} + + {/* } /> */} + {/* } /> */} + } /> ); } -export default App; \ No newline at end of file +export default App; diff --git a/web_server/frontend/src/assets/styles/index.css b/web_server/frontend/src/assets/styles/index.css index e38e8b8..fc89180 100644 --- a/web_server/frontend/src/assets/styles/index.css +++ b/web_server/frontend/src/assets/styles/index.css @@ -2,6 +2,24 @@ @tailwind components; @tailwind utilities; +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: hsl(242, 100%, 10%); + border-radius: 5px; +} + +::-webkit-scrollbar-thumb { + background: #ff9900; + border-radius: 5px; +} + +::-webkit-scrollbar-thumb:hover { + background: #555; +} + /* :root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; diff --git a/web_server/frontend/src/components/Checkout/CheckoutForm.tsx b/web_server/frontend/src/components/Checkout/CheckoutForm.tsx index acbfa32..2add983 100644 --- a/web_server/frontend/src/components/Checkout/CheckoutForm.tsx +++ b/web_server/frontend/src/components/Checkout/CheckoutForm.tsx @@ -1 +1,95 @@ -// checkout.html \ No newline at end of file +import React, { useState, useEffect } from "react"; +import { loadStripe } from "@stripe/stripe-js"; +import { + EmbeddedCheckoutProvider, + EmbeddedCheckout, +} from "@stripe/react-stripe-js"; +import { Navigate } from "react-router-dom"; + +const API_URL = import.meta.env.VITE_API_URL; + +// Initialize Stripe once +const stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY); + + +export const Return: React.FC = () => { + const [status, setStatus] = useState(null); + const [customerEmail, setCustomerEmail] = useState(""); + + useEffect(() => { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const sessionId = urlParams.get("session_id"); + + if (sessionId) { + fetch(`${API_URL}/session-status?session_id=${sessionId}`) + .then((res) => res.json()) + .then((data) => { + setStatus(data.status); + setCustomerEmail(data.customer_email); + }); + } + }, []); + + if (status === "open") { + return ; + } + + if (status === "complete") { + return ( +
+

+ We appreciate your business! A confirmation email will be sent to{" "} + {customerEmail}. If you have any questions, please email{" "} + orders@example.com. +

+
+ ); + } + + return null; +}; + +// Main CheckoutForm component +interface CheckoutFormProps { + onClose: () => void; +} + +const CheckoutForm: React.FC = ({ onClose }) => { + const fetchClientSecret = () => { + return fetch(`${API_URL}/create-checkout-session`, { + method: "POST", + }) + .then((res) => res.json()) + .then((data) => data.clientSecret); + }; + + const options = { fetchClientSecret }; + + return ( + <> +
+
+ +
+
+ + + +
+
+
+ + ); +}; + +export default CheckoutForm; \ No newline at end of file diff --git a/web_server/frontend/src/components/Layout/Button.tsx b/web_server/frontend/src/components/Layout/Button.tsx index efa82c7..af362f1 100644 --- a/web_server/frontend/src/components/Layout/Button.tsx +++ b/web_server/frontend/src/components/Layout/Button.tsx @@ -1,17 +1,21 @@ -import React from 'react' +import React from "react"; interface ButtonProps { - title?: string; - alt?: string; - onClick?: () => void; + title?: string; + onClick?: () => void; } -const Button = ({ title, alt, onClick }: ButtonProps) => { +const Button: React.FC = ({ + title = "Submit", + onClick, +}) => { return ( -
- -
- ) -} +
+ +
+ ); +}; -export default Button +export default Button; diff --git a/web_server/frontend/src/pages/CheckoutPage.tsx b/web_server/frontend/src/pages/CheckoutPage.tsx index ed05852..e69de29 100644 --- a/web_server/frontend/src/pages/CheckoutPage.tsx +++ b/web_server/frontend/src/pages/CheckoutPage.tsx @@ -1,10 +0,0 @@ -import React from 'react'; - -const CheckoutPage: React.FC = () => { - return ( -
-
- ); -}; - -export default CheckoutPage; \ No newline at end of file diff --git a/web_server/frontend/src/pages/HomePage.tsx b/web_server/frontend/src/pages/HomePage.tsx index dbc489b..acb4837 100644 --- a/web_server/frontend/src/pages/HomePage.tsx +++ b/web_server/frontend/src/pages/HomePage.tsx @@ -3,6 +3,8 @@ import Navbar from "../components/Layout/Navbar"; import ListRow from "../components/Layout/ListRow"; // import { data, Link } from "react-router-dom"; +const API_URL = import.meta.env.VITE_API_URL; + const handleStreamClick = (streamId: string) => { // Handle navigation to stream page console.log(`Navigating to stream ${streamId}`); @@ -22,13 +24,13 @@ const HomePage: React.FC = () => { // ↓↓ runs twice when in development mode useEffect(() => { - fetch("http://127.0.0.1:5000/get_loggedin_status") + fetch(`${API_URL}/get_loggedin_status`) .then((response) => response.json()) .then((data) => { setLoggedInStatus(data); console.log(data); }); - fetch("http://127.0.0.1:5000/get_streams") + fetch(`${API_URL}/get_streams`) .then((response) => response.json()) .then((data: StreamItem[]) => { setFeaturedStreams(data); @@ -37,17 +39,20 @@ const HomePage: React.FC = () => { }, []); return ( -
+
- { + const [showCheckout, setShowCheckout] = useState(false); + const showReturn = window.location.search.includes('session_id'); + + useEffect(() => { + if (showCheckout) { + document.body.style.overflow = "hidden"; + } else { + document.body.style.overflow = "unset"; + } + // Cleanup function to ensure overflow is restored when component unmounts + return () => { + document.body.style.overflow = "unset"; + }; + }, [showCheckout]); + return (

Hello!

+ +
); }; diff --git a/web_server/project_structure.txt b/web_server/project_structure.txt deleted file mode 100644 index d912264..0000000 --- a/web_server/project_structure.txt +++ /dev/null @@ -1,178 +0,0 @@ - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 21/01/2025 17:22 __pycache__ -lar-- 21/01/2025 17:31 backend -lar-- 21/01/2025 18:14 flask_session -l---- 21/01/2025 17:09 frontend -la--- 21/01/2025 17:30 55 .flaskenv -la--- 21/01/2025 17:21 435 Dockerfile --a--- 21/01/2025 18:37 0 project_structure.txt -la--- 20/01/2025 16:53 383 requirements.txt - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 21/01/2025 17:32 __pycache__ -lar-- 21/01/2025 17:22 blueprints -lar-- 21/01/2025 17:22 database -la--- 21/01/2025 17:21 749 forms.py - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend\blueprints - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 21/01/2025 18:14 __pycache__ -la--- 21/01/2025 18:14 907 __init__.py -la--- 21/01/2025 17:31 3626 authentication.py -la--- 21/01/2025 17:21 325 main.py -la--- 21/01/2025 17:21 1294 stripe.py -la--- 21/01/2025 17:21 844 utils.py - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend\blueprints\__pycache__ - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 18:08 1155 __init__.cpython-310.pyc -la--- 21/01/2025 17:21 1673 __init__.cpython-311.pyc -la--- 21/01/2025 18:14 1572 __init__.cpython-312.pyc -la--- 21/01/2025 17:21 562 app.cpython-310.pyc -la--- 21/01/2025 17:21 2594 authentication.cpython-310.pyc -la--- 21/01/2025 17:21 5120 authentication.cpython-311.pyc -la--- 21/01/2025 17:31 4750 authentication.cpython-312.pyc -la--- 21/01/2025 17:21 564 main.cpython-310.pyc -la--- 21/01/2025 17:21 800 main.cpython-311.pyc -la--- 21/01/2025 17:31 767 main.cpython-312.pyc -la--- 21/01/2025 17:21 2457 stripe.cpython-311.pyc -la--- 21/01/2025 17:31 2347 stripe.cpython-312.pyc -la--- 21/01/2025 18:08 1393 utils.cpython-310.pyc -la--- 21/01/2025 17:21 2018 utils.cpython-311.pyc -la--- 21/01/2025 17:30 1892 utils.cpython-312.pyc - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend\database - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 21/01/2025 17:31 __pycache__ -la--- 21/01/2025 17:21 28672 app.db -la--- 21/01/2025 17:21 588 database.py -la--- 21/01/2025 17:21 5 requirements.txt -la--- 21/01/2025 17:21 990 schema.sql - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend\database\__pycache__ - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 17:21 2082 database.cpython-311.pyc -la--- 21/01/2025 17:31 1936 database.cpython-312.pyc - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\backend\__pycache__ - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 17:31 1418 forms.cpython-312.pyc - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\flask_session - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 18:14 9 2029240f6d1128be89ddc327294631 - 29 -la--- 21/01/2025 17:21 37 bd9d4040a2dcd9c9d4ed85d3dc2d6b - a7 - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 20/01/2025 17:44 src -la--- 20/01/2025 17:15 734 eslint.config.js -la--- 21/01/2025 16:58 370 index.html -la--- 20/01/2025 17:21 149648 package-lock.json -la--- 21/01/2025 18:07 837 package.json -la--- 20/01/2025 17:16 80 postcss.config.js -la--- 20/01/2025 17:16 126 tailwind.config.js -la--- 20/01/2025 17:15 665 tsconfig.app.json -la--- 20/01/2025 17:15 119 tsconfig.json -la--- 20/01/2025 17:15 593 tsconfig.node.json -la--- 20/01/2025 17:15 161 vite.config.ts - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 20/01/2025 17:15 assets -lar-- 20/01/2025 17:46 components -lar-- 21/01/2025 16:29 pages -la--- 20/01/2025 17:15 606 App.css -la--- 21/01/2025 16:30 799 App.tsx -la--- 20/01/2025 17:15 1161 index.css -la--- 20/01/2025 17:15 230 main.tsx -la--- 20/01/2025 17:15 38 vite-env.d.ts - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\assets - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 20/01/2025 17:15 4126 react.svg - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\components - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -lar-- 20/01/2025 17:47 Auth -lar-- 20/01/2025 17:47 Checkout -lar-- 20/01/2025 17:47 Layout -lar-- 20/01/2025 17:48 Video - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\components\Auth - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 20/01/2025 17:47 13 LoginForm.tsx -la--- 20/01/2025 17:47 14 SignupForm.tsx - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\components\Checkout - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 20/01/2025 17:48 16 CheckoutForm.tsx - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\components\Layout - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 20/01/2025 17:49 533 BaseLayout.tsx - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\components\Video - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 20/01/2025 17:48 709 VideoPlayer.tsx - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\frontend\src\pages - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 16:28 139 CheckoutPage.tsx -la--- 21/01/2025 16:27 309 HomePage.tsx -la--- 21/01/2025 16:28 133 LoginPage.tsx -la--- 21/01/2025 16:29 139 NotFoundPage.tsx -la--- 21/01/2025 16:29 135 SignupPage.tsx -la--- 21/01/2025 16:49 153 VideoPage.tsx - - Directory: C:\Users\chris\OneDrive - University College Cork\Documents\School\Year 3\Semester 2\CS3305 - Team Software Project\cs3305-team11\Team-Software-Project\web_server\__pycache__ - -Mode LastWriteTime Length Name ----- ------------- ------ ---- -la--- 21/01/2025 17:21 551 app.cpython-310.pyc -la--- 21/01/2025 17:21 6641 app.cpython-313.pyc -la--- 21/01/2025 17:21 976 database.cpython-310.pyc -la--- 21/01/2025 17:21 1036 forms.cpython-310.pyc -la--- 21/01/2025 17:21 1727 forms.cpython-311.pyc -la--- 21/01/2025 17:21 1291 forms.cpython-312.pyc -la--- 21/01/2025 17:21 1342 forms.cpython-313.pyc -