### Install dependencies Source: https://github.com/bannergress/website/blob/main/README.md Run this command to install all required project dependencies. ```bash npm i ``` -------------------------------- ### Start the application Source: https://github.com/bannergress/website/blob/main/README.md Run this command to start the development server after configuring the .env file. ```bash npm run start ``` -------------------------------- ### Core API Client Usage Source: https://context7.com/bannergress/website/llms.txt Demonstrates how to use the centralized Api class for various HTTP requests (GET, POST, PUT, DELETE) with automatic token refresh and internationalization headers. Use this for general backend communication. ```typescript import { api } from './api' // GET request with query parameters const response = await api.get>('bnrs', { orderBy: 'created', orderDirection: 'DESC', limit: 10, online: true }) if (response.ok) { console.log('Banners:', response.data) } else { console.error('Request failed with status:', response.status) } // POST request with JSON body const newBanner = await api.post('bnrs', { title: 'My Banner', description: 'A custom banner', missions: { 0: mission1, 1: mission2 }, width: 6, type: 'sequential' }) // PUT request for updates const updated = await api.put('bnrs/banner-id', { title: 'Updated Title' }) // DELETE request const deleted = await api.delete('bnrs/banner-id') ``` -------------------------------- ### GET /bnrs Source: https://context7.com/bannergress/website/llms.txt Retrieves a list of banners based on provided query parameters for filtering and pagination. ```APIDOC ## GET /bnrs ### Description Retrieves a list of banners with support for ordering, limiting, and online status filtering. ### Method GET ### Endpoint /bnrs ### Parameters #### Query Parameters - **orderBy** (string) - Optional - Field to sort by (e.g., 'created') - **orderDirection** (string) - Optional - Sort direction ('ASC' or 'DESC') - **limit** (number) - Optional - Maximum number of results - **online** (boolean) - Optional - Filter by online status ### Response #### Success Response (200) - **data** (Array) - List of banner objects ``` -------------------------------- ### Configure Keycloak Authentication Source: https://context7.com/bannergress/website/llms.txt Sets up Keycloak client initialization and the React provider. Requires environment variables for realm, URL, and client ID. ```typescript // keycloak.ts import Keycloak from 'keycloak-js' const keycloakConfig = { realm: import.meta.env.VITE_KEYCLOAK_REALM, url: import.meta.env.VITE_KEYCLOAK_URL, clientId: import.meta.env.VITE_KEYCLOAK_CLIENT_ID, } const keycloak = new Keycloak(keycloakConfig) export default keycloak // App.tsx - Provider setup import { ReactKeycloakProvider } from '@react-keycloak/web' import keycloak from './keycloak' import { updateApiState } from './api' const App: React.FC = () => ( e === 'onReady' && updateApiState()} > {/* App content */} ) // Environment variables (.env) VITE_API_BASE_URL=https://api.bannergress.com VITE_KEYCLOAK_REALM=bannergress VITE_KEYCLOAK_URL=https://auth.bannergress.com/auth/ VITE_KEYCLOAK_CLIENT_ID=bannergress-frontend ``` -------------------------------- ### POST /bnrs Source: https://context7.com/bannergress/website/llms.txt Creates a new banner on the platform. ```APIDOC ## POST /bnrs ### Description Creates a new custom banner by providing title, description, missions, and layout configuration. ### Method POST ### Endpoint /bnrs ### Request Body - **title** (string) - Required - Banner title - **description** (string) - Optional - Banner description - **missions** (Object) - Required - Dictionary of missions - **width** (number) - Optional - Banner width - **type** (string) - Optional - 'sequential' or 'anyOrder' ### Response #### Success Response (200) - **banner** (Banner) - The created banner object ``` -------------------------------- ### Display Legacy Browser Notice Source: https://github.com/bannergress/website/blob/main/index.html Checks for Promise support and displays a legacy browser warning element if unavailable. ```javascript function showLegacyNotice(){ elem = document.getElementById('legacy_browser'); if(elem) elem.style.display = 'block'; } if(!window.Promise){ setTimeout(showLegacyNotice, 500) } ``` -------------------------------- ### Define Redux Store State and Selectors Source: https://context7.com/bannergress/website/llms.txt Defines the root state interface and demonstrates how to use useSelector to retrieve banner data from the store. ```typescript // storeTypes.ts import { BannerState } from './features/banner/types' import { PlaceState } from './features/place/types' import { MissionState } from './features/mission/types' import { NewsState } from './features/news/types' import { SettingsState } from './features/settings/types' interface RootState { banner: BannerState place: PlaceState mission: MissionState news: NewsState settings: SettingsState } // BannerState structure interface BannerState { banners: Array fullBanners: Array recentBanners: Array browsedBanners: Array searchBanners: Array agentBanners: Array userBannerListBanners: Array mapBanners: Array canBrowseMore: Boolean canSearchMore: Boolean hasMoreAgentBanners: Boolean hasMoreUserBannerListBanners: Boolean createdBanner: Banner | undefined } // SettingsState structure interface SettingsState { defaultOrderBy: BannerOrder defaultOrderDirection: BannerOrderDirection defaultOnline: boolean | undefined defaultProximityLatitude: number | undefined defaultProximityLongitude: number | undefined } // Selectors usage import { useSelector } from 'react-redux' import { getBanner, getRecentBanners } from './features/banner/selectors' const MyComponent: React.FC = () => { const recentBanners = useSelector(getRecentBanners) const specificBanner = useSelector(state => getBanner(state, 'banner-id')) } ``` -------------------------------- ### Extract Banner Titles and Numbering Source: https://context7.com/bannergress/website/llms.txt Demonstrates simple and advanced extraction of mission titles and numbering patterns using the TitleExtractor utility. ```typescript import { extract, titleAndNumberingExtraction, TitleExtractor } from './features/banner/naming' // Simple extraction from mission titles const missions = [ { title: 'City Tour 1/6 - Start' }, { title: 'City Tour 2/6 - Center' }, { title: 'City Tour 3/6 - End' } ] const result = extract(missions.map(m => m.title)) // result.title = 'City Tour' // result.results[0].totalMarker.parsed = 6 // Advanced extraction with TitleExtractor const extractor = new TitleExtractor() extractor.fill(missions) const advancedResult = titleAndNumberingExtraction(missions, extractor) // advancedResult.title = 'City Tour' // advancedResult.total = 6 // advancedResult.results = [{ mission, index: 1 }, { mission, index: 2 }, ...] // Supported numbering formats: // - Arabic numerals: "1", "01", "1/6", "(1)" // - Roman numerals: "I", "II", "III", "IV" // - NATO phonetic: "Alpha", "Bravo", "Charlie" // - Latin letters with base-6: "A1", "A2", "B1" ``` -------------------------------- ### Define Application Routes Source: https://context7.com/bannergress/website/llms.txt Configures React Router with public and protected routes. Uses PrivateRoute for restricted access paths. ```tsx import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom' import { PrivateRoute } from './components/login/private-route' const AppRoutes: React.FC = () => ( {/* Public routes */} {/* Protected routes */} {/* Fallback */} ) // Keyboard shortcut // Shift+N: Navigate to /new-banner ``` -------------------------------- ### User API Functions Source: https://context7.com/bannergress/website/llms.txt Functions for managing user authentication and Ingress agent identity verification. ```APIDOC ## User API Functions ### Description Handles user session management and the verification process for Ingress agents. ### Methods - getUser() - claimUser(agentName) - abortClaimUser() - unlinkUser() ### Response - **User** (object) - Contains agent details (name, faction) and verification status. ``` -------------------------------- ### Search Missions for Banners Source: https://context7.com/bannergress/website/llms.txt Query available missions by location or search string to include in banner creation. ```typescript import { searchMissions, PAGE_SIZE } from './features/mission/api' // Search for missions by query const filter: MissionFilter = { orderBy: 'title', orderDirection: 'ASC' } const missions = await searchMissions( null, // location (optional) 'City Tour', // search query filter, 0 // page number ) // Mission interface interface Mission { id: string title: string picture: string steps?: Array description?: string type?: 'hidden' | 'anyOrder' | 'sequential' status?: 'submitted' | 'published' | 'disabled' author?: { name: string, faction: 'enlightened' | 'resistance' } } interface Step { poi?: POI objective?: 'hack' | 'captureOrUpgrade' | 'createLink' | 'createField' | 'installMod' | 'takePhoto' | 'viewWaypoint' | 'enterPassphrase' | 'hidden' } ``` -------------------------------- ### Mission Search API Source: https://context7.com/bannergress/website/llms.txt Functions for searching and retrieving mission data for banner creation. ```APIDOC ## Mission Search API ### Description Allows searching for missions based on location and query strings. ### Methods - searchMissions(location, query, filter, page) ### Response - **Mission** (object) - Contains id, title, picture, steps, description, type, status, and author information. ``` -------------------------------- ### Banner Redux Actions Source: https://context7.com/bannergress/website/llms.txt Redux thunk actions for managing banner state, including loading, searching, creating, and submitting banners. ```APIDOC ## Redux Actions for Banners ### Description Provides methods to interact with the application state for banner management, including loading banners from various sources (recent, search, map) and performing CRUD-like operations. ### Methods - loadBannerAction(id) - loadRecentBannersAction() - loadBrowsedBannersAction(placeId, filter, page) - loadSearchBannersAction(query, filter, page) - loadMapBannersAction(minLat, minLon, maxLat, maxLon, filter) - createBannerAction(bannerData) - submitBannerAction() - deleteBannerAction(id) - changeBannerSettingsAction(banner, settings) ``` -------------------------------- ### Implement BannersMap Component Source: https://context7.com/bannergress/website/llms.txt Integrates an interactive Leaflet map for banner visualization. Requires handling map bounds changes and banner selection state. ```tsx import BannersMap from './components/banners-map' import { Banner } from './features/banner' const MapPage: React.FC = () => { const [banners, setBanners] = useState([]) const [selectedBannerId, setSelectedBannerId] = useState() const [loading, setLoading] = useState(false) const handleMapChanged = (bounds: LatLngBounds) => { // Load banners within new map bounds setLoading(true) loadMapBanners( bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest(), filter ).then(response => { setBanners(response.data) setLoading(false) }) } const handleSelectBanner = (banner: Banner) => { setSelectedBannerId( selectedBannerId === banner.id ? undefined : banner.id ) } return ( ) } // URL parameters supported: // ?lat=52.52&lng=13.41&zoom=10 - Center and zoom // ?bounds=52.50,13.38,52.52,13.41 - Initial bounds ``` -------------------------------- ### Implement BannerCard Component Source: https://context7.com/bannergress/website/llms.txt Displays individual banner details in a card format. Includes support for status indicators and navigation links. ```tsx import BannerCard from './components/banner-card' import { Banner } from './features/banner' const BannerListItem: React.FC<{ banner: Banner }> = ({ banner }) => { return ( ) } // BannerCard displays: // - Banner title // - Banner picture (mosaic of mission icons) // - Number of missions (with offline/missing warnings) // - Distance/length // - Start location with link to browse page // - Details link ``` -------------------------------- ### Place API Functions Source: https://context7.com/bannergress/website/llms.txt Functions for retrieving geographic data, including countries, administrative areas, and searching for specific places. ```APIDOC ## Place API Functions ### Description Retrieves geographic information to facilitate browsing banners by location. ### Methods - getCountries() - getAdministrativeAreas(countryId) - getPlace(placeId) - searchPlaces(query, page) ### Response - **Place** (object) - Contains id, formattedAddress, longName, shortName, numberOfBanners, and boundary coordinates. ``` -------------------------------- ### Manage User Authentication and Identity Source: https://context7.com/bannergress/website/llms.txt API functions for retrieving current user state and verifying Ingress agent identities. ```typescript import { getUser, claimUser, unlinkUser, abortClaimUser } from './features/user/api' // Get current authenticated user const user = await getUser() // Returns: { agent: { name: 'AgentName', faction: 'enlightened' }, verificationAgent: '...', verificationMessage: '...' } // Claim/verify an Ingress agent identity const claimed = await claimUser('AgentName') // Abort pending verification await abortClaimUser() // Unlink agent from account await unlinkUser() // User interface interface User { agent?: { name: string faction: 'enlightened' | 'resistance' } verificationAgent?: string verificationMessage?: string } ``` -------------------------------- ### Banner API Functions Source: https://context7.com/bannergress/website/llms.txt Provides functions for fetching, searching, creating, and managing banners, including filtering and pagination. Use these specific functions for banner-related operations. ```typescript import { getBanner, getRecentBanners, getBanners, searchBanners, listAgentBanners, postBanner, updateBanner, deleteBanner, searchMapBanners, changeBannerSettings } from './features/banner/api' // Fetch a single banner by ID const banner = await getBanner('abc123') // Get recent banners for homepage const recentBanners = await getRecentBanners(12) // Browse banners by place with filtering const filter: BannerFilter = { orderBy: 'created', orderDirection: 'DESC', online: true, onlyOfficialMissions: false } const banners = await getBanners('place-id', filter, 0) // page 0 // Search banners by text const searchResults = await searchBanners('Berlin', filter, 0) // List banners by agent/author const agentBanners = await listAgentBanners('AgentName', filter, 0) // Search banners within map bounds const mapBanners = await searchMapBanners( 52.52, // topRightLat 13.41, // topRightLng 52.50, // bottomLeftLat 13.38, // bottomLeftLng filter ) // Create a new banner const newBanner = await postBanner({ title: 'City Tour Banner', description: 'Explore the city center', missions: { 0: mission1, 1: mission2, 2: mission3 }, numberOfMissions: 3, width: 6, type: 'sequential' }) // Update banner settings (add to todo/done list) await changeBannerSettings(banner, { listType: 'todo' }) ``` -------------------------------- ### Mission Interface Source: https://context7.com/bannergress/website/llms.txt Defines the structure for a Mission object, including its ID, title, picture, steps, and author information. Essential for representing individual missions within a banner. ```typescript interface Mission { id: string title: string picture: string steps?: Array description?: string startLatitude?: number startLongitude?: number type?: 'hidden' | 'anyOrder' | 'sequential' status?: 'submitted' | 'published' | 'disabled' author?: NamedAgent averageDurationMilliseconds?: number lengthMeters?: number } ``` -------------------------------- ### Banner Interface Source: https://context7.com/bannergress/website/llms.txt Defines the structure for a Banner object, including its ID, title, description, mission details, and various status flags. Used for type checking and data manipulation. ```typescript interface Banner { id: string requestedId?: string title: string description?: string numberOfMissions: number numberOfSubmittedMissions: number numberOfDisabledMissions: number startLatitude: number startLongitude: number lengthMeters?: number formattedAddress?: string picture?: string missions?: NumDictionary type?: 'sequential' | 'anyOrder' listType?: 'todo' | 'done' | 'blacklist' | 'none' width?: number averageDurationMilliseconds?: number startPlaceId?: string owner?: Boolean warning?: string plannedOfflineDate?: string eventStartDate?: string eventEndDate?: string } ``` -------------------------------- ### BannerFilter Interface Source: https://context7.com/bannergress/website/llms.txt Defines the structure for filtering banner searches, including sorting options, online status, and proximity parameters. Use this to customize banner retrieval. ```typescript interface BannerFilter { orderBy: 'relevance' | 'listAdded' | 'created' | 'lengthMeters' | 'title' | 'numberOfMissions' | 'proximityStartPoint' orderDirection: 'ASC' | 'DESC' online: boolean | undefined onlyOfficialMissions?: boolean minEventTimestamp?: string maxEventTimestamp?: string proximityLatitude?: number proximityLongitude?: number } ``` -------------------------------- ### Retrieve Geographic Place Data Source: https://context7.com/bannergress/website/llms.txt Functions for fetching countries, administrative areas, and specific place details to support location-based banner browsing. ```typescript import { getCountries, getAdministrativeAreas, getPlace, searchPlaces } from './features/place/api' // Get all countries with banners const countries = await getCountries() // Returns: [{ id: 'DE', longName: 'Germany', numberOfBanners: 12, type: 'country', ... }] // Get administrative areas within a country const regions = await getAdministrativeAreas('DE') // Returns: [{ id: 'BY', longName: 'Bavaria', parentPlaceId: 'DE', type: 'administrative_area_level_1', ... }] // Get a specific place by ID const place = await getPlace('BY') // Search places by name const searchResults = await searchPlaces('Berlin', 0) // page 0 // Place interface interface Place { id: string formattedAddress: string longName: string shortName: string numberOfBanners: number boundaryMinLatitude: number boundaryMinLongitude: number boundaryMaxLatitude: number boundaryMaxLongitude: number parentPlace?: Place parentPlaceId?: string type?: 'country' | 'administrative_area_level_1' | 'administrative_area_level_2' | 'locality' } ``` -------------------------------- ### PUT /bnrs/:id Source: https://context7.com/bannergress/website/llms.txt Updates an existing banner's information. ```APIDOC ## PUT /bnrs/:id ### Description Updates specific fields of an existing banner identified by its ID. ### Method PUT ### Endpoint /bnrs/:id ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the banner ### Request Body - **title** (string) - Optional - New title for the banner ``` -------------------------------- ### Dispatch Redux Banner Actions Source: https://context7.com/bannergress/website/llms.txt Utilize Redux thunk actions to load, search, create, and manage banner state within React components. ```typescript import { useDispatch } from 'react-redux' import { loadBannerAction, loadRecentBannersAction, loadBrowsedBannersAction, loadSearchBannersAction, loadAgentBannersAction, loadMapBannersAction, createBannerAction, submitBannerAction, deleteBannerAction, changeBannerSettingsAction } from './features/banner/actions' // In a React component const dispatch = useDispatch() // Load a specific banner dispatch(loadBannerAction('banner-id')) // Load recent banners for homepage dispatch(loadRecentBannersAction()) // Browse banners by place with pagination const filter = { orderBy: 'created', orderDirection: 'DESC', online: true } dispatch(loadBrowsedBannersAction('place-id', filter, 0)) // Search banners dispatch(loadSearchBannersAction('Munich', filter, 0)) // Load banners for map view dispatch(loadMapBannersAction(52.52, 13.41, 52.50, 13.38, filter)) // Create banner preview dispatch(createBannerAction({ title: 'New Banner', missions: { 0: mission1 }, width: 6, type: 'sequential' })) // Submit banner to server const bannerId = await dispatch(submitBannerAction()) // Add banner to todo list dispatch(changeBannerSettingsAction(banner, { listType: 'todo' })) ``` -------------------------------- ### DELETE /bnrs/:id Source: https://context7.com/bannergress/website/llms.txt Deletes a banner from the platform. ```APIDOC ## DELETE /bnrs/:id ### Description Removes a banner from the system. ### Method DELETE ### Endpoint /bnrs/:id ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the banner to delete ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.