Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_KEY=your_api_key_here
VITE_API_BASE_URL=https://api.thecatapi.com/v1
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Dependencies
/node_modules
/.pnp
.pnp.js

# Testing
/coverage

# Production
/build
/dist

# Misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.docs
154 changes: 141 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,149 @@
# GlobalWebIndex Engineering Challenge
# Cat Lovers App

## Exercise: CatLover
A modern React application for cat enthusiasts, built with React, TypeScript, and Tailwind CSS. The app integrates with TheCatAPI to provide a delightful experience for exploring and saving your favorite cat images.

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.
## Features

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.
The application consists of three main views:

The **third** view allows you do the following things:
1. **Random Cats**: Displays a grid of random cat images with a "Load More" button. Clicking on any image opens a modal with detailed information and options to mark as favorite.

- Display your favourite cats
- Remove an image from your favourites (use any UX option you like)
2. **Breeds**: Shows a list of cat breeds. Clicking on a breed opens a modal with details about that breed and related images.

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.
3. **Favorites**: Displays all the cat images you've marked as favorites, with the option to remove them from your collection.

## UI Design

The UI is designed following the Tailwind UI blocks style, featuring:

- Clean, modern interface with consistent spacing and typography
- Responsive design that works well on mobile, tablet, and desktop
- Interactive components with hover and focus states
- Accessible UI elements with proper ARIA attributes

## Tech Stack

- **React**: Frontend library for building user interfaces
- **TypeScript**: For type safety and better developer experience
- **Tailwind CSS**: Utility-first CSS framework for styling
- **React Query**: For data fetching, caching, and state management
- **React Router**: For handling navigation and routing
- **Headless UI**: For accessible UI components
- **Heroicons**: For beautiful, consistent icons
- **Zustand**: For local state management
- **Axios**: For API requests

## SEO Optimization

The application is optimized for search engines with:

- Semantic HTML structure
- Meta tags for each page
- JSON-LD structured data following schema.org standards
- Canonical URLs
- Open Graph meta tags for social sharing

## Project Structure

The project follows a modular architecture with clear separation of concerns:

```
src/
├── api/ # API services and client configuration
├── components/ # Reusable UI components
├── hooks/ # Custom React hooks
├── layouts/ # Layout components
├── pages/ # Page components
├── store/ # Zustand store definitions
├── types/ # TypeScript type definitions
└── utils/ # Utility functions
```

## Component Library

The application includes a comprehensive set of reusable UI components:

- **Button**: Versatile button component with various styles, sizes, and states
- **Card**: Flexible card component for displaying content in a structured format
- **Modal**: Accessible modal dialog for displaying detailed information
- **Loading**: Various loading indicators for different contexts
- **Error**: Error message components for different scenarios

## Setup

### Prerequisites

- Node.js (v14 or later)
- npm or yarn

### Installation

1. Clone the repository
2. Install dependencies:
```
npm install
```
or
```
yarn
```

### Environment Variables

This project uses environment variables to store sensitive information like API keys. To set up the environment variables:

1. Copy the `.env.example` file to a new file named `.env`
2. Replace the placeholder values with your actual API keys

```
VITE_API_KEY=your_api_key_here
VITE_API_BASE_URL=https://api.thecatapi.com/v1
```

You can obtain an API key from [TheCatAPI](https://developers.thecatapi.com/).

### Running the Application

To start the development server:

```
npm run dev
```

or

```
yarn dev
```

The application will be available at `http://localhost:5173` (or another port if 5173 is in use).

### Building for Production

To build the application for production:

```
npm run build
```

or

```
yarn build
```

This will create a `dist` directory with optimized production build.

To preview the production build locally:

```
npm run preview
```

or

```
yarn preview
```

## Submission

Once you have built your app, share your code in the mean suits you best
Good luck, potential colleague!
23 changes: 23 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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 { globalIgnores } from 'eslint/config'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
53 changes: 53 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Cat Lovers App - Browse random cat images, explore cat breeds, and save your favorites." />
<meta name="keywords" content="cats, cat breeds, cat images, cat lovers, pet, animals" />
<meta name="author" content="Cat Lovers App" />
<meta name="robots" content="index, follow" />

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://cat-lovers-app.example.com/" />
<meta property="og:title" content="Cat Lovers App" />
<meta property="og:description" content="Browse random cat images, explore cat breeds, and save your favorites." />
<meta property="og:image" content="/cat-lovers-app-preview.jpg" />

<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://cat-lovers-app.example.com/" />
<meta property="twitter:title" content="Cat Lovers App" />
<meta property="twitter:description" content="Browse random cat images, explore cat breeds, and save your favorites." />
<meta property="twitter:image" content="/cat-lovers-app-preview.jpg" />

<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<title>Cat Lovers App</title>

<!-- Structured Data for Google -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "Cat Lovers App",
"description": "A mobile-first React application for cat lovers to browse random cat images, explore cat breeds, and save favorites.",
"applicationCategory": "Entertainment",
"operatingSystem": "Web",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"author": {
"@type": "Organization",
"name": "Cat Lovers App"
}
}
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading