Online pharmacy platform — a customer storefront for ordering medicine and a vendor dashboard for running the store.
E-Pharmacy is a web platform for ordering medicine from online pharmacies. It covers both sides of the assignment in one application: customers browse pharmacies and a medicine catalog, read product details and reviews, fill a cart and place an order; the pharmacy vendor signs in to a private dashboard with statistics, orders, products, suppliers and customer data.
Authentication and every data collection run on Firebase (Authentication + Cloud Firestore). Filtering and pagination are resolved server-side by Firestore queries, not in the browser.
Built as a course project for the GoIT Frontend Development program, following the Figma mockup supplied with the technical specification.
| Storefront | e-pharmacy-murex.vercel.app |
| Vendor panel | /admin/login |
| Repository | github.com/kutluhangil/E-Pharmacy |
| Design | Figma mockup |
| Spec | docs/superpowers/specs |
- Register / Login — react-hook-form + yup validation (name, email pattern, phone, 6+ character password); registration signs the user in immediately, backend errors surface as a toast.
- Home — promo banner, three offer banners (70% / 100% / 35%) wired to the catalog and the feature block, six randomly drawn nearby pharmacies, the "add your pharmacy" section with the platform's five capabilities, and customer testimonials pulled from Firestore.
- Medicine store — the full pharmacy list with address, phone, star rating, an OPEN / CLOSE indicator and a "Visit Store" action.
- Medicine — a category dropdown, a name search and a Filter button; a 12-per-page product grid with "Add to cart" and "Details"; pagination appears once the result set exceeds one page, and an empty result renders "Nothing was found for your request". An anonymous visitor who tries to add to the cart is offered registration or login in a modal.
- Product — image, name, brand, price, rating, a quantity stepper and "Add to cart", plus a tab container switching between the description and paginated user reviews.
- Cart — shipping details form, Cash On Delivery / Bank payment choice, editable quantities, per-item removal, order total and "Place order", which writes the order to Firestore.
- Login — email/password form validated with yup; only an account carrying the
vendorrole can enter, and everything else is redirected away. - Dashboard — product / supplier / customer counters, a recent-customers table and an income/expenses panel.
- All orders — user info, address, products, order date, price and status, filtered by user name.
- All products — filter by product name, "Add a new product" modal, plus edit and delete modals; newest products first, across the nine assignment categories.
- All suppliers — filter by name, add and edit modals including an MUI X date picker for the delivery date, with an Active / Deactive status badge.
- Customers data — user info, email, address, phone and register date, with pagination.
- Responsive layout — fluid from 320px, responsive from 375px, tablet from 768px, desktop from 1440px; the storefront collapses to a slide-in burger menu and the dashboard sidebar becomes a bottom icon bar.
- Session persistence — the Firebase session is restored before private routes resolve; the cart survives a reload through redux-persist.
- Error handling — failures are never swallowed; the Firebase code and message reach the user as an actionable toast or inline error.
| Layer | Choice |
|---|---|
| Build tool | Vite |
| UI library | React 19 + TypeScript |
| Routing | React Router 7 (lazy pages, private routes) |
| State management | Redux Toolkit + React-Redux + redux-persist |
| Backend | Firebase Authentication + Cloud Firestore |
| Forms & validation | React Hook Form + Yup |
| Date input | MUI X Date Pickers + Day.js |
| Notifications | React Hot Toast |
| Styling | CSS Modules, design tokens, self-hosted Inter font, SVG icon sprite |
| Deployment | Vercel |
There is no custom server: Firebase Authentication handles accounts and Cloud Firestore
stores every collection. Reads and writes are constrained by the security rules in
firestore.rules — the catalog is public, back-office collections require the
vendor role, and a customer may only create an order for themselves.
users uid, name, email, role (customer | vendor), phone
stores name, street, city, phone, isOpen, rating
products name, brand, category, price, stock, photo, description,
rating, suppliers, discount, createdAt
reviews productId (null for testimonials), author, avatar, text, rating
customers name, email, address, phone, photo, registerDate, spent
suppliers name, address, company, deliveryDate, amount, status
orders userId, user info, address, products[], orderDate, price, status
transactions type (income | expense | error), title, email, amount, date
Searching is served by a lowercased nameLower field queried as a prefix range, and page size is
applied by Firestore itself; the composite indexes those queries need are declared in
firestore.indexes.json.
| Path | Access | Page |
|---|---|---|
/home |
public | Home |
/medicine-store |
public | Medicine store |
/medicine |
private | Medicine catalog |
/product/:productId |
public | Product |
/cart |
private | Cart |
/login · /register |
public | Customer authentication |
/admin/login |
public | Vendor authentication |
/dashboard |
vendor | Statistics |
/orders |
vendor | All orders |
/products |
vendor | All products |
/suppliers |
vendor | All suppliers |
/customers |
vendor | Customers data |
* |
public | Not found |
Requires Node.js 20 or newer and a Firebase project with Email/Password authentication and Cloud Firestore enabled.
npm install # install dependencies
cp .env.example .env # fill in the Firebase web config
npm run dev # start the dev server on http://localhost:5173
npm run build # type-check and build into dist/
npm run preview # preview the production build
npm run lint # lint the source with oxlint
npm run format # format the source with Prettier
npm run seed # populate Firestore with the demo datasetnpm run seed writes the demo pharmacies, products, reviews, customers, suppliers, orders and
transactions, and creates the vendor account used by the dashboard. It authenticates with a service
account key when FIREBASE_SERVICE_ACCOUNT is set, and otherwise falls back to
gcloud auth application-default login.
src/
├── app/ route guards, session bootstrap
├── features/ auth, cart, products, stores, admin building blocks
├── layouts/ client layout (header/footer/menu), admin layout (header/sidebar)
├── pages/ one folder per route — component + CSS module
├── services/ Firebase app, auth and Firestore access
├── shared/ design-system components and helpers
├── store/ Redux Toolkit slices, hooks and selectors
├── styles/ design tokens and global styles
└── types/ domain models
scripts/ Firestore seed script
Kutluhan Gil GitHub
Built as part of the GoIT Frontend Development program.
MIT Licensed — see LICENSE