Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7fc8dbb
initial commit with some basic configuration including service-worker…
JABER-AHMED Jan 30, 2024
e080230
beer single page - with map, basic design and make favourite
JABER-AHMED Jan 30, 2024
668d65a
home page favourite list with single and multi remove also with basic…
JABER-AHMED Jan 30, 2024
93ba39f
feature/beerListpage - pagination, filter, sort
JABER-AHMED Jan 30, 2024
2ebde4d
feature/perPage - add the perPage dynamically by dropdown
JABER-AHMED Jan 30, 2024
01107c5
Create Documentation.md
JABER-AHMED Jan 30, 2024
0a6bdd6
Create README.md
JABER-AHMED Jan 30, 2024
028f836
Update Documentation.md
JABER-AHMED Jan 30, 2024
6ca4469
Update Documentation.md
JABER-AHMED Jan 30, 2024
0020336
modify service-worker
JABER-AHMED Jan 30, 2024
10139ab
Merge branch 'main' of https://github.com/JABER-AHMED/BeerApp---Senior
JABER-AHMED Jan 30, 2024
a57cc13
modified home.tsx and home utils
JABER-AHMED Jan 30, 2024
309bd71
modified the beerList with the metadata api call and dropdown modific…
JABER-AHMED Jan 30, 2024
218f57d
remove consoles and modify offline index
JABER-AHMED Jan 30, 2024
31d732f
added the app name
JABER-AHMED Jan 30, 2024
5e39178
modified the design of beerDetails page
JABER-AHMED Jan 30, 2024
b87f409
refector some codes and tryting to write some of the tests
JABER-AHMED Jan 30, 2024
414c883
fixed the type filter issue
JABER-AHMED Jan 30, 2024
ddfac3f
modify test for home and beer
JABER-AHMED Jan 30, 2024
64fd539
fix map market issue
JABER-AHMED Jan 31, 2024
0c0c086
refectoring the code and solved some issues
JABER-AHMED Jan 31, 2024
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
14 changes: 14 additions & 0 deletions BeerApp - Senior/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
moduleDirectories: ['node_modules', 'src'],
collectCoverage: true,
collectCoverageFrom: ['src/**/*.ts', 'src/**/*.tsx'],
coverageReporters: ['json-summary', 'text', 'lcov'],
extensionsToTreatAsEsm: ['.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};
1,023 changes: 778 additions & 245 deletions BeerApp - Senior/package-lock.json

Large diffs are not rendered by default.

15 changes: 12 additions & 3 deletions BeerApp - Senior/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,37 @@
"@fontsource/roboto": "^4.5.8",
"@mui/icons-material": "^5.11.16",
"@mui/material": "^5.13.0",
"@popperjs/core": "^2.11.8",
"axios": "^1.4.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-leaflet": "^4.2.1",
"react-router-dom": "^6.11.1"
},
"devDependencies": {
"@babel/preset-typescript": "^7.23.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/leaflet": "^1.9.8",
"@types/node": "^16.18.28",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"jest": "^27.4.7",
"react-scripts": "5.0.1",
"react-test-renderer": "^18.0.0",
"ts-jest": "^27.0.7",
"typescript": "^4.9.5",
"typescript-plugin-css-modules": "^5.0.1"
"typescript-plugin-css-modules": "^5.0.1",
"workbox-webpack-plugin": "^7.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\""
},
"eslintConfig": {
"extends": [
Expand Down
Binary file added BeerApp - Senior/public/images/marker-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions BeerApp - Senior/public/service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// public/service-worker.js
const CACHE_NAME = 'beer-app-cache';
self.addEventListener('install', (event) => {
const urlsToCache = [
'/',
'/index.html',
// Add other URLs you want to cache...
];

event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(urlsToCache);
})
);
});

self.addEventListener('fetch', (event) => {
event.respondWith(
// Try to fetch the request from the network
fetch(event.request).then((response) => {
// If the fetch is successful, clone the response and cache it
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, clone);
});
}
return response;
}).catch(() => {
// If the fetch fails (e.g., when offline), try to respond with the cached version
return caches.match(event.request).then((cachedResponse) => {
return cachedResponse || new Response('', { status: 404, statusText: 'Not Found' });
});
})
);
});

4 changes: 3 additions & 1 deletion BeerApp - Senior/src/api/beer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const getBeer = (id: string) => axios.get(`${API}breweries/${id}`);

const getBeerList = (params?: ApiParams) => axios.get(`${API}breweries/`, { params });

const getFavouriteListByIds = (by_ids: string) => axios.get(`${API}breweries`, { params: { by_ids } });

/**
* @param size Int between 1 and 50. Default is 3.
* @returns New promise with api call for random beer list.
Expand All @@ -22,4 +24,4 @@ const searchBeerList = (query: string, isAutoComplete = false) =>

const getBeerMetaData = (params?: ApiParams) => axios.get(`${API}breweries/meta`, { params });

export { getBeer, getBeerList, getRandomBeerList, searchBeerList, getBeerMetaData };
export { getBeer, getBeerList, getRandomBeerList, searchBeerList, getBeerMetaData, getFavouriteListByIds };
22 changes: 22 additions & 0 deletions BeerApp - Senior/src/components/Map/Map.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { useRef } from "react";
import { MapContainer, TileLayer } from "react-leaflet";
import "leaflet/dist/leaflet.css";

const Map = ({lat, lang}) => {
const mapRef = useRef(null);
const latitude = lat;
const longitude = lang;

return (
// Make sure you set the height and width of the map container otherwise the map won't show
<MapContainer center={[latitude, longitude]} zoom={13} ref={mapRef} style={{height: "100vh", width: "100vw"}}>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{/* Additional map layers or components can be added here */}
</MapContainer>
);
};

