Skip to content

Commit

Permalink
Merge pull request #21 from paulbtw/feature/MCB-8_add-footer-and-debug
Browse files Browse the repository at this point in the history
Feature/mcb 8 add footer and debug
  • Loading branch information
paulbtw authored Sep 22, 2023
2 parents 5f7a260 + ec599f6 commit b37aa69
Show file tree
Hide file tree
Showing 23 changed files with 6,707 additions and 123 deletions.
96 changes: 48 additions & 48 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
name: Tests CI
# name: Tests CI

on: [push, pull_request]
# on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- name: Run tests
run: npm run test:ci
env:
BASIC_TOKEN_EU: ${{ secrets.BASIC_TOKEN_EU }}
BASIC_TOKEN_EL: ${{ secrets.BASIC_TOKEN_EL }}
BASIC_TOKEN_US: ${{ secrets.BASIC_TOKEN_US }}
BASIC_TOKEN_AP: ${{ secrets.BASIC_TOKEN_AP }}
- name: Tests ✅
if: ${{ success() }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
--data '{
"context": "tests",
"state": "success",
"description": "Tests passed",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}'
# jobs:
# test:
# runs-on: ubuntu-latest
# strategy:
# matrix:
# node-version: [16.x]
# steps:
# - uses: actions/checkout@v2
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v1
# with:
# node-version: ${{ matrix.node-version }}
# - run: npm install
# - name: Run tests
# run: npm run test:ci
# env:
# BASIC_TOKEN_EU: ${{ secrets.BASIC_TOKEN_EU }}
# BASIC_TOKEN_EL: ${{ secrets.BASIC_TOKEN_EL }}
# BASIC_TOKEN_US: ${{ secrets.BASIC_TOKEN_US }}
# BASIC_TOKEN_AP: ${{ secrets.BASIC_TOKEN_AP }}
# - name: Tests ✅
# if: ${{ success() }}
# run: |
# curl --request POST \
# --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
# --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
# --header 'content-type: application/json' \
# --data '{
# "context": "tests",
# "state": "success",
# "description": "Tests passed",
# "target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# }'

- name: Tests 🚨
if: ${{ failure() }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
--data '{
"context": "tests",
"state": "failure",
"description": "Tests failed",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}'
# - name: Tests 🚨
# if: ${{ failure() }}
# run: |
# curl --request POST \
# --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
# --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
# --header 'content-type: application/json' \
# --data '{
# "context": "tests",
# "state": "failure",
# "description": "Tests failed",
# "target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# }'
5 changes: 4 additions & 1 deletion frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "next/core-web-vitals"
"extends": "next/core-web-vitals",
"rules": {
"react/display-name": "off"
}
}
5 changes: 4 additions & 1 deletion frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ const nextConfig = {
},
};

module.exports = nextConfig;
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer(nextConfig);
6 changes: 5 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
"scripts": {
"dev": "next dev",
"build": "next build",
"build:analyze": "ANALYZE=true yarn build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@floating-ui/dom": "^1.5.3",
"@floating-ui/react": "^0.25.4",
"@next/bundle-analyzer": "^13.5.2",
"@types/node": "20.6.0",
"@types/react": "18.2.21",
"@types/react-dom": "18.2.7",
"@vercel/analytics": "^1.0.2",
"autoprefixer": "10.4.15",
"axios": "^1.5.0",
"clsx": "^2.0.0",
Expand All @@ -28,6 +31,7 @@
"react-map-gl": "^7.1.6",
"react-query": "^3.39.3",
"tailwindcss": "3.3.3",
"typescript": "5.2.2"
"typescript": "5.2.2",
"usehooks-ts": "^2.9.1"
}
}
13 changes: 9 additions & 4 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import clsx from 'clsx'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import { type PropsWithChildren } from 'react'
import { Analytics } from '@vercel/analytics/react'
import { Footer } from '@/components/Footer'

const inter = Inter({ subsets: ['latin'] })

Expand Down Expand Up @@ -34,13 +36,16 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: PropsWithChildren) {
return (
<html lang="en">
<ReactQueryProvider>
<body className={clsx('bg-slate-100', inter.className)}>
<body className={clsx('bg-slate-100', inter.className)}>
<ReactQueryProvider>
<main className="container mx-auto px-4 sm:px-6 lg:px-8">
{children}
<Footer />
</main>
</body>
</ReactQueryProvider>
</ReactQueryProvider>

<Analytics />
</body>
</html>
)
}
6 changes: 3 additions & 3 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Map } from '@/components/Map'
import { Stats } from '@/components/Stats'
import { MapContainer } from '@/components/Map/Container'

export default function Home() {
return (
<div className="w-full box-border">
<Stats />
<div className="w-full h-[70vh] rounded-xl overflow-hidden shadow">
<Map />
<div className="w-full h-[70vh]">
<MapContainer />
</div>
</div>
)
Expand Down
24 changes: 22 additions & 2 deletions frontend/src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import { type PropsWithChildren } from 'react'

function ListItem({ href, children }: PropsWithChildren<{ href: string }>) {
return (
<li>
<a href={href} className="hover:underline ml-4 md:ml-6 text-end" rel="noreferrer noopener" target="_blank">
{children}
</a>
</li>
)
}

export function Footer() {
return (
<footer>
asd
<footer className="my-4">
<div className="w-full mx-auto container py-4 md:flex md:items-center md:justify-between">
<span className="text-sm text-gray-500 sm:text-center">
This site is no way affiliated with McD&apos;s
</span>
<ul className="flex flex-wrap items-center mt-3 text-sm font-medium text-gray-500 sm:mt-0">
<ListItem href="https://github.com/paulbtw/mcbrokenio" >Sourcecode</ListItem>
<ListItem href="https://mcbroken.com">Inspired by McBroken.com</ListItem>
</ul>
</div>
</footer>
)
}
66 changes: 66 additions & 0 deletions frontend/src/components/Map/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client'

import { useLocation } from '@/hooks/queries/useLocation'
import { useMcData } from '@/hooks/queries/useMcData'
import { Map } from '@/components/Map'
import { useCallback, useEffect, useRef, useState } from 'react'
import { type MapRef } from 'react-map-gl'
import { useDebounce } from 'usehooks-ts'
import { List } from '@/components/Map/List'

export interface ViewState {
latitude: number
longitude: number
zoom: number
}

export function MapContainer() {
const mapRef = useRef<MapRef>(null)
const { data: geoJson, isLoading: isLoadingGeoJson } = useMcData()
const { data: location, isLoading: isLoadingLocation } = useLocation()
const [viewState, setViewState] = useState<ViewState>({
latitude: 0,
longitude: 0,
zoom: 10
})
const debouncedViewState = useDebounce(viewState, 300)
const isLoading = isLoadingGeoJson || isLoadingLocation

useEffect(() => {
setViewState({
latitude: location?.lat ?? 52.5119151,
longitude: location?.lon ?? 13.3668864,
zoom: 10
})
}, [location])

const onClick = useCallback((lat: number, lon: number) => {
if (mapRef.current == null) {
return
}

mapRef.current.panTo({ lat, lon })
}, [])

return (
<div className="flex h-full gap-4">
<div className="grow h-full rounded-xl shadow bg-white overflow-hidden">
{isLoading && <div className="w-full h-full bg-slate-300" />}
{!isLoading && (
<Map
geoJson={geoJson}
setViewState={setViewState}
viewState={viewState}
ref={mapRef}
/>
)}
</div>
<List
isLoading={isLoading}
viewState={debouncedViewState}
geoJson={geoJson}
onClick={onClick}
/>
</div>
)
}
64 changes: 64 additions & 0 deletions frontend/src/components/Map/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { type ViewState } from '@/components/Map/Container'
import { type McDataGeometry } from '@/hooks/queries/useMcData'
import clsx from 'clsx'
import { useMemo } from 'react'

interface ListProps {
isLoading: boolean
geoJson?: McDataGeometry
viewState: ViewState
onClick?: (lat: number, lon: number) => void
}

const colorMap: Record<string, string> = {
GREY: 'bg-gray-500',
GREEN: 'bg-green-500',
YELLOW: 'bg-yellow-500'
}

export function List({ isLoading, geoJson, viewState, onClick }: ListProps) {
const sortedByDistance = useMemo(() => {
if (geoJson == null || isLoading) {
return []
}

return geoJson.features
.map((feature) => {
const [lon, lat] = feature.geometry.coordinates
const distance = Math.sqrt(
Math.pow(lon - viewState.longitude, 2) +
Math.pow(lat - viewState.latitude, 2)
)

return {
...feature,
distance
}
})
.sort((a, b) => a.distance - b.distance)
.slice(0, 25)
}, [
geoJson,
isLoading,
viewState.latitude,
viewState.longitude
])

return (
<div className="basis-80 rounded-xl shadow h-full bg-white overflow-y-auto hidden lg:block">
{sortedByDistance.map((feature) => {
const colorClassName = colorMap[feature.properties.dot]
return (
<div key={feature.properties.id} onClick={() => { onClick?.(feature.geometry.coordinates[1], feature.geometry.coordinates[0]) }} className="px-3 py-4 flex gap-4 border-b border-slate-300 items-center last:border-0 cursor-pointer hover:bg-slate-100">
<div className={clsx('w-4 h-4 rounded-full shrink-0', colorClassName)} />
<div>
<div className="text-xs font-semibold line-clamp-2">
{feature.properties.name}
</div>
</div>
</div>
)
})}
</div>
)
}
6 changes: 6 additions & 0 deletions frontend/src/components/Map/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type McDataProperties } from '@/hooks/queries/useMcData'
import { ItemStatus } from '@/types'
import clsx from 'clsx'
import { formatDistance } from 'date-fns'
import { useSettings } from '@/hooks/useSettings'

const colorMap = {
[ItemStatus.AVAILABLE]: 'bg-green-500',
Expand Down Expand Up @@ -43,6 +44,7 @@ function Item({
}

export function Popover({
id,
name,
hasMcFlurry,
hasMcSundae,
Expand All @@ -56,6 +58,8 @@ export function Popover({
milkshakeErrorCount,
customItems
}: McDataProperties) {
const [{ debugMode }] = useSettings()

return (
<div className="bg-white rounded overflow-hidden">
<h3 className="text-lg font-semibold mb-1">{name}</h3>
Expand Down Expand Up @@ -96,6 +100,8 @@ export function Popover({
})
: 'never'}
</div>
{debugMode === true && (<div>{id}</div>)}

</div>
)
}
Loading

0 comments on commit b37aa69

Please sign in to comment.