diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 45edf1b7..4145c686 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -1,82 +1,81 @@
-name: Staging Deployment
-on:
- pull_request:
- types: [opened, closed]
- branches: [staging]
- push:
- branches: [staging]
-
-env:
- AWS_REGION: "eu-west-3"
- AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
- AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
- AWS_ECR_REGISTRY: ${{secrets.AWS_ECR_REGISTRY}}
- AWS_ECR_REPOSITORY: ${{secrets.AWS_ECR_REPOSITORY}}
- SSH_STAGING_HOST: ${{secrets.SSH_STAGING_HOST}}
- CURAMAP_SSH_USER: ${{secrets.CURAMAP_SSH_USER}}
- SSH_STAGING_PASSWORD: ${{secrets.SSH_STAGING_PASSWORD}}
-
-concurrency:
- group: ${{github.head_ref || github.run_id}}
- cancel-in-progress: true
-
-
-jobs:
- Build_curamap_image:
- name: Build Docker Image and Push to ECR
- if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
- runs-on: ubuntu-latest
- steps:
- - name: Checkout Code
- uses: actions/checkout@v4
- with:
- fetch-depth: 1
-
- - name: Configure AWS Credentials
- uses: aws-actions/configure-aws-credentials@v4
- with:
- aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
- aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
- aws-region: ${{ env.AWS_REGION }}
-
- - name: Log-in to Elastic Container Registry
- id: login-ecr
- uses: aws-actions/amazon-ecr-login@v2
-
- - name: Build Frontend Image and Push to ECR
- uses: docker/build-push-action@v6
- with:
- context: ./Frontend
- push: true
- tags: ${{ env.AWS_ECR_REGISTRY }}/${{ env.AWS_ECR_REPOSITORY }}:frontend
-
- - name: Build Backend Image and Push to ECR
- uses: docker/build-push-action@v6
- with:
- context: ./Backend
- push: true
- tags: ${{ env.AWS_ECR_REGISTRY }}/${{ env.AWS_ECR_REPOSITORY }}:backend
-
-
- Deploy_to_Staging:
- name: Deploy to Staging EC2 Server
- if: github.ref == 'refs/heads/staging'
- needs: [Build_curamap_image]
- runs-on: ubuntu-latest
- steps:
- - name: Deploy to EC2 Server ⏳
- uses: appleboy/ssh-action@master
- with:
- host: ${{ env.SSH_STAGING_HOST }}
- username: ${{ env.CURAMAP_SSH_USER }}
- password: ${{ env.SSH_STAGING_PASSWORD }}
- script: |
- set -ex
- export IMAGE_TAG=latest
- cd ~/curamap
- aws ecr get-login-password --region eu-west-3 | docker login --username AWS --password-stdin ${{ env.AWS_ECR_REGISTRY }}
- docker compose pull curamap-frontend curamap-backend
- docker compose down -v --remove-orphans
- docker compose up -d --force-recreate curamap-frontend curamap-backend
- docker image prune -af
-
+name: Staging Deployment
+on:
+ pull_request:
+ types: [opened, closed]
+ branches: [staging]
+ push:
+ branches: [staging]
+
+env:
+ AWS_REGION: "eu-west-3"
+ AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
+ AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
+ AWS_ECR_REGISTRY: ${{secrets.AWS_ECR_REGISTRY}}
+ AWS_ECR_REPOSITORY: ${{secrets.AWS_ECR_REPOSITORY}}
+ SSH_STAGING_HOST: ${{secrets.SSH_STAGING_HOST}}
+ CURAMAP_SSH_USER: ${{secrets.CURAMAP_SSH_USER}}
+ SSH_STAGING_PASSWORD: ${{secrets.SSH_STAGING_PASSWORD}}
+
+concurrency:
+ group: ${{github.head_ref || github.run_id}}
+ cancel-in-progress: true
+
+
+jobs:
+ Build_curamap_image:
+ name: Build Docker Image and Push to ECR
+ if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
+ aws-region: ${{ env.AWS_REGION }}
+
+ - name: Log-in to Elastic Container Registry
+ id: login-ecr
+ uses: aws-actions/amazon-ecr-login@v2
+
+ - name: Build Frontend Image and Push to ECR
+ uses: docker/build-push-action@v6
+ with:
+ context: ./Frontend
+ push: true
+ tags: ${{ env.AWS_ECR_REGISTRY }}/${{ env.AWS_ECR_REPOSITORY }}:frontend
+
+ - name: Build Backend Image and Push to ECR
+ uses: docker/build-push-action@v6
+ with:
+ context: ./Backend
+ push: true
+ tags: ${{ env.AWS_ECR_REGISTRY }}/${{ env.AWS_ECR_REPOSITORY }}:backend
+
+
+ Deploy_to_Staging:
+ name: Deploy to Staging EC2 Server
+ if: github.ref == 'refs/heads/staging'
+ needs: [Build_curamap_image]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Deploy to EC2 Server ⏳
+ uses: appleboy/ssh-action@master
+ with:
+ host: ${{ env.SSH_STAGING_HOST }}
+ username: ${{ env.CURAMAP_SSH_USER }}
+ password: ${{ env.SSH_STAGING_PASSWORD }}
+ script: |
+ set -ex
+ export IMAGE_TAG=latest
+ cd ~/curamap
+ aws ecr get-login-password --region eu-west-3 | docker login --username AWS --password-stdin ${{ env.AWS_ECR_REGISTRY }}
+ docker compose pull curamap-frontend curamap-backend
+ docker compose down -v --remove-orphans
+ docker compose up -d --force-recreate curamap-frontend curamap-backend
+ docker image prune -af
diff --git a/Backend/controllers/Medicine.js b/Backend/controllers/Medicine.js
new file mode 100644
index 00000000..c4f1c9d3
--- /dev/null
+++ b/Backend/controllers/Medicine.js
@@ -0,0 +1,59 @@
+// medicines.controller.js
+const Medicine = require("../models/Medicine");
+
+// Create a new medicine
+exports.createMedicine = async (req, res, next) => {
+ try {
+ const medicine = new Medicine(req.body);
+ await medicine.save();
+ res.status(201).json(medicine);
+ } catch (err) {
+ next(err);
+ }
+};
+
+// Get all medicines
+exports.getMedicines = async (req, res, next) => {
+ try {
+ const meds = await Medicine.find();
+ res.json(meds);
+ } catch (err) {
+ next(err);
+ }
+};
+
+// Get one by ID
+exports.getMedicineById = async (req, res, next) => {
+ try {
+ const med = await Medicine.findById(req.params.id);
+ if (!med) return res.status(404).json({ message: "Medicine not found" });
+ res.json(med);
+ } catch (err) {
+ next(err);
+ }
+};
+
+// Update by ID
+exports.updateMedicine = async (req, res, next) => {
+ try {
+ const med = await Medicine.findByIdAndUpdate(req.params.id, req.body, {
+ new: true,
+ runValidators: true,
+ });
+ if (!med) return res.status(404).json({ message: "Medicine not found" });
+ res.json(med);
+ } catch (err) {
+ next(err);
+ }
+};
+
+// Delete by ID
+exports.deleteMedicine = async (req, res, next) => {
+ try {
+ const med = await Medicine.findByIdAndDelete(req.params.id);
+ if (!med) return res.status(404).json({ message: "Medicine not found" });
+ res.status(204).end();
+ } catch (err) {
+ next(err);
+ }
+};
diff --git a/Backend/controllers/pharmacyController.js b/Backend/controllers/pharmacyController.js
index dc89321f..0312ecc9 100644
--- a/Backend/controllers/pharmacyController.js
+++ b/Backend/controllers/pharmacyController.js
@@ -173,7 +173,9 @@ exports.toggleClosingStatus = async (req, res) => {
// @desc post pharmacy Forgot password
// @route POST /api/pharmacies/forgot-password
exports.forgotPassword = async (req, res) => {
- const pharmacy = await pharmacy.findOne({ email: req.body.email.trim().toLowerCase() });
+ const pharmacy = await pharmacy.findOne({
+ email: req.body.email.trim().toLowerCase(),
+ });
if (!pharmacy) {
return res.status(404).json({ message: "Pharmacy not found" });
}
@@ -204,8 +206,7 @@ exports.forgotPassword = async (req, res) => {
message: "Error sending email. Please try again later.",
});
}
-}
-
+};
// @desc patch pharmacy reset password
// @route PATCH /api/pharmacies/reset-password/:token
@@ -221,17 +222,17 @@ exports.resetPassword = async (req, res) => {
passwordResetToken: hashedToken,
passwordResetExpires: { $gt: Date.now() },
});
-
+
if (!pharmacy) {
return res.status(400).json({ message: "Invalid or expired token" });
}
-
+
pharmacy.password = req.body.password;
pharmacy.passwordResetToken = undefined;
pharmacy.passwordResetExpires = undefined;
-
+
await pharmacy.save();
-
+
res.status(200).json({ message: "Password reset successful" });
//login pharmacy
const loginToken = generateToken(pharmacy);
@@ -240,6 +241,6 @@ exports.resetPassword = async (req, res) => {
token: loginToken,
});
} catch (err) {
- res.status(500).json({message: "Server error", error: err.message });
+ res.status(500).json({ message: "Server error", error: err.message });
}
-}
\ No newline at end of file
+};
diff --git a/Backend/data/medicines.js b/Backend/data/medicines.js
new file mode 100644
index 00000000..b16f335d
--- /dev/null
+++ b/Backend/data/medicines.js
@@ -0,0 +1,66 @@
+module.exports = [
+ {
+ name: "Paracetamol",
+ description: "Pain reliever and fever reducer",
+ dosages: ["500mg", "650mg"],
+ packageSizes: ["10 tablets", "20 tablets"],
+ prescription: false,
+ prices: {
+ Nigeria: {
+ "500mg": 100,
+ "650mg": 120,
+ },
+ Ghana: {
+ "500mg": 80,
+ "650mg": 100,
+ },
+ },
+ },
+ {
+ name: "Amoxicillin",
+ description: "Used to treat bacterial infections",
+ dosages: ["250mg", "500mg"],
+ packageSizes: ["capsules", "syrup"],
+ prescription: true,
+ prices: {
+ Nigeria: {
+ "250mg": 150,
+ "500mg": 200,
+ },
+ Kenya: {
+ "250mg": 130,
+ "500mg": 180,
+ },
+ },
+ },
+ {
+ name: "Ibuprofen",
+ description: "Reduces fever and treats pain or inflammation",
+ dosages: ["200mg", "400mg"],
+ packageSizes: ["24 tablets", "12 tablets"],
+ prescription: false,
+ prices: {
+ Nigeria: {
+ "200mg": 90,
+ "400mg": 160,
+ },
+ Ghana: {
+ "200mg": 75,
+ "400mg": 140,
+ },
+ },
+ },
+ {
+ name: "Vitamin C",
+ description: "Boosts immune system",
+ dosages: ["100mg", "500mg"],
+ packageSizes: ["30 tablets", "60 tablets"],
+ prescription: false,
+ prices: {
+ Nigeria: {
+ "100mg": 70,
+ "500mg": 120,
+ },
+ },
+ },
+];
diff --git a/Backend/index.js b/Backend/index.js
index 76d420fa..f56e3d65 100644
--- a/Backend/index.js
+++ b/Backend/index.js
@@ -8,6 +8,7 @@ const app = express();
// Route Imports
const pharmacyRoutes = require("./routes/pharmacyRoutes");
const patientRoutes = require("./routes/patientRoutes");
+const medicineRoutes = require("./routes/medicine");
// Middleware
app.use(express.json());
@@ -27,6 +28,8 @@ app.use(cors());
// Routes
app.use("/api/pharmacies", pharmacyRoutes);
app.use("/api/patients", patientRoutes);
+app.use("/api/medicines", medicineRoutes);
+
// Database Connection
mongoose
.connect(process.env.DB_URI, { serverSelectionTimeoutMS: 60000 })
diff --git a/Backend/models/Medicine.js b/Backend/models/Medicine.js
new file mode 100644
index 00000000..f71e4c7b
--- /dev/null
+++ b/Backend/models/Medicine.js
@@ -0,0 +1,27 @@
+// medicines.model.js
+const mongoose = require("mongoose");
+const { Schema } = mongoose;
+
+const medicineSchema = new Schema(
+ {
+ name: { type: String, required: true },
+ description: { type: String },
+ dosages: [{ type: String }],
+ packageSizes: [{ type: String }],
+ prescription: { type: Boolean, default: false },
+ prices: {
+ type: Map,
+ of: new Schema(
+ {
+ type: Map,
+ of: Number,
+ },
+ { _id: false }
+ ),
+ required: true,
+ },
+ },
+ { timestamps: true }
+);
+
+module.exports = mongoose.model("Medicine", medicineSchema);
diff --git a/Backend/models/PharmacyModel.js b/Backend/models/PharmacyModel.js
index 3a043354..5f8d457a 100644
--- a/Backend/models/PharmacyModel.js
+++ b/Backend/models/PharmacyModel.js
@@ -8,15 +8,15 @@ const pharmacySchema = new mongoose.Schema(
default: () => new mongoose.Types.ObjectId().toString(),
},
name: { type: String, required: true }, // Pharmacy Name
- owner: { type: String, required: true }, // Owner's Name
+ owner: { type: String }, // Owner's Name
email: { type: String, required: true, unique: true },
- phone: { type: String, required: true },
- address: { type: String, required: true },
- city: { type: String, required: true },
- state: { type: String, required: true },
- country: { type: String, required: true },
+ phone: { type: String },
+ address: { type: String },
+ city: { type: String },
+ state: { type: String },
+ country: { type: String },
website: { type: String }, // Optional website
- licenseNumber: { type: String, required: true, unique: true }, // Regulatory License Number
+ licenseNumber: { type: String, unique: true }, // Regulatory License Number
password: { type: String, required: true },
passwordChangeAt: { type: Date },
passwordResetToken: { type: String },
@@ -28,7 +28,6 @@ const pharmacySchema = new mongoose.Schema(
},
openingHours: {
type: String,
- required: true, // e.g., "8:00 AM - 10:00 PM"
},
closingStatus: {
type: Boolean,
@@ -59,7 +58,10 @@ pharmacySchema.methods.comparePassword = async function (password) {
pharmacySchema.methods.generatePasswordResetToken = function () {
const resetToken = crypto.randomBytes(32).toString("hex");
// Hashing the token for protection
- this.passwordResetToken = crypto.createHash("sha256").update(resetToken).digest("hex");
+ this.passwordResetToken = crypto
+ .createHash("sha256")
+ .update(resetToken)
+ .digest("hex");
// Set the expiration time for the token
this.passwordResetExpires = Date.now() + 10 * 60 * 1000; // 10 minutes expiration
diff --git a/Backend/routes/medicine.js b/Backend/routes/medicine.js
new file mode 100644
index 00000000..6bc4a4fe
--- /dev/null
+++ b/Backend/routes/medicine.js
@@ -0,0 +1,14 @@
+// routes/medicineRoutes.js
+
+const express = require("express");
+const router = express.Router();
+const ctrl = require("../controllers/Medicine");
+
+router.post("/", ctrl.createMedicine);
+router.get("/", ctrl.getMedicines);
+router.get("/:id", ctrl.getMedicineById);
+router.put("/:id", ctrl.updateMedicine);
+router.delete("/:id", ctrl.deleteMedicine);
+
+// ✅ Export just the router
+module.exports = router;
diff --git a/Backend/seeds/seedMedicines.js b/Backend/seeds/seedMedicines.js
new file mode 100644
index 00000000..50541321
--- /dev/null
+++ b/Backend/seeds/seedMedicines.js
@@ -0,0 +1,25 @@
+const mongoose = require("mongoose");
+const Medicine = require("../models/Medicine");
+const medicines = require("../data/medicines");
+require("dotenv").config();
+
+const MONGO_URI = process.env.DB_URI;
+
+const seed = async () => {
+ try {
+ await mongoose.connect(MONGO_URI, {
+ useNewUrlParser: true,
+ useUnifiedTopology: true,
+ });
+
+ await Medicine.deleteMany();
+ await Medicine.insertMany(medicines);
+ console.log("✅ Medicines seeded successfully.");
+ process.exit(0);
+ } catch (err) {
+ console.error("❌ Error seeding medicines:", err);
+ process.exit(1);
+ }
+};
+
+seed();
diff --git a/Frontend/.gitignore b/Frontend/.gitignore
index a547bf36..5c0b45a0 100644
--- a/Frontend/.gitignore
+++ b/Frontend/.gitignore
@@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+
+# Ignore the .env file
+.env
diff --git a/Frontend/src/App.jsx b/Frontend/src/App.jsx
index 1c2dbc0a..7eb1b5c8 100644
--- a/Frontend/src/App.jsx
+++ b/Frontend/src/App.jsx
@@ -17,11 +17,12 @@ import OrderSummary from "./pages/OrderSummary";
// import ProfileSignup from "./pages/ProfileSignup";
import FindMedsLoading from "./components/FindMedsLoading";
import UpdatedCart from "./pages/UpdatedCart";
-import PhamarcySignUp from "./components/forms/PhamarcySignUp";
+import NewPharmarcySignUp from "./components/forms/NewPharmarcySignUp";
import MedicineTable from "./components/MedicineTable";
import UploadPrescription from "./pages/UploadPrescription";
import PharmacyOtp from "./components/PharmacyOtp";
import OtpConfirmed from "./components/OtpConfirmed";
+import Pharmarcysignin from "./components/forms/Pharmarcysignin";
// Code splitted Components (Lazy Loading)...
// N.B- Please do not touch if you're new to how lazy loading works..
@@ -133,7 +134,8 @@ function App() {
{/* Pharmacy Routing */}
} />
} />
- } />
+ } />
+ } />
} />
} />
} />
diff --git a/Frontend/src/components/PaymentModal.jsx b/Frontend/src/components/PaymentModal.jsx
index dce43d04..3882a348 100644
--- a/Frontend/src/components/PaymentModal.jsx
+++ b/Frontend/src/components/PaymentModal.jsx
@@ -1,16 +1,25 @@
// import React from "react";
import React, { useState } from "react";
+import { useLocation, useNavigate } from "react-router-dom";
import "../styles/paymentmodal.css";
import { FaHospital, FaMoneyBillWave, FaLock } from "react-icons/fa";
const PaymentModal = () => {
+ const { state } = useLocation();
+ const total = state?.total || 0; // Default value if not provided
const [selectedMethod, setSelectedMethod] = useState("pharmacy");
+ const navigate = useNavigate();
+
+ const handleOtppage = () => {
+ navigate("/otp-page")
+ }
+
return (
Update payment method
-
Pay 40,000
+
Pay {total}
@@ -46,14 +59,15 @@ const PaymentModal = () => {
value="transfer"
checked={selectedMethod === "transfer"}
onChange={() => setSelectedMethod("transfer")}
+ disabled
/>
{" "}
Pay with Transfer
@@ -61,7 +75,9 @@ const PaymentModal = () => {
{/* Buttons */}
-
+
{/* Security Info */}
diff --git a/Frontend/src/components/forms/NewPharmarcySignUp.jsx b/Frontend/src/components/forms/NewPharmarcySignUp.jsx
new file mode 100644
index 00000000..8ed1ad11
--- /dev/null
+++ b/Frontend/src/components/forms/NewPharmarcySignUp.jsx
@@ -0,0 +1,170 @@
+import React, { useState } from "react";
+import styles from "../../styles/newpharmacysignup.module.css";
+import caretleft from "../../assets/CaretLeft.png";
+import cancelicon from "../../assets/X.png";
+
+const InputField = ({ id, name, type, placeholder, value, onChange }) => (
+
+);
+
+const NewPharmarcySignUp = () => {
+ const [formData, setFormData] = useState({
+ name: "",
+ email: "",
+ password: "",
+ confirmPassword: "",
+ phone: "",
+ address: "",
+ });
+
+ const [error, setError] = useState("");
+ const [success, setSuccess] = useState(false);
+ const [loading, setLoading] = useState(false);
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData({ ...formData, [name]: value });
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ setError("");
+ setSuccess(false);
+
+ // Basic validation
+ if (
+ !formData.name ||
+ !formData.email ||
+ !formData.password ||
+ !formData.confirmPassword ||
+ !formData.phone ||
+ !formData.address
+ ) {
+ setError("All fields are required.");
+ return;
+ }
+
+ if (formData.password !== formData.confirmPassword) {
+ setError("Passwords do not match.");
+ return;
+ }
+
+ setLoading(true);
+
+ try {
+ const response = await fetch(
+ `${import.meta.env.VITE_API_URL}/pharmacies/signup`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(formData),
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error("Failed to sign up. Please try again.");
+ }
+
+ const data = await response.json();
+ setSuccess(true);
+ setFormData({
+ name: "",
+ email: "",
+ password: "",
+ confirmPassword: "",
+ phone: "",
+ address: "",
+ });
+ } catch (err) {
+ setError(err.message);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+

+
Create Account
+

+
+
+
+
Already have an account?
+
Log in
+
+
+
+ );
+};
+
+export default NewPharmarcySignUp;
diff --git a/Frontend/src/components/forms/PhamarcySignUp.jsx b/Frontend/src/components/forms/PhamarcySignUp.jsx
deleted file mode 100644
index f9360ab5..00000000
--- a/Frontend/src/components/forms/PhamarcySignUp.jsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React from "react";
-import "../../styles/pharmacysignup.css";
-import caretleft from "../../assets/CaretLeft.png";
-import cancelicon from "../../assets/X.png"
-const PhamarcySignUp = () => {
- return (
-
-
-

-

-
-
-
- {" "}
-
Already have An Account
-
Login in
-
-
- );
-};
-
-export default PhamarcySignUp;
diff --git a/Frontend/src/components/forms/Pharmarcysignin.jsx b/Frontend/src/components/forms/Pharmarcysignin.jsx
new file mode 100644
index 00000000..cfeb306b
--- /dev/null
+++ b/Frontend/src/components/forms/Pharmarcysignin.jsx
@@ -0,0 +1,130 @@
+import React, { useState } from "react";
+import styles from "../../styles/pharmacysignin.module.css";
+import caretleft from "../../assets/CaretLeft.png";
+import cancelicon from "../../assets/X.png";
+import { useNavigate } from "react-router-dom";
+
+const Pharmarcysignin = () => {
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [rememberMe, setRememberMe] = useState(false);
+ const [error, setError] = useState("");
+
+ const handleSignIn = async (e) => {
+ // Prevent Default submission
+ e.preventDefault();
+ setError("");
+
+ try {
+ const response = await fetch(
+ // "https://new-cura.onrender.com/api/pharmacies/signin",
+ `${import.meta.env.VITE_API_URL}/pharmacies/signin`,
+
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ email, password }),
+ }
+ );
+
+ const data = await response.json();
+
+ if (response.ok) {
+ localStorage.setItem("authtoken", data.token);
+ navigate("/dashboard");
+ } else if (response.status === 401) {
+ const data = await response.json();
+ setError(data.message || "Invalid email or password.");
+ } else if (response.status === 404) {
+ setError("Account not found. Please check your email.");
+ } else {
+ setError(data.message || "Sign-in failed. Please try again.");
+ }
+ } catch (error) {
+ setError("Network error. Please try again later.");
+ console.error("Sign-in error:", error);
+ }
+ };
+
+ const navigate = useNavigate();
+
+ const handleSignUp = () => {
+ navigate("/signup-email");
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ };
+ return (
+
+
+
+

+
Log In
+

+
+
+
+
Don't have an account?
+
Sign up
+
+
+
+ );
+};
+
+export default Pharmarcysignin;
diff --git a/Frontend/src/components/forms/SignIn.jsx b/Frontend/src/components/forms/SignIn.jsx
index bbc47f4a..19e3158c 100644
--- a/Frontend/src/components/forms/SignIn.jsx
+++ b/Frontend/src/components/forms/SignIn.jsx
@@ -16,7 +16,8 @@ const SignIn = () => {
try {
const response = await fetch(
- "https://new-cura.onrender.com/api/patients/signin",
+ `${import.meta.env.VITE_API_URL}/patients/signin`,
+
{
method: "POST",
headers: {
@@ -95,7 +96,7 @@ const SignIn = () => {
/>
Remember Me
-
Forgot password?
+
Forgot password?
@@ -259,4 +313,4 @@ const SignUp = () => {
);
};
-export default SignUp;
+export default SignUp;
\ No newline at end of file
diff --git a/Frontend/src/main.jsx b/Frontend/src/main.jsx
index 44e5058c..178d0cac 100644
--- a/Frontend/src/main.jsx
+++ b/Frontend/src/main.jsx
@@ -5,10 +5,12 @@ import "./index.css";
import App from "./App.jsx";
+
createRoot(document.getElementById("root")).render(
+
);
diff --git a/Frontend/src/pages/LandingPage.jsx b/Frontend/src/pages/LandingPage.jsx
index 011720a6..a2a7c571 100644
--- a/Frontend/src/pages/LandingPage.jsx
+++ b/Frontend/src/pages/LandingPage.jsx
@@ -54,13 +54,17 @@ const LandingPage = () => {
to prioritize your wellbeing without the hassle.
-
-
Sign Up
-
Sign In
+
+
+ Sign Up
+ Sign In
+
+
+
-
+
Connecting Patients to Pharmacies For Easy Medication Access.
@@ -120,7 +124,7 @@ const LandingPage = () => {
-
How is curamap Different ?
+
How is curamap Different ?
@@ -341,7 +345,10 @@ const LandingPage = () => {
Youtube
+
Terms And Conditions | Privacy Policy
+
+
);
diff --git a/Frontend/src/pages/OrderSummary.jsx b/Frontend/src/pages/OrderSummary.jsx
index 5eb842d3..6c6a0d3e 100644
--- a/Frontend/src/pages/OrderSummary.jsx
+++ b/Frontend/src/pages/OrderSummary.jsx
@@ -16,11 +16,13 @@ const OrderSummary = () => {
const backToSelection = () =>
navigate("/findmeds", { state: { selectedMedicines } });
const proceedToCheckout = () =>
- navigate("/payment-modal", { state: { selectedMedicines, pharmacy } });
+ navigate("/payment-modal", {
+ state: { selectedMedicines, pharmacy, total },
+ });
const subtotal = selectedMedicines.reduce((acc, medicine) => {
const { price, quantity } = medicine;
- const calculatedPrice = Number(price) * Number(quantity);
+ const calculatedPrice = Number(price) + Number(quantity);
const totalMedicinePrice = calculatedPrice * (quantity || 1);
return acc + totalMedicinePrice;
@@ -28,7 +30,7 @@ const OrderSummary = () => {
const tax = 1500;
- const total = subtotal + tax;
+ const total = (subtotal + tax).toFixed(2); // Total price including tax
// Check if any prescription medicines are selected
@@ -63,11 +65,11 @@ const OrderSummary = () => {
-
*/}
+ {/*
100% Secure
*/}
- Back to Selection
+ Find more Meds
@@ -148,7 +150,7 @@ const OrderSummary = () => {
Total:
- ₦{total.toFixed(2)}
+ ₦{total}
diff --git a/Frontend/src/pages/OtpPage.jsx b/Frontend/src/pages/OtpPage.jsx
index ad55c349..013fd8bd 100644
--- a/Frontend/src/pages/OtpPage.jsx
+++ b/Frontend/src/pages/OtpPage.jsx
@@ -2,39 +2,52 @@ import "../styles/otppage.css";
import onePic from "../assets/one.com.png";
import twoPic from "../assets/two.com.png";
import threePic from "../assets/three.com.png";
+import { useNavigate } from "react-router-dom";
-function OtpPage(){
+function OtpPage() {
+ const navigate = useNavigate();
- return(
-
-
+ const handleContinue = () => {
+ navigate("/locate-pharmacy");
+ };
-
-
Check your Email or phone number for OTP
-
+ return (
+
+
+
+
Check your Email or phone number for OTP
+
-
Here’s how it works
+
Here’s how it works
-
-
-
-
Arrive at the pharmacy
+
+
+
+

+
+
Arrive at the pharmacy
+
+
+
+

+
+
Meet the pharmacist and provide OTP
+
+
+
+

+
+
Pharmacist confirms your pick up
+
+
+
+ Continue
+
+
+
-
-
-
Meet the pharmacist and provide OTP
-
-
-
-
Pharmacist confirms your pick up
-
-
-
-
-
-
- );
+ );
}
-export default OtpPage;
\ No newline at end of file
+export default OtpPage;
diff --git a/Frontend/src/pages/SearchpageSummary.jsx b/Frontend/src/pages/SearchpageSummary.jsx
index b3b75106..b216c8cf 100644
--- a/Frontend/src/pages/SearchpageSummary.jsx
+++ b/Frontend/src/pages/SearchpageSummary.jsx
@@ -28,8 +28,8 @@ const SearchpageSummary = () => {
Selected Medicines:
{selectedMedicines.map((medicine) => {
- const { price, quantity } = medicine;
- const calculatedPrice = Number(price) * Number(quantity);
+ const { price } = medicine;
+ const calculatedPrice = Number(price);
return (
-
@@ -50,7 +50,7 @@ const SearchpageSummary = () => {
onClick={viewShoppingCart}
className="summary-btn view-cart-btn"
>
- View Shopping Cart
+ Find more Meds
{
disabled={selectedMedicines.length === 0}
className="summary-btn continue-btn"
>
- Continue Shopping
+ Continue
{/* Prescription warning message */}
diff --git a/Frontend/src/pages/UpdatedCart.jsx b/Frontend/src/pages/UpdatedCart.jsx
index b9dc82ae..1177faca 100644
--- a/Frontend/src/pages/UpdatedCart.jsx
+++ b/Frontend/src/pages/UpdatedCart.jsx
@@ -26,24 +26,24 @@ const UpdatedCart = () => {
- navigate("/order-summary", {
- state: { selectedMedicines, pharmacy },
- })
+ navigate("/findmeds", { state: { selectedMedicines } })
}
disabled={selectedMedicines.length === 0}
- className={styles.shoppingCartBtn}
+ className={styles.backBtn}
>
- View Shopping Cart
+ Find more meds
- navigate("/findmeds", { state: { selectedMedicines } })
+ navigate("/order-summary", {
+ state: { selectedMedicines, pharmacy },
+ })
}
disabled={selectedMedicines.length === 0}
className={styles.continueBtn}
>
- Continue Shopping
+ Checkout
diff --git a/Frontend/src/styles/landingpage.css b/Frontend/src/styles/landingpage.css
index 56ef69c8..794519bb 100644
--- a/Frontend/src/styles/landingpage.css
+++ b/Frontend/src/styles/landingpage.css
@@ -14,7 +14,7 @@ body {
.landing-page-container {
display: flex;
flex-direction: column;
- gap: 7rem;
+ gap: 0rem;
}
.Logo {
@@ -23,6 +23,7 @@ body {
justify-items: center;
padding-left: 1.5rem;
padding-top: 1.5rem;
+ margin-left: 4em;
}
.Logo img:nth-child(1) {
@@ -33,18 +34,12 @@ body {
.MainContent {
display: flex;
- align-items: center;
- justify-content: center;
+ align-content: flex-start;
height: 100%;
gap: 10rem;
}
-.TextContent {
- display: flex;
- flex-direction: column;
- gap: 3rem;
- max-width: 600px;
-}
+
.TextContent h1 {
font-size: 3rem;
@@ -60,12 +55,18 @@ body {
line-height: 1.6;
}
-.Buttons {
+.Buttons-and-banner {
display: flex;
- gap: 1rem;
+ justify-content: center;
+ align-items: flex-end;
+ gap: 28rem;
+ margin-top: -23em;
}
-.Buttons button {
+.buttons-container {
+ display: flex;
+}
+.Buttons-and-banner button {
padding: 0.5rem 2rem;
border-radius: 4px;
font-size: 1rem;
@@ -74,23 +75,29 @@ body {
transition: all 0.2s;
}
-.Buttons button:first-child {
+.button-1 {
background-color: transparent;
+ height: 4em;
+ width: 10em;
+ text-wrap: nowrap;
color: #007e85;
border: none;
}
-.Buttons button:first-child:hover {
+.button-1:hover {
color: #0f0f0f;
}
-.Buttons button:last-child {
+.button-2 {
background-color: #007e85;
+ height: 4em;
+ width: 10em;
+ text-wrap: nowrap;
color: #f0f7ff;
border: 1px solid #4a9eff;
}
-.Buttons button:last-child:hover {
+.button-2:hover {
color: #080808;
}
@@ -101,6 +108,7 @@ body {
max-width: 100%;
}
.MainContent img:nth-child(2) {
+ margin-top: 1em;
max-width: 550px;
width: 100%;
height: auto;
@@ -270,6 +278,9 @@ body {
flex-direction: column;
}
+.fourth-level-content h2 {
+ font-size: 1.5em;
+}
/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
/* .name-pre h4,
p {
@@ -325,8 +336,14 @@ p {
.fifth-level-content {
display: flex;
flex-direction: column;
+ margin-bottom: 4em;
}
+.fifth-level-content h2 {
+ font-size: 1.6em;
+ margin-left: 2em;
+ margin-bottom: 4em;
+}
.fifth-card-container {
display: flex;
justify-content: center;
@@ -393,6 +410,11 @@ p {
.card-6 p {
margin-bottom: 4em;
}
+
+.colorbuttons-container {
+ margin: 0 auto;
+ margin-top: 4em;
+}
/* sixth levl content*/
.sixth-level-content {
@@ -523,6 +545,10 @@ p {
gap: 1.2em;
list-style-type: none;
}
+
+.Terms-container {
+ margin-top: 12em;
+}
/* Responsive Design */
/* Small Mobile Devices (up to 576px) */
diff --git a/Frontend/src/styles/newpharmacysignup.module.css b/Frontend/src/styles/newpharmacysignup.module.css
new file mode 100644
index 00000000..868dcc77
--- /dev/null
+++ b/Frontend/src/styles/newpharmacysignup.module.css
@@ -0,0 +1,63 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100vh;
+ background-image: url("../assets/Background.svg");
+ background-size: cover;
+ background-position: center;
+}
+.signupSection {
+ width: 100%;
+ max-width: 400px;
+ background-color: #fff;
+ border-radius: 10px;
+ padding: 20px 30px 20px 30px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1;
+
+ > .headerNav {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ }
+ > form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ > input {
+ width: 100%;
+ padding: 10px;
+ border-radius: 4px;
+ border: 1px solid #110f0f;
+ font-size: 16px;
+ }
+ > .signupbtn {
+ width: 100%;
+ padding: 7px;
+ border-radius: 4px;
+ border: none;
+ outline: none;
+ font-size: 16px;
+ background-color: #83c0b9;
+ color: white;
+ cursor: pointer;
+ margin-bottom: 5px;
+ &:hover {
+ background-color: #6da8a0;
+ }
+ }
+ }
+ > .redirectLink {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 5px;
+ > a {
+ text-decoration: none;
+ color: #83c0b9;
+ }
+ }
+}
diff --git a/Frontend/src/styles/order-summary.css b/Frontend/src/styles/order-summary.css
index e2d2aef3..476a7967 100644
--- a/Frontend/src/styles/order-summary.css
+++ b/Frontend/src/styles/order-summary.css
@@ -1,5 +1,5 @@
.shopping-cart {
- padding: 0px 30px;
+ padding: 20px 30px;
}
.search-header {
@@ -54,6 +54,7 @@
.cart-text {
display: flex;
align-items: center;
+ padding-block: 1rem;
}
.cart-text-1 {
diff --git a/Frontend/src/styles/otppage.css b/Frontend/src/styles/otppage.css
index 627777ce..f29e363b 100644
--- a/Frontend/src/styles/otppage.css
+++ b/Frontend/src/styles/otppage.css
@@ -1,47 +1,58 @@
-.bodyotp{
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- margin: 0;
-
-
+.bodyotp {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ margin: 0;
}
-
.boxOne {
- width:800px;
- height: 80vh;
+ width: 800px;
+ min-height: 80vh;
padding: 35px;
- background-color: white;
+ background-color: white;
}
-.topText{
- text-align: center;
- color: grey;
+.topText {
+ text-align: center;
+ color: grey;
}
.bodyotp {
-line-height: 2.4;
+ line-height: 2.4;
}
.boxTwo {
- display: flex;
- flex-direction: column;
- gap: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
}
-
+
.boxchilds {
- border: 1px solid black;
- height: 10vh;
- width: 400px;
- margin-left: 80px;
- border-radius: 8px;
- display: flex;
- padding: 20px;
- gap: 50px;
- color:grey
-}
-.onlyAchord{
- margin: 0 auto;
+ border: 1px solid black;
+ min-height: 10vh;
+ width: 400px;
+ margin-left: 80px;
+ border-radius: 8px;
+ display: flex;
+ padding: 20px;
+ gap: 50px;
+ color: grey;
+}
+.onlyAchord {
+ margin: 0 auto;
+}
+
+.otp-cta {
+ width: 150px;
+ border: none;
+ background-color: rgba(0, 168, 67, 0.795);
+ color: #fff;
+ border-radius: 4px;
+ cursor: pointer;
+
+ &:hover {
+ background-color: rgb(0, 84, 0);
+ }
}
diff --git a/Frontend/src/styles/pharmacylogin.css b/Frontend/src/styles/pharmacylogin.css
new file mode 100644
index 00000000..e2fce678
--- /dev/null
+++ b/Frontend/src/styles/pharmacylogin.css
@@ -0,0 +1,65 @@
+.pharmacy-login-container {
+ position: relative;
+ background-image: url("../assets/Background.svg");
+ width: 100%;
+ height: 150vh;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ z-index: -2;
+ }
+
+ .direction-header {
+ position: absolute;
+ top: 6em;
+ display: flex;
+ gap: 20rem;
+ }
+
+ form {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ max-width: 600px;
+ margin-top: -250px;
+ background: #f9fdfd;
+ border-radius: 10px;
+ padding: 20px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ width: 50rem;
+ height: 100vh;
+ z-index: -1;
+ }
+
+ input[type="email"],
+ input[type="password"] {
+ width: 100%;
+ padding: 10px 90px;
+ margin: 10px 0;
+ outline: none;
+ border: none;
+ border-radius: 4px;
+ border: 2px solid #110f0f;
+ font-size: 16px;
+ }
+
+ button {
+ width: 50px 60px;
+ padding: 10px 150px;
+ border-radius: 4px;
+ border: 1px solid #0e0d0d;
+ font-size: 16px;
+ margin-top: 40px;
+ }
+ .redirect-link {
+ margin-top: -50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ }
+
\ No newline at end of file
diff --git a/Frontend/src/styles/pharmacysignin.module.css b/Frontend/src/styles/pharmacysignin.module.css
new file mode 100644
index 00000000..04d8e9c0
--- /dev/null
+++ b/Frontend/src/styles/pharmacysignin.module.css
@@ -0,0 +1,83 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100vh;
+ background-image: url("../assets/Background.svg");
+ background-size: cover;
+ background-position: center;
+}
+
+.signupSection {
+ width: 100%;
+ max-width: 400px;
+ background-color: #fff;
+ border-radius: 10px;
+ padding: 20px 30px 20px 30px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1;
+
+ > .headerNav {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ }
+ > form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ > input {
+ width: 100%;
+ padding: 10px;
+ border-radius: 4px;
+ border: 1px solid #110f0f;
+ font-size: 16px;
+ }
+ > .options {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ > label {
+ font-size: 16px;
+ color: #110f0f;
+ display: flex;
+ align-items: center;
+ > input[type="checkbox"] {
+ width: 14px;
+ cursor: pointer;
+ }
+ }
+ > .forgot {
+ text-decoration: none;
+ color: #110f0f;
+ }
+ }
+ > .signupbtn {
+ width: 100%;
+ padding: 7px;
+ border-radius: 4px;
+ border: none;
+ outline: none;
+ font-size: 16px;
+ background-color: #83c0b9;
+ color: white;
+ cursor: pointer;
+ margin-bottom: 5px;
+ &:hover {
+ background-color: #6da8a0;
+ }
+ }
+ }
+ > .redirectLink {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 5px;
+ > a {
+ text-decoration: none;
+ color: #83c0b9;
+ }
+ }
+}
diff --git a/Frontend/src/styles/pharmacysignup.css b/Frontend/src/styles/pharmacysignup.module.css
similarity index 74%
rename from Frontend/src/styles/pharmacysignup.css
rename to Frontend/src/styles/pharmacysignup.module.css
index f618b8e7..c7d69eb4 100644
--- a/Frontend/src/styles/pharmacysignup.css
+++ b/Frontend/src/styles/pharmacysignup.module.css
@@ -1,72 +1,67 @@
-
-
-.pharmacy-signup-container {
- position: relative;
- background-image: url("../assets/Background.svg");
- width: 100%;
- height: 150vh;
- margin: 0;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- z-index: -2;
-}
-
-
-.direction-header{
- position: absolute;
- top: 4em;
- display: flex;
- gap: 20rem;
- }
-
-/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
-/* form {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- width: 100%;
- max-width: 600px;
- margin-top: -250px;
- background: #f9fdfd;
- border-radius: 10px;
- padding: 20px;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- width: 50rem;
- height: 100vh;
- z-index: -1;
-} */
-
-/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
-/* input[type="text"],
-input[type="email"],
-input[type="password"] {
- width: 100%;
- padding: 10px 90px;
- margin: 10px 0;
- outline: none;
- border-radius: 4px;
- border: 2px solid #110f0f;
- font-size: 16px;
-} */
-
-/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
-/* button {
- width: 50px 60px;
- padding: 10px 150px;
- border-radius: 4px;
- border: 1px solid #0e0d0d;
- font-size: 16px;
- margin-top: 40px;
-} */
-
-.redirect-link {
- margin-top: -50px;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 10px;
-}
-
+.pharmacySignupContainer {
+ position: relative;
+ background-image: url("../assets/Background.svg");
+ width: 100%;
+ height: 100vh;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ z-index: -2;
+}
+
+.directionHeader {
+ top: 4em;
+ display: flex;
+ gap: 20rem;
+}
+
+/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
+form {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+ width: 100%;
+ max-width: 500px;
+ margin-top: -250px;
+ background: #f9fdfd;
+ border-radius: 10px;
+ padding: 20px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ z-index: -1;
+}
+
+/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
+input[type="text"],
+input[type="email"],
+input[type="password"],
+input[type="tel"],
+input[type="address"] {
+ width: 100%;
+ padding: 10px 90px;
+ outline: none;
+ border-radius: 4px;
+ border: 2px solid #110f0f;
+ font-size: 16px;
+}
+
+/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
+button {
+ width: 50px 60px;
+ padding: 10px 150px;
+ border-radius: 4px;
+ border: 1px solid #0e0d0d;
+ font-size: 16px;
+ margin-top: 40px;
+}
+
+.redirectLink {
+ margin-top: -50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+}
diff --git a/Frontend/src/styles/searchpage.css b/Frontend/src/styles/searchpage.css
index b6ba60b8..6ac4aacf 100644
--- a/Frontend/src/styles/searchpage.css
+++ b/Frontend/src/styles/searchpage.css
@@ -171,4 +171,7 @@ input[type="number"]::-webkit-inner-spin-button {
border-radius: 10px;
cursor: pointer;
font-size: 16px;
+ &:hover {
+ background-color: #399b90;
+ }
}
diff --git a/Frontend/src/styles/signup.module.css b/Frontend/src/styles/signup.module.css
index 92edd6ff..1059864f 100644
--- a/Frontend/src/styles/signup.module.css
+++ b/Frontend/src/styles/signup.module.css
@@ -296,8 +296,6 @@ button[type="submit"] {
}
.signupbtn {
- -webkit-margin-before: 1rem;
- margin-block-start: 1rem;
padding-block: 0.5rem;
border: 1px solid #338f85;
border-radius: 4px;
@@ -452,6 +450,11 @@ button[type="submit"] {
}
}
+.error {
+ color: #ff0000;
+ font-size: 12px;
+}
+
.btnbox {
display: flex;
flex-direction: row;
@@ -508,4 +511,4 @@ button[type="submit"] {
.profileheading {
text-align: center;
}
-}
+}
\ No newline at end of file
diff --git a/Frontend/src/styles/updatedcart.module.css b/Frontend/src/styles/updatedcart.module.css
index e4a4464f..c6a2a27e 100644
--- a/Frontend/src/styles/updatedcart.module.css
+++ b/Frontend/src/styles/updatedcart.module.css
@@ -26,7 +26,7 @@
margin-block: 20px;
}
-.shoppingCartBtn {
+.continueBtn {
background: #83c0b9;
height: 48px;
width: 160px;
@@ -37,7 +37,7 @@
cursor: pointer;
}
-.continueBtn {
+.backBtn {
background-color: #ffffff;
height: 48px;
width: 160px;
diff --git a/docker-compose.yml b/docker-compose.yml
index bdc261b0..5057c891 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,52 +1,52 @@
-services:
- curamap-frontend:
- container_name: curamap-frontend
- build: ./Frontend
- depends_on:
- - curamap-backend
- restart: "always"
- environment:
- - BACKEND_APP_API_URL=${BACKEND_APP_API_URL}
- ports:
- - 8000:80
- networks:
- - curamap-network
-
-
- curamap-backend:
- container_name: curamap-backend
- build: ./Backend
- depends_on:
- - curamap-db
- restart: "always"
- environment:
- - MONGO_URI=${MONGO_URI}
- ports:
- - 5000:5000
- networks:
- - curamap-network
-
-
- curamap-db:
- container_name: curamap-db
- image: mongo
- environment:
- - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
- - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
- - MONGO_INITDB_DATABASE=${MONGO_INITDB_DATABASE}
- ports:
- - ${MONGODB_EXTERNAL_PORT}:27017
- networks:
- - curamap-network
- volumes:
- - mongo-db:/data/db
-
-
-volumes:
- mongo-data:
-
-
-networks:
- curamap-network:
- name: curamap-network
- driver: bridge
+services:
+ curamap-frontend:
+ container_name: curamap-frontend
+ build: ./Frontend
+ depends_on:
+ - curamap-backend
+ restart: "always"
+ environment:
+ - BACKEND_APP_API_URL=${BACKEND_APP_API_URL}
+ ports:
+ - 8000:80
+ networks:
+ - curamap-network
+
+
+ curamap-backend:
+ container_name: curamap-backend
+ build: ./Backend
+ depends_on:
+ - curamap-db
+ restart: "always"
+ environment:
+ - MONGO_URI=${MONGO_URI}
+ ports:
+ - 5000:5000
+ networks:
+ - curamap-network
+
+
+ curamap-db:
+ container_name: curamap-db
+ image: mongo
+ environment:
+ - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
+ - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
+ - MONGO_INITDB_DATABASE=${MONGO_INITDB_DATABASE}
+ ports:
+ - ${MONGODB_EXTERNAL_PORT}:27017
+ networks:
+ - curamap-network
+ volumes:
+ - mongo-db:/data/db
+
+
+volumes:
+ mongo-data:
+
+
+networks:
+ curamap-network:
+ name: curamap-network
+ driver: bridge
\ No newline at end of file