export default Map;
2 changes: 1 addition & 1 deletion BeerApp - Senior/src/components/TopBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const TopBar = (props: Props) => {
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap component="div">
V
BeerWiki
</Typography>
</Toolbar>
</AppBar>
Expand Down
15 changes: 9 additions & 6 deletions BeerApp - Senior/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider } from '@emotion/react';
import { theme } from './styles/theme';
import './styles/global.css';
import { registerServiceWorker } from './registerServiceWorker';

registerServiceWorker();

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<CssBaseline />
<ThemeProvider theme={theme}>
<Router />
</ThemeProvider>
</React.StrictMode>
<React.StrictMode>
<CssBaseline />
<ThemeProvider theme={theme}>
<Router />
</ThemeProvider>
</React.StrictMode>
);
15 changes: 15 additions & 0 deletions BeerApp - Senior/src/registerServiceWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// registerServiceWorker.js or registerServiceWorker.ts

export const registerServiceWorker = () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/service-worker.js')
.then((registration) => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch((error) => {
console.error('Service Worker registration failed:', error);
});
}
};

1 change: 1 addition & 0 deletions BeerApp - Senior/src/setupTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
14 changes: 14 additions & 0 deletions BeerApp - Senior/src/utils/favoritesUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const saveAsFavourite = (id: string, setFavourite: React.Dispatch<React.SetStateAction<string[]>>) => {
const favouriteList = JSON.parse(localStorage.getItem('favouriteList') || '[]');
if (favouriteList.indexOf(id) === -1) {
favouriteList.push(id);
localStorage.setItem('favouriteList', JSON.stringify(favouriteList));
setFavourite(favouriteList);
} else {
favouriteList.splice(favouriteList.indexOf(id), 1);
localStorage.setItem('favouriteList', JSON.stringify(favouriteList));
setFavourite(favouriteList);
}
};

export default saveAsFavourite;
21 changes: 21 additions & 0 deletions BeerApp - Senior/src/views/Beer/Beer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root {
margin: 'auto';
padding: '20px'
}
.title {
font-weight: 'bold';
font-size: '3rem';
margin-top: '10px';
}
.subtitle {
font-size: '2rem';
margin-bottom: '10px';
}
.subheading {
font-size: '1.75rem';
margin-top: '20px';
}
.cardContent {
display: 'flex';
padding: 1.5rem;
}
39 changes: 39 additions & 0 deletions BeerApp - Senior/src/views/Beer/Map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "leaflet/dist/leaflet.css";
import React, { useRef } from "react";
import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";

import L from "leaflet";

const customIcon = L.icon({
iconUrl: `${window.location.origin}/images/marker-icon.png`,
iconSize: [25, 30],
});

interface MapProps {
lat: number;
lang: number;
name: string;
}

const Map: React.FC<MapProps> = ({ lat, lang, name }) => {
const mapRef = useRef(null);
const latitude = lat;
const longitude = lang;
const companyName = name;

return (
<MapContainer center={[latitude, longitude]} zoom={15} ref={mapRef} style={{height: "70vh", width: "70vw"}}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<Marker position={[latitude, longitude]} icon={customIcon}>
<Popup>
{companyName}
</Popup>
</Marker>
</MapContainer>
);
};

export default Map;
79 changes: 79 additions & 0 deletions BeerApp - Senior/src/views/Beer/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Beer.test.js

import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import Beer from "./index";

const beer = {
id: "5128df48-79fc-4f0f-8b52-d06be54d0cec",
name: "(405) Brewing Co",
brewery_type: "micro",
address_1: "1716 Topeka St",
address_2: null,
address_3: null,
city: "Norman",
state_province: "Oklahoma",
postal_code: "73069-8224",
country: "United States",
longitude: "-97.46818222",
latitude: "35.25738891",
phone: "4058160490",
website_url: "http://www.405brewing.com",
state: "Oklahoma",
street: "1716 Topeka St",
};

jest.mock("./utils", () => ({
fetchData: (setData: (data: typeof beer) => void) => {
setData(beer);
},
}));

describe("Beer", () => {
beforeEach(() => {
// Mock route param
const mockBear = {
...beer
};

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useParams: () => ({
id: mockBear.id,
}),
}));
});

afterEach(() => {
jest.restoreAllMocks();
});

it("displays beer details", async () => {
render(
<BrowserRouter>
<Beer />
</BrowserRouter>
);

// Check name
expect(
await screen.findByRole("heading", { name: beer.name })
).toBeInTheDocument();

// Check type
expect(screen.getByText(`Type: ${beer.brewery_type}`)).toBeInTheDocument();

// Check website
expect(
screen.getByRole("link", { name: beer.website_url })
).toBeInTheDocument();

// Check phone
expect(screen.getByText(beer.phone)).toBeInTheDocument();

// Check coordinates
expect(
screen.getByText(`Coordinate: ${beer.latitude}, ${beer.longitude}`)
).toBeInTheDocument();
});
});
Loading