Neptune Beer Club

A 4-day challenge for the web agency Lumy. I developed a web application to find bars in Brest 🍺, France. The criteria are based, among other things, on deployment, filtering system, and originality.

TYPEChallenge, Web
DATE
STACKVite, React, TypeScript, Tailwind CSS, React Map GL
Neptune Beer Club project

The problem

The solution

  1. Single Page Application (SPA) with the React, Vite and Tailwind library.
  2. Configuration: Vite, Vitest, Prettier, EsLint, TypeScript
  3. File organization: Screaming architecture with a features/bar folder
  4. Deployment: GitHub Actions

Screaming architecture

I tried to implement these features:

└── src/
	├── assets/
    ├── features/
    │   ├── bars/
    │   │   ├── index.js (public API)
	│   │   ├── api/index.ts
    │   │   ├── bar-map/
    │   │   ├── bar-form/
    │   │   └── bar-list/
    │   │       ├── index.js (public API)
    │   │       ├── bar-item.component.js
    │   │       ├── bar-list.component.js
    │   │       ├── bar-list.context.js
    │   │       ├── bar-list.test.js
    │   │       └── use-bar-list.js
    │   ├── users/ (new features, not yet)
    │   │   ├── index.js
    │   │   ├── login/
    │   │   ├── signup/
    │   │   └── use-auth.js
	│	├── ui/ (common, shared components)
    │   ├── index.js
    │   ├── components/
    │   ├── containers/ : header, footer, navbar, ...
    │   └── layouts/
    └── pages/
        └── home.tsx

Public API (index.js)

export * from './bar-list';
export * from './bar-map';
export * from './bar-filters';
export * from './bar-context';

Home.tsx

import { Header } from '@containers/Header';
import { BarList, BarMap, BarFilters, BarProvider } from '@features/bar';
import { MapProvider } from 'react-map-gl';

export const Home = () => {
  return (
    <BarProvider>
      <MapProvider>
        <div className="grid grid-cols-[1fr_2fr]">
          <div className="flex h-screen flex-col">
            <Header />
            <BarFilters />
            <BarList />
          </div>
          <div>
            <BarMap />
          </div>
        </div>
      </MapProvider>
    </BarProvider>
  );
};

React Map GL

<Map
  id="barmap"
  initialViewState={{
    longitude: -4.4852,
    latitude: 48.3891,
    zoom: 14,
  }}
  mapStyle="mapbox://styles/mapbox/dark-v9"
  mapboxAccessToken={MAPBOX_TOKEN}
  interactiveLayerIds={[clusterLayer.id as string]}
  ref={mapRef}
  onClick={onClick}
>
  {geojsonData ? (
    <Source
      id="brest-bars"
      type="geojson"
      data={geojsonData}
      cluster={true}
      clusterMaxZoom={14}
      clusterRadius={50}
    >
      <Layer {...clusterLayer} />
      <Layer {...clusterCountLayer} />
      <Layer {...unclusteredPointLayer} />
    </Source>
  ) : null}
  <BarMapMarkers bars={filteredBars} />
</Map>

What I Learned

Future Plans

The goal is to develop the “Neptune Beer Club” application, giving a charismatic and legendary identity to bars in Brest.

  1. Enhanced User Interaction: Implementing a search feature, providing directions, and enabling location sharing for a more interactive experience.
  2. Technical Optimization: Utilizing API Directus for efficient data management, deploying with Docker, and incorporating animations for improved technical aspects.
  3. Creative Branding and Promotion: Establishing a unique brand identity, promoting local bars and beers, and adding thematic elements for a creative touch.
  4. Innovative Features: Exploring the integration of an AI bot, experimenting with 3D effects, and providing inclusivity information for a modern and innovative application.
  5. Diverse User Scenarios: Offering users a choice between traditional (Couple, Brewer/Connoisseur, Friends, Business) and original scenarios involving a dog, a robot, or envisioning the future.