diff --git a/.github/workflows/curamap.html b/.github/workflows/curamap.html
deleted file mode 100644
index e69de29b..00000000
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
deleted file mode 100644
index 45edf1b7..00000000
--- a/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,82 +0,0 @@
-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/DashboardComponents/RevenueChart.jsx b/Frontend/src/components/DashboardComponents/RevenueChart.jsx
index 95e55f5a..4dda20bc 100644
--- a/Frontend/src/components/DashboardComponents/RevenueChart.jsx
+++ b/Frontend/src/components/DashboardComponents/RevenueChart.jsx
@@ -2,7 +2,7 @@ import React from "react";
import { Line } from "react-chartjs-2";
import { Chart as ChartJS, defaults } from "chart.js/auto";
-import SourceData from "../data/sourceData.json";
+import SourceData from "../data/sourceData.json";
import styles from "../../styles/dashboard.module.css";
defaults.maintainAspectRatio = false;
@@ -19,6 +19,7 @@ const RevenueChart = () => {
data.label),
datasets: [
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}
{
Pay at Pharmacy
@@ -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 */}
Cancel Payment
- Confirm
+
+ Confirm{" "}
+
{/* Security Info */}
diff --git a/Frontend/src/components/forms/NewPharmarcySignUp.jsx b/Frontend/src/components/forms/NewPharmarcySignUp.jsx
new file mode 100644
index 00000000..f0778d43
--- /dev/null
+++ b/Frontend/src/components/forms/NewPharmarcySignUp.jsx
@@ -0,0 +1,185 @@
+import React, { useState } from "react";
+import styles from "../../styles/newpharmacysignup.module.css";
+import caretleft from "../../assets/CaretLeft.png";
+import cancelicon from "../../assets/X.png";
+import { useNavigate } from "react-router-dom";
+
+const InputField = ({ id, name, type, placeholder, value, onChange }) => (
+
+);
+
+const NewPharmarcySignUp = () => {
+ const navigate = useNavigate();
+
+ const handlePharmSignIn = () => {
+ navigate("/pharmacy-signin");
+ };
+
+ 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: "",
+ });
+ alert("Signup successful!");
+ navigate("/pharmacy-signin");
+ } catch (err) {
+ setError(err.message);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+
Create Account
+
+
+
+
+
Already have an account?
+ {/*
Log in */}
+
+ 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?
(
+
+);
+
const SignUp = () => {
const navigate = useNavigate();
@@ -11,15 +31,17 @@ const SignUp = () => {
year: "",
email: "",
password: "",
- otp: "",
+ confirmPassword: "",
fullName: "",
phoneNumber: "",
validId: "",
conditions: "",
});
- const [isCompleteVisible, setIsCompleteVisible] = useState(false); // State to toggle between sections
+ const [isCompleteVisible, setIsCompleteVisible] = useState(false);
const [error, setError] = useState("");
+ const [loading, setLoading] = useState(false);
+ const [invalidFields, setInvalidFields] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
@@ -27,36 +49,68 @@ const SignUp = () => {
...prev,
[name]: value,
}));
+
+ // Clear invalid field if it becomes valid
+ setInvalidFields((prev) => ({
+ ...prev,
+ [name]: value.trim() === "" ? true : false,
+ }));
};
const handleNext = () => {
- setIsCompleteVisible(true); // Show the .complete section
+ setIsCompleteVisible(true);
+ };
+ const handleSignin = () => {
+ navigate("/signin");
};
const handleBack = () => {
- setIsCompleteVisible(false); // Show the .signUp section
+ setIsCompleteVisible(false);
+ };
+
+ const validateFields = () => {
+ const newInvalidFields = {};
+ if (!formData.fullName.trim()) newInvalidFields.fullName = true;
+ if (!formData.phoneNumber.trim() || !/^\d{10}$/.test(formData.phoneNumber))
+ newInvalidFields.phoneNumber = true;
+ if (!formData.validId.trim()) newInvalidFields.validId = true;
+ if (!formData.conditions.trim()) newInvalidFields.conditions = true;
+ if (!formData.email.trim() || !/\S+@\S+\.\S+/.test(formData.email))
+ newInvalidFields.email = true;
+ if (formData.password !== formData.confirmPassword)
+ newInvalidFields.password = true;
+
+ setInvalidFields(newInvalidFields);
+ return Object.keys(newInvalidFields).length === 0;
};
const handleSubmit = async (e) => {
e.preventDefault();
setError("");
+ if (!validateFields()) {
+ setError("Please correct the highlighted fields.");
+ return;
+ }
+
+ setLoading(true);
+
const payload = {
dateOfBirth: `${formData.year}-${formData.month}-${formData.day}`,
email: formData.email,
password: formData.password,
- otp: formData.otp,
+ confirmPassword: formData.confirmPassword,
fullName: formData.fullName,
phoneNumber: formData.phoneNumber,
validId: formData.validId,
conditions: formData.conditions,
};
- console.log("Payload being sent:", payload);
-
try {
const response = await fetch(
- "https://new-cura.onrender.com/api/patients/signup",
+ // "https://new-cura.onrender.com/api/patients/signup",
+ `${import.meta.env.VITE_API_URL}/patients/signup`,
+
{
method: "POST",
headers: {
@@ -68,19 +122,18 @@ const SignUp = () => {
if (!response.ok) {
const errorData = await response.json();
- console.error("Error response from server:", errorData);
throw new Error(
errorData.message || "Failed to sign up. Please try again."
);
}
const data = await response.json();
- console.log("Signup successful:", data);
alert("Signup successful!");
- navigate("/findmeds");
+ navigate("/signin");
} catch (err) {
- console.error("Error details:", err);
setError(err.message || "An error occurred. Please try again.");
+ } finally {
+ setLoading(false);
}
};
@@ -99,21 +152,21 @@ const SignUp = () => {
When is your birthday?
-
Month
@@ -131,45 +184,49 @@ const SignUp = () => {
November
December
-
Your birthday won't be shown publicly.
-
-
-
+ {error && {error}
}
+
{
>
Next
- {error && {error}
}
+
+ Already have an account? Log In
+
{/* Complete Profile Section */}
+
- Finish
+ {loading ? "Submitting..." : "Finish"}
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/Dashboard.jsx b/Frontend/src/pages/Dashboard.jsx
index d54414f6..17efa951 100644
--- a/Frontend/src/pages/Dashboard.jsx
+++ b/Frontend/src/pages/Dashboard.jsx
@@ -18,12 +18,12 @@ const Dashboard = () => {
-
+
+
-
diff --git a/Frontend/src/pages/LandingPage.jsx b/Frontend/src/pages/LandingPage.jsx
index 011720a6..975105a5 100644
--- a/Frontend/src/pages/LandingPage.jsx
+++ b/Frontend/src/pages/LandingPage.jsx
@@ -31,7 +31,11 @@ const LandingPage = () => {
};
const handleMedication = () => {
- navigate("/findmeds");
+ navigate("/signin");
+ };
+
+ const handlePharmacy = () => {
+ navigate("/pharmacy-signup");
};
return (
@@ -43,24 +47,33 @@ const LandingPage = () => {
-
- Your Health Journey,
-
- Mapped In a click.
-
-
-
- We are here to make Healthcare simple and accessible,empowering you
-
- to prioritize your wellbeing without the hassle.
-
-
-
Sign Up
-
Sign In
+
+
+ Your Health Journey,
+
+ Mapped In a click.
+
+
+
+ We are here to make Healthcare simple and accessible,empowering
+ you
+
+ to prioritize your wellbeing without the hassle.
+
+
+
+
+ Sign Up
+
+
+ Sign In
+
+
+
+
+
-
-
Connecting Patients to Pharmacies For Easy Medication Access.
@@ -110,17 +123,19 @@ const LandingPage = () => {
Your Health Will Thank You
- order Easily, find Genuine Drug Instantly,Pay securely and Pick up
+ Order easily, find Genuine Drug Instantly,Pay securely and Pick up
With Confidence-experience ,Fast safe and Reliable Access to
Medication With Curamap
Browse Medications
-
+
+
+
-
How is curamap Different ?
+
How is curamap Different ?
@@ -204,7 +219,7 @@ const LandingPage = () => {
Wale
- curamap has completely Transformed how i managemy prescription.As
+ Curamap has completely Transformed how i managemy prescription.As
someone With a Hectic Schedule, The One-click Delivery Option is a
Game-Changer.My Meds Arrive Quickly
@@ -219,7 +234,7 @@ const LandingPage = () => {
- i Love How Curamap Makes Health care so easy. i no longer have to
+ I Love How Curamap Makes Health care so easy. i no longer have to
worry about long Pharmacy Ques or missing doses. The convenience
of irdering online and the speed of delivery are unmatched,
curamap has truly simplified my life.
@@ -285,7 +300,7 @@ const LandingPage = () => {
Transforming Nigerian Pharmaceutical
Healthcare Through Enhanced Pharmacy Fulfillment
-
Partner with us
+
Partner with us
@@ -308,7 +323,7 @@ const LandingPage = () => {
- Copyright 2025 BRIX Templates | All Rights Reserved
+ Copyright 2025 Curamap | All Rights Reserved
@@ -341,7 +356,9 @@ const LandingPage = () => {
Youtube
-
Terms And Conditions | Privacy Policy
+
+
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/dashboard.module.css b/Frontend/src/styles/dashboard.module.css
index 71c2d266..9c9a8b9b 100644
--- a/Frontend/src/styles/dashboard.module.css
+++ b/Frontend/src/styles/dashboard.module.css
@@ -34,7 +34,6 @@
align-items: center;
justify-content: start;
margin-bottom: 20px;
-
}
.sidebar .logo img {
@@ -219,12 +218,12 @@ input:checked + .slider:before {
/*Orders Table Style*/
.table {
- margin-top: 30px;
+ /* margin-top: 30px; */
background: transparent;
padding: 20px;
border-radius: 12px;
- width: 50%;
- height: 300px;
+ /* width: 50%; */
+ /* height: 300px; */
border: 1px solid #000;
}
@@ -232,7 +231,7 @@ input:checked + .slider:before {
width: 100%;
height: 100%;
display: flex;
- justify-content: center;
+ /* justify-content: center; */
align-items: center;
}
@@ -256,6 +255,8 @@ input:checked + .slider:before {
/*Revenue Chart Style*/
.revenue-chart {
+ width: 100%;
+ height: 100%;
margin-top: 30px;
background: white;
padding: 20px;
@@ -263,8 +264,10 @@ input:checked + .slider:before {
}
.revenueChart {
- width: 50%;
- height: 300px;
+ /* width: 50%; */
+ /* height: 300px; */
+ width: 100%;
+ height: 100%;
margin-top: 20px;
border-radius: 12px;
background: #83c0b9;
@@ -277,4 +280,20 @@ input:checked + .slider:before {
justify-content: center;
align-items: center;
margin-top: 20px;
-}
\ No newline at end of file
+}
+
+.middleSection {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 20px;
+ width: 100%;
+}
+.revenueChartLine {
+ width: 100%;
+ height: 100%;
+ margin-top: 20px;
+ border-radius: 12px;
+ background: #83c0b9;
+ padding: 10px 30px 20px 30px;
+}
diff --git a/Frontend/src/styles/landingpage.css b/Frontend/src/styles/landingpage.css
index 56ef69c8..05fecdcf 100644
--- a/Frontend/src/styles/landingpage.css
+++ b/Frontend/src/styles/landingpage.css
@@ -8,42 +8,55 @@
body {
font-family: "Roboto", sans-serif;
background: #f0f7ff;
- min-height: 100vh;
}
.landing-page-container {
display: flex;
flex-direction: column;
- gap: 7rem;
+ gap: 0rem;
+ width: 100%;
+ min-height: 100vh;
}
.Logo {
display: flex;
align-items: center;
justify-items: center;
- padding-left: 1.5rem;
padding-top: 1.5rem;
+ margin-left: 3em;
}
.Logo img:nth-child(1) {
- max-width: 100%;
height: 60px;
width: 60px;
}
.MainContent {
display: flex;
- align-items: center;
- justify-content: center;
height: 100%;
gap: 10rem;
+ width: 100%;
}
-
.TextContent {
display: flex;
+ justify-content: flex-start;
+}
+.my-text {
+ display: flex;
+ max-width: 60%;
+ width: 100%;
flex-direction: column;
- gap: 3rem;
- max-width: 600px;
+ align-items: center;
+ gap: 1em;
+ padding-left: 1em;
+ padding-right: 2em;
+ > p {
+ padding-inline-start: 2em;
+ }
+}
+.my-banner {
+ max-width: 40%;
+ width: 100%;
}
.TextContent h1 {
@@ -60,48 +73,54 @@ body {
line-height: 1.6;
}
-.Buttons {
+.buttons-container {
display: flex;
- gap: 1rem;
+ width: 100%;
}
-.Buttons button {
- padding: 0.5rem 2rem;
+.button-1 {
+ background-color: transparent;
+ height: 4em;
+ width: 10em;
+ text-wrap: nowrap;
+ color: #007e85;
+ border: none;
border-radius: 4px;
+ cursor: pointer;
font-size: 1rem;
font-weight: bold;
- cursor: pointer;
transition: all 0.2s;
}
-.Buttons button:first-child {
- background-color: transparent;
- 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;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 1rem;
+ font-weight: bold;
+ transition: all 0.2s;
}
-.Buttons button:last-child:hover {
+.button-2:hover {
color: #080808;
}
.MainContent img:nth-child(1) {
- max-width: 100%;
+ width: 100%;
height: auto;
- width: 100px;
- max-width: 100%;
}
+
.MainContent img:nth-child(2) {
- max-width: 550px;
+ margin-top: 1em;
width: 100%;
height: auto;
}
@@ -113,7 +132,7 @@ body {
font-size: 14px;
display: flex;
flex-direction: column;
- gap: 10em;
+ gap: 8em;
justify-content: flex-start;
border-top: 1px solid #080808;
border-bottom: 1px solid #080808;
@@ -139,10 +158,6 @@ body {
flex-direction: column;
}
-.second-level-content-p {
- font-size: 18px;
-}
-
.benefit-text-container p {
text-wrap: wrap;
}
@@ -161,7 +176,7 @@ body {
flex: 1;
}
.second-level-content-p {
- font-size: 1em;
+ font-size: 20px;
flex: 2;
width: 100%;
text-wrap: nowrap;
@@ -175,14 +190,68 @@ body {
.third-level-content {
display: flex;
- justify-content: space-between;
align-items: center;
- gap: 12em;
width: 100%;
- max-width: 90rem;
border-bottom: 1px solid #080808;
+ > .third-level-content-text {
+ max-width: 40%;
+ width: 100%;
+ padding-left: 20px;
+ }
+ > .third-level-content-image {
+ flex: 1;
+ }
+}
+
+.third-level-content-text {
+ display: flex;
+ width: 50em;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ font-size: 16px;
+ gap: 4em;
+ padding-left: 2em;
+}
+
+.third-level-content-text p {
+ text-wrap: wrap;
+}
+.third-level-content-text h2 {
+ font-size: 3rem;
+ color: #333;
+}
+
+.third-level-content-text button {
+ width: 9rem;
+ height: 4.5rem;
+ padding: 0.5em;
+ background: #007e85;
+ color: #f0f7ff;
+ border: none;
+ border-radius: 0.3em;
+}
+
+/* Fourth level content of Landing Page*/
+
+.fourth-level-content {
+ display: flex;
+ justify-content: flex-start;
+ gap: 2rem;
+ align-items: flex-start;
+ padding: 4rem;
+ flex-direction: column;
+ width: 100%;
}
+.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 {
+ text-wrap: nowrap;
+} */
.card-1-img-container {
position: absolute;
display: flex;
@@ -191,7 +260,7 @@ body {
border-radius: 3em;
top: 0.5em;
left: 1em;
- max-width: 100%;
+ width: 100%;
}
.card-container {
@@ -199,6 +268,7 @@ body {
justify-content: center;
align-items: center;
gap: 2em;
+ width: 100%;
}
.card {
position: relative;
@@ -230,52 +300,6 @@ body {
margin-top: 15rem;
}
-.third-level-content-text {
- display: flex;
- width: 50em;
- flex-direction: column;
- justify-content: center;
- align-items: flex-start;
- font-size: 16px;
- gap: 5em;
- padding-left: 2em;
-}
-
-.third-level-content-text p {
- text-wrap: wrap;
-}
-.third-level-content-text h2 {
- font-size: 2.1rem;
- color: #333;
-}
-
-.third-level-content-text button {
- width: 9rem;
- height: 4.5rem;
- padding: 0.5em;
- background: #007e85;
- color: #f0f7ff;
- border: none;
- border-radius: 0.3em;
-}
-
-/* Fourth level content of Landing Page*/
-
-.fourth-level-content {
- display: flex;
- justify-content: flex-start;
- gap: 2rem;
- align-items: flex-start;
- padding: 4rem;
- flex-direction: column;
-}
-
-/* BEFORE YOU UNCOMMENT THIS CODE MAKE SURE YOU GIVE IT A CLASS SO IT STOPS AFFECTING OTHER PEOPLE'S CODE */
-/* .name-pre h4,
-p {
- text-wrap: nowrap;
-} */
-
.card-3 {
display: flex;
flex-direction: column;
@@ -325,13 +349,22 @@ p {
.fifth-level-content {
display: flex;
flex-direction: column;
+ margin-bottom: 4em;
+ width: 100%;
}
+.fifth-level-content h2 {
+ font-size: 1.6em;
+ margin-left: 2em;
+ margin-bottom: 4em;
+}
.fifth-card-container {
display: flex;
- justify-content: center;
+ justify-content: space-between;
align-items: center;
gap: 3em;
+ width: 100%;
+ padding-inline: 2em;
}
.testimonial-card {
@@ -339,60 +372,45 @@ p {
position: relative;
display: flex;
flex-direction: column;
- justify-content: center;
align-items: center;
width: 24rem;
height: 20rem;
border-radius: 1em;
- padding: 10rem;
- padding-left: 5em;
- max-width: 500px;
+
font-size: 14px;
overflow: hidden;
}
-.testimonial-card p {
- width: 300px;
- height: 300px;
-}
.profile {
display: flex;
text-align: left;
align-items: center;
- justify-content: center;
- margin-left: -7em;
+
+ width: 100%;
gap: 2em;
}
.card-5 {
width: 26rem;
- height: 26rem;
-}
-
-.card-4 {
- padding-top: 9em;
- padding-left: 6em;
-}
-
-.card-5 {
- padding-top: 4.5em;
+ height: 25rem;
}
.image-container {
width: 150px;
}
.testimonial-card p {
- text-wrap: wrap;
-}
-
-.card-6 {
- padding-top: 13.5em;
- padding-left: 6.5em;
+ text-wrap: normal;
+ padding-left: 5px;
}
.card-6 p {
margin-bottom: 4em;
}
+
+.colorbuttons-container {
+ margin: 0 auto;
+ margin-top: 4em;
+}
/* sixth levl content*/
.sixth-level-content {
@@ -504,8 +522,9 @@ p {
.eight-level-content {
display: flex;
gap: 5em;
- padding-top: 3em;
- padding-bottom: 3em;
+ padding-top: 2em;
+ padding-bottom: 2em;
+ margin-top: 1em;
justify-content: center;
align-items: center;
border-top: 1px solid #080808;
@@ -515,13 +534,19 @@ p {
.column {
display: flex;
flex-direction: column;
- gap: 1.2em;
+ gap: 1em;
+ padding-inline: 0;
}
.column ul {
display: flex;
flex-direction: column;
- gap: 1.2em;
+ gap: 1em;
list-style-type: none;
+ padding-inline: 0;
+}
+
+.Terms-container {
+ margin-top: 12em;
}
/* Responsive Design */
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/signin.module.css b/Frontend/src/styles/signin.module.css
index a80a3f59..4ab9d461 100644
--- a/Frontend/src/styles/signin.module.css
+++ b/Frontend/src/styles/signin.module.css
@@ -1,5 +1,3 @@
-/* sign in css section */
-
.container {
max-width: 1280px;
margin: 0 auto;
@@ -22,10 +20,10 @@
padding: 3rem;
border-radius: 10px;
max-width: 484px;
- width: 80%;
+ width: 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
position: relative;
- min-height: 544px;
+ /* min-height: 544px; */
}
.backButton {
@@ -115,7 +113,8 @@
}
.signupText a {
- color: #83c0b9;
+ color: #338f85;
+ font-weight: bold;
text-decoration: none;
cursor: pointer;
}
diff --git a/Frontend/src/styles/signup.module.css b/Frontend/src/styles/signup.module.css
index 92edd6ff..5e8e5eda 100644
--- a/Frontend/src/styles/signup.module.css
+++ b/Frontend/src/styles/signup.module.css
@@ -1,5 +1,4 @@
.signupwrapper {
- max-width: 1280px;
margin: 0 auto;
width: 100%;
min-height: 100vh;
@@ -66,6 +65,15 @@ form {
display: flex;
flex-direction: column;
gap: 1rem;
+ > .login {
+ text-align: center;
+
+ > a {
+ color: #338f85;
+ cursor: pointer;
+ font-weight: 500;
+ }
+ }
}
fieldset {
@@ -296,8 +304,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 +458,11 @@ button[type="submit"] {
}
}
+.error {
+ color: #ff0000;
+ font-size: 12px;
+}
+
.btnbox {
display: flex;
flex-direction: row;
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
deleted file mode 100644
index bdc261b0..00000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-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