Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3259c45
Initial commit
StefanosSt Sep 23, 2025
e50f58c
Setup scss and basic styles, integrate Redux and React Query to project
StefanosSt Sep 23, 2025
39cab49
Setup Router to project
StefanosSt Sep 23, 2025
1aa4899
Introduce Header and icons component
StefanosSt Sep 23, 2025
cf3347f
Build useClickOutside and useEscapeKey hooks as utility for Dropdown,…
StefanosSt Sep 23, 2025
7d4fe14
Introduce Footer and main content base styling
StefanosSt Sep 23, 2025
bcfcfe4
Add the 404 page
StefanosSt Sep 23, 2025
7de6bc5
Introduce PageHeading for all pages and maintain the content in redux
StefanosSt Sep 23, 2025
351ceef
Add dummy data to render the catList page
StefanosSt Sep 23, 2025
2b73fd7
Add BreedCard for Breeds page
StefanosSt Sep 23, 2025
f22797e
Introduce helper functions and hooks to handle React Queries
StefanosSt Sep 23, 2025
1e36c67
Introduce endpoint for breeds
StefanosSt Sep 23, 2025
56cbb52
Add Skeletons for the CatCards and BreedCards
StefanosSt Sep 23, 2025
121d3b7
Implement favorites functionality with API integration and UI updates
StefanosSt Sep 23, 2025
8c3bc0c
Add Toast component and global toast functionality; integrate Progres…
StefanosSt Sep 23, 2025
6bb0d7b
Add modal functionality with cat info and detailed about the breed.
StefanosSt Sep 23, 2025
a2ae1a1
Add fetchCatById API function and open Modal if cat_id exists in url
StefanosSt Sep 23, 2025
6b2ade9
Implement modal functionality on favorites page
StefanosSt Sep 23, 2025
725486d
Implement modal functionality on breeds page
StefanosSt Sep 23, 2025
93e6d89
Allow users to see Breeds and cat on the same modal with nav
StefanosSt Sep 24, 2025
adab37c
Handle modal State to clear data on Close
StefanosSt Sep 24, 2025
69d898c
Fix: ui optimizations across the app
StefanosSt Sep 24, 2025
65d7d11
Save favorites length to Redux to improve UI
StefanosSt Sep 24, 2025
ddbe9b8
Setup Vitest and create some tests for some files
StefanosSt Sep 24, 2025
4c43a9d
Update README.md and project name
StefanosSt Sep 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_URL=https://api.thecatapi.com/v1/
VITE_API_KEY=live_7X4kYGgl0fqjcR3gRpHrL2XsLXdcFyeGFzreeXYRcGTxTMEMHLAbkYTpVbuZFg37
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
114 changes: 101 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,109 @@
# GlobalWebIndex Engineering Challenge
# 🐾 Meowbase – Stefanos Stamoulis

## Exercise: CatLover
A responsive, modern React application that fetches and displays cat images and breed data from **TheCatAPI**.
Built with a cutting-edge React 19 + Vite toolchain, the project demonstrates **state management, caching, routing, accessibility, and testing practices**.

Create a React application for cat lovers which is going to build upon thecatapi.com and will have 3 views.
The **first** view displays a list of 10 random cat images and a button to load more. Clicking on any of those images opens a modal view with the image and the information about the cat’s breed if available. This would be a link to the second view below - the breed detail. The modal should also contain a form to mark the image as your favourite (a part of the third view as well). Make sure you can copy-paste the URL of the modal and send it to your friends - they should see the same image as you can see.
---

The **second** view displays a list of cat breeds. Each breed opens a modal again with a list of cat images of that breed. Each of those images must be a link to the image detail from the previous point.
## ✨ Demo
[Live Demo](https://meowbase.pages.dev/)

The **third** view allows you do the following things:
---

- Display your favourite cats
- Remove an image from your favourites (use any UX option you like)
## 🚀 Tech Stack
This project is built with a modern frontend toolchain, optimized for **performance, developer experience, and scalability**:

You can find the API documentation here: https://developers.thecatapi.com/
We give you a lot of freedom in technologies and ways of doing things. We only insist on you using React.js. Get creative as much as you want, we WILL appreciate it. You will not be evaluated based on how well you follow these instructions, but based on how sensible your solution will be. In case you are not able to implement something you would normally implement for time reasons, make it clear with a comment.
- **React 19** – UI foundation
- **Vite 7** – Lightning-fast dev/build tooling
- **TypeScript 5** – Type safety & DX
- **React Router v7** – Client-side routing
- **Redux Toolkit** – State management made simple
- **TanStack React Query v5** – Data fetching, caching & syncing
- **React Content Loader** – Skeleton loaders during fetches
- **React to Print** – Export/print support
- **Sass** – Styling with flexibility and modularity

## Submission
---

Once you have built your app, share your code in the mean suits you best
Good luck, potential colleague!
## ⚙️ Getting Started

### Prerequisites
- Node.js v18+
- npm

### Setup

# Clone the repo
```
git clone https://github.com/StefanosSt/Meowbase.git
cd meowbase
```

# Install dependencies
```
npm install
```
# Start development
```
npm run dev
```
---

## 📁 Project Structure

```
src/
├── api/ # API clients and endpoints (TheCatAPI integration)
├── assets/ # includes images & icons
├── components/ # Reusable UI components
├── hooks/ # Custom React hooks
├── pages/ # Route-based pages
├── routes/ # Route endpoints setup
├── store/ # Redux store setup
├── styles/ # Global Sass styles
├── types/ # Shared TypeScript types
```

---

## 🧹 Code Quality & Formatting
Consistency and maintainability are enforced via:

- **ESLint** – Static code analysis
- **Prettier** – Consistent formatting
- **TypeScript ESLint plugin** – Advanced type linting

---

## ♿ Accessibility (a11y)

- Semantic markup for screen readers
- Keyboard-friendly navigation
- Skeleton loaders to improve perceived performance

---

## 🎨 Styling & Theming

- Built with Sass for modular, maintainable styling
- Structure allows for easy integration of light/dark modes in the future

---

## 🚧 Improvements & Future Work

- Add integration/E2E tests (Cypress or Playwright)
- Centralize Modal logic in order to share functionality across the app
- Internationalization (i18n) for multilingual support
- Improvements on A11y

## 📚 Summary

### Meowbase showcases:

- Modern frontend stack (React 19 + Vite + TypeScript)
- Scalable architecture (Redux Toolkit + React Query)
- Testing setup for reliability
- Clean, extensible project structure

🐱 Built with ❤️ for cat lovers and developers alike.
25 changes: 25 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import { defineConfig, globalIgnores } from 'eslint/config';

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
prettier,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
]);
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/meowbase.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MeowBase | </title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading