feat: use drink api in front and more (#16)
All checks were successful
Build Docker Image Front / run (push) Successful in 28s
Build Docker Image Back / run (push) Successful in 27s

Reviewed-on: #16
Co-authored-by: Clement <c.boesmier@aptatio.com>
Co-committed-by: Clement <c.boesmier@aptatio.com>
This commit is contained in:
Clement 2024-06-07 19:09:57 +02:00 committed by Clement
parent 2cb2166093
commit 3cb5a30270
36 changed files with 882 additions and 132 deletions

View File

@ -1,5 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */ /** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = { module.exports = {
testPathIgnorePatterns: [
"<rootDir>/dist/"
],
testTimeout: 10000, testTimeout: 10000,
preset: 'ts-jest', preset: 'ts-jest',
testEnvironment: 'node', testEnvironment: 'node',

View File

@ -8,6 +8,7 @@
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/node": "^20.12.7", "@types/node": "^20.12.7",
"axios": "^1.6.8", "axios": "^1.6.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
@ -15,6 +16,7 @@
"swagger-ui-express": "^5.0.0" "swagger-ui-express": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/cors": "^2.8.17",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/rewire": "^2.5.30", "@types/rewire": "^2.5.30",
"@types/supertest": "^6.0.2", "@types/supertest": "^6.0.2",
@ -1968,6 +1970,15 @@
"integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
"dev": true "dev": true
}, },
"node_modules/@types/cors": {
"version": "2.8.17",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
@ -4745,6 +4756,18 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/create-jest": { "node_modules/create-jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
@ -9248,7 +9271,6 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }

View File

@ -14,6 +14,7 @@
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/node": "^20.12.7", "@types/node": "^20.12.7",
"axios": "^1.6.8", "axios": "^1.6.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
@ -21,6 +22,7 @@
"swagger-ui-express": "^5.0.0" "swagger-ui-express": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/cors": "^2.8.17",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/rewire": "^2.5.30", "@types/rewire": "^2.5.30",
"@types/supertest": "^6.0.2", "@types/supertest": "^6.0.2",

View File

@ -1,11 +1,13 @@
import { getCity, getRadius, getPoiId, getBox } from "./openTripMaps" import { getCity, getRadius, getPoiId, getBox } from "./openTripMaps"
import express from "express" import express from "express"
import cors from "cors"
/** /**
* Initialize Express application instance. * Initialize Express application instance.
* @returns An initialized Express application object. * @returns An initialized Express application object.
*/ */
const app = express() const app = express()
app.use(cors())
/** /**

View File

@ -13,7 +13,7 @@ const key = process.env.OPEN_TRIP_MAPS_KEY
* @param {string} lat2 Latitude of the 2nd point of the box * @param {string} lat2 Latitude of the 2nd point of the box
* @returns {FeatureCollection} a list of POIs with their type, id, etc. (cf: [opentripmap](https://dev.opentripmap.org/docs#)) * @returns {FeatureCollection} a list of POIs with their type, id, etc. (cf: [opentripmap](https://dev.opentripmap.org/docs#))
*/ */
async function callBox(lon1:string, lat1:string, lon2: string, lat2: string) { async function callBox(lon1:string, lat1:string, lon2: string, lat2: string, rate: string) {
const lonMin = Math.min(parseFloat(lon1), parseFloat(lon2)) const lonMin = Math.min(parseFloat(lon1), parseFloat(lon2))
const lonMax = Math.max(parseFloat(lon1), parseFloat(lon2)) const lonMax = Math.max(parseFloat(lon1), parseFloat(lon2))
const latMin = Math.min(parseFloat(lat1), parseFloat(lat2)) const latMin = Math.min(parseFloat(lat1), parseFloat(lat2))
@ -27,6 +27,7 @@ async function callBox(lon1:string, lat1:string, lon2: string, lat2: string) {
lon_max: lonMax, lon_max: lonMax,
lat_min: latMin, lat_min: latMin,
lat_max: latMax, lat_max: latMax,
rate: rate,
apikey: key, apikey: key,
kinds: 'bars,cafes,pubs,biergartens' kinds: 'bars,cafes,pubs,biergartens'
}, },
@ -182,11 +183,16 @@ export async function getBox(req:express.Request, res: express.Response) {
const lat1 = req.query["lat1"] as string const lat1 = req.query["lat1"] as string
const lon2 = req.query["lon2"] as string const lon2 = req.query["lon2"] as string
const lat2 = req.query["lat2"] as string const lat2 = req.query["lat2"] as string
let rate = req.query["rate"] as string
if(!lon1 || !lat1 || !lon2 || !lat2){ if(!lon1 || !lat1 || !lon2 || !lat2){
res.status(400).send("Missing Argument") res.status(400).send("Missing Argument")
return return
} }
res.send( await callBox(lon1, lat1, lon2, lat2)) if(!rate){
rate = "1";
}
res.send( await callBox(lon1, lat1, lon2, lat2, rate))
} }

View File

@ -21,7 +21,7 @@ const options = {
} }
], ],
}, },
apis: ['./src/*.ts'], apis: ['./src/*.ts','./dist/src/*.js'],
explorer: true explorer: true
} }

View File

@ -219,6 +219,14 @@ describe("Test the otm city path", () => {
} }
] ]
} }
function sleep(milliseconds: number) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
sleep(2000);
request(app) request(app)
.get("/otm/box") .get("/otm/box")
.query({'lon1':'-1.435199','lon2':'-1.43519', 'lat1':'46.668460', 'lat2':'46.668461'}) .query({'lon1':'-1.435199','lon2':'-1.43519', 'lat1':'46.668460', 'lat2':'46.668461'})

View File

@ -0,0 +1,18 @@
{
"folders": [
{
"name": "Ratrapage_WEB",
"path": "."
},
{
"name": "barAndCafe",
"path": "Express/barAndCafe"
},
{
"path": "front"
}
],
"settings": {
"typescript.tsdk": "node_modules/typescript/lib"
}
}

View File

@ -1,5 +1,6 @@
vars { vars {
TRIPMAP_URL: https://api.opentripmap.com/0.1 TRIPMAP_URL: https://api.opentripmap.com/0.1
EXPRESS_API: http://localhost:3001
} }
vars:secret [ vars:secret [
app_key, app_key,

View File

@ -0,0 +1,8 @@
vars {
EXPRESS_API: https://drink-tweb.cb85.fr
PB_URL: https://pb-tweb.cb85.fr
TRIPMAP_URL: https://api.opentripmap.com/0.1/
}
vars:secret [
OTM_KEY
]

View File

@ -5,7 +5,7 @@ meta {
} }
get { get {
url: http://localhost:3001/otm/city?name=La roche sur yon&radius=300 url: {{EXPRESS_API}}/otm/city?name=La roche sur yon&radius=300
body: none body: none
auth: none auth: none
} }

View File

@ -0,0 +1,16 @@
meta {
name: otm_city
type: http
seq: 5
}
get {
url: {{TRIPMAP_URL}}/en/places/geoname?name=paris&apikey={{OTM_KEY}}
body: none
auth: none
}
query {
name: paris
apikey: {{OTM_KEY}}
}

View File

@ -0,0 +1,18 @@
meta {
name: connexion
type: http
seq: 1
}
post {
url: {{PB_URL}}/api/collections/users/auth-with-password
body: json
auth: none
}
body:json {
{
"identity": "michel.biche@aptatio.com",
"password": "123456789"
}
}

View File

@ -0,0 +1,27 @@
meta {
name: get all poi
type: http
seq: 5
}
get {
url: {{PB_URL}}/api/collections/user_poi/records?filter=owner='vvy93m1hoaeshwy'&&poi_list='cabkkovmjsfoapa'
body: json
auth: bearer
}
query {
filter: owner
poi_list: 'cabkkovmjsfoapa'
}
auth:bearer {
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfcGJfdXNlcnNfYXV0aF8iLCJleHAiOjE3MTg4Mjg0NzEsImlkIjoidnZ5OTNtMWhvYWVzaHd5IiwidHlwZSI6ImF1dGhSZWNvcmQifQ.pC7u-QaZ_BYqWA5wG8wu1lRbbd4mKuKeAveWe_IBnfU
}
body:json {
{
"owner": "vvy93m1hoaeshwy",
"poi_list": "sh430u0im37cxm5"
}
}

View File

@ -0,0 +1,22 @@
meta {
name: link user to poi
type: http
seq: 3
}
post {
url: {{PB_URL}}/api/collections/user_poi/records
body: json
auth: bearer
}
auth:bearer {
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfcGJfdXNlcnNfYXV0aF8iLCJleHAiOjE3MTg4Mjg0NzEsImlkIjoidnZ5OTNtMWhvYWVzaHd5IiwidHlwZSI6ImF1dGhSZWNvcmQifQ.pC7u-QaZ_BYqWA5wG8wu1lRbbd4mKuKeAveWe_IBnfU
}
body:json {
{
"owner": "vvy93m1hoaeshwy",
"poi_list": "sh430u0im37cxm5"
}
}

View File

@ -0,0 +1,40 @@
meta {
name: send a poi
type: http
seq: 2
}
post {
url: {{PB_URL}}/api/collections/POI/records
body: json
auth: bearer
}
auth:bearer {
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfcGJfdXNlcnNfYXV0aF8iLCJleHAiOjE3MTg4Mjg0NzEsImlkIjoidnZ5OTNtMWhvYWVzaHd5IiwidHlwZSI6ImF1dGhSZWNvcmQifQ.pC7u-QaZ_BYqWA5wG8wu1lRbbd4mKuKeAveWe_IBnfU
}
body:json {
{
"Poi_id": "11472887",
"Poi": {
"type": "Feature",
"id": "11472887",
"geometry": {
"type": "Point",
"coordinates": [
-0.0626024,
51.4924088
]
},
"properties": {
"xid": "W544344833",
"name": "The Blue Anchor",
"rate": 2,
"osm": "way/544344833",
"wikidata": "Q7718716",
"kinds": "pubs,foods,shops,marketplaces,tourist_facilities"
}
}
}
}

View File

@ -0,0 +1,37 @@
meta {
name: send fav to astro
type: http
seq: 4
}
post {
url: http://localhost:3000/maps/save_poi
body: json
auth: bearer
}
auth:bearer {
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb2xsZWN0aW9uSWQiOiJfcGJfdXNlcnNfYXV0aF8iLCJleHAiOjE3MTg4ODY2OTIsImlkIjoidnZ5OTNtMWhvYWVzaHd5IiwidHlwZSI6ImF1dGhSZWNvcmQifQ.R9PBGlHn6aBHt89g6G0NykMh_Vye24OpKEUYtz6R6Og
}
body:json {
{
"type": "Feature",
"id": "11472888",
"geometry": {
"type": "Point",
"coordinates": [
-0.0626024,
51.4924088
]
},
"properties": {
"xid": "W544344833",
"name": "The Blue Anchor",
"rate": 2,
"osm": "way/544344833",
"wikidata": "Q7718716",
"kinds": "pubs,foods,shops,marketplaces,tourist_facilities"
}
}
}

View File

@ -18,7 +18,9 @@ services:
- public - public
front: front:
image: git.lab-ouest.org/epitech/ratrapage_t-web_front:pr-1-head image: git.lab-ouest.org/epitech/ratrapage_t-web_front:pr-16-head
environment:
- POCKETBASE_URL=https://${POCKET_BASE_URL}
depends_on: depends_on:
- pocketbase - pocketbase
labels: labels:
@ -30,9 +32,10 @@ services:
- public - public
back_drink: back_drink:
image: git.lab-ouest.org/epitech/ratrapage_t-web_back:pr-6-head image: git.lab-ouest.org/epitech/ratrapage_t-web_back:master
environment: environment:
- port=${BACK_BASE_PORT} - port=${BACK_BASE_PORT}
- OPEN_TRIP_MAPS_KEY=${OPEN_TRIP_MAPS_KEY}
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.expressDrinkTweb.rule=Host(`${DRINK_URL}`) - traefik.http.routers.expressDrinkTweb.rule=Host(`${DRINK_URL}`)
@ -92,4 +95,4 @@ x-dockge:
- https://${FRONT_URL}/ - https://${FRONT_URL}/
- https://${DOCS_DRINK_URL}/ - https://${DOCS_DRINK_URL}/
- https://${DRINK_URL}/ - https://${DRINK_URL}/
- https://${DATA_TOURISME_URL}/ - https://${DATA_TOURISME_URL}/

View File

@ -26,7 +26,8 @@ const whenExternalScripts = (items = []) =>
hasExternalScripts ? (Array.isArray(items) ? items.map((item) => item()) : [items()]) : []; hasExternalScripts ? (Array.isArray(items) ? items.map((item) => item()) : [items()]) : [];
export default defineConfig({ export default defineConfig({
output: 'server',
compressHTML: true, compressHTML: true,
build: { build: {
assets: 'assets', assets: 'assets',
@ -37,7 +38,6 @@ export default defineConfig({
port: 3000 port: 3000
}, },
trailingSlash: 'never', trailingSlash: 'never',
output: 'server',
adapter: node({ adapter: node({
mode: 'standalone' mode: 'standalone'
}), }),

View File

@ -20,12 +20,16 @@
"astro-embed": "^0.7.2", "astro-embed": "^0.7.2",
"astro-icon": "^1.1.0", "astro-icon": "^1.1.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet-control-geocoder": "^2.4.0",
"leaflet-geosearch": "^4.0.0",
"leaflet-routing-machine": "^3.2.12",
"limax": "4.1.0", "limax": "4.1.0",
"lodash.merge": "^4.6.2", "lodash.merge": "^4.6.2",
"lucide-astro": "^0.372.0", "lucide-astro": "^0.372.0",
"pocketbase": "^0.21.1", "pocketbase": "^0.21.1",
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"simple-icons-astro": "^11.12.0", "simple-icons-astro": "^11.12.0",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"unpic": "^3.18.0" "unpic": "^3.18.0"
}, },
@ -42,6 +46,7 @@
"@types/eslint__js": "^8.42.3", "@types/eslint__js": "^8.42.3",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/leaflet": "^1.9.12", "@types/leaflet": "^1.9.12",
"@types/leaflet-routing-machine": "^3.2.8",
"@types/lodash.merge": "^4.6.9", "@types/lodash.merge": "^4.6.9",
"@types/node": "^20", "@types/node": "^20",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
@ -59,7 +64,6 @@
"reading-time": "^1.5.0", "reading-time": "^1.5.0",
"rehype-plugin-image-native-lazy-loading": "^1.2.0", "rehype-plugin-image-native-lazy-loading": "^1.2.0",
"sharp": "0.33.3", "sharp": "0.33.3",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript": "^5", "typescript": "^5",
"typescript-eslint": "^7.9.0", "typescript-eslint": "^7.9.0",
@ -1129,7 +1133,6 @@
"version": "7.24.5", "version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
"integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
"dev": true,
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.14.0" "regenerator-runtime": "^0.14.0"
}, },
@ -1746,6 +1749,15 @@
"resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.0.18.tgz", "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.0.18.tgz",
"integrity": "sha512-rJzSrtJ3b7djiGFvRuTe6stDfbYJGhdQSfn2SI2WfXviee7Er0yKAHE5u7FU7OWVQQQ1x3+cxdmx9NdiAkcrcA==" "integrity": "sha512-rJzSrtJ3b7djiGFvRuTe6stDfbYJGhdQSfn2SI2WfXviee7Er0yKAHE5u7FU7OWVQQQ1x3+cxdmx9NdiAkcrcA=="
}, },
"node_modules/@googlemaps/js-api-loader": {
"version": "1.16.6",
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.6.tgz",
"integrity": "sha512-V8p5W9DbPQx74jWUmyYJOerhiB4C+MHekaO0ZRmc6lrOYrvY7+syLhzOWpp55kqSPeNb+qbC2h8i69aLIX6krQ==",
"optional": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.11.14", "version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
@ -2459,6 +2471,22 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@mapbox/corslite": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/@mapbox/corslite/-/corslite-0.0.7.tgz",
"integrity": "sha512-w/uS474VFjmqQ7fFWIMZINQM1BAQxDLuoJaZZIPES1BmeYpCtlh9MtbFxKGGDAsfvut8/HircIsVvEYRjQ+iMg=="
},
"node_modules/@mapbox/polyline": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@mapbox/polyline/-/polyline-0.2.0.tgz",
"integrity": "sha512-GCddO0iw6AzOQqZgBmjEQI9Pgo40/yRgkTkikGctE01kNBN0ThWYuAnTD+hRWrAWMV6QJ0rNm4m8DAsaAXE7Pg==",
"bin": {
"polyline": "bin/polyline.bin.js"
},
"engines": {
"node": "*"
}
},
"node_modules/@mdx-js/mdx": { "node_modules/@mdx-js/mdx": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz",
@ -3061,6 +3089,15 @@
"@types/geojson": "*" "@types/geojson": "*"
} }
}, },
"node_modules/@types/leaflet-routing-machine": {
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/@types/leaflet-routing-machine/-/leaflet-routing-machine-3.2.8.tgz",
"integrity": "sha512-v2pJDv/nqbB769SsytHemhLkqwjVor9UdWvZ1l6Y2SEaXNt1yDwVrktc4sCT8/4n7npuEb8VP+UAk8xrPePqSQ==",
"dev": true,
"dependencies": {
"@types/leaflet": "*"
}
},
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.17.4", "version": "4.17.4",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz",
@ -6318,7 +6355,7 @@
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true "devOptional": true
}, },
"node_modules/fast-glob": { "node_modules/fast-glob": {
"version": "3.3.2", "version": "3.3.2",
@ -8117,6 +8154,36 @@
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
}, },
"node_modules/leaflet-control-geocoder": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/leaflet-control-geocoder/-/leaflet-control-geocoder-2.4.0.tgz",
"integrity": "sha512-b2QlxuFd40uIDbnoUI3U9fzfnB4yKUYlmsXjquJ2d2YjoJqnyVYcIJeErAVv3kPvX3nI0gzvBq1XHMgSVFrGkQ==",
"optionalDependencies": {
"open-location-code": "^1.0.0"
},
"peerDependencies": {
"leaflet": "^1.6.0"
}
},
"node_modules/leaflet-geosearch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/leaflet-geosearch/-/leaflet-geosearch-4.0.0.tgz",
"integrity": "sha512-a92VNY9gxyv3oyEDqIWoCNoBllajWRYejztzOSNmpLRtzpA6JtGgy/wwl9tsB8+6Eek1fe+L6+W0MDEOaidbXA==",
"optionalDependencies": {
"@googlemaps/js-api-loader": "^1.16.6",
"leaflet": "^1.6.0"
}
},
"node_modules/leaflet-routing-machine": {
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/leaflet-routing-machine/-/leaflet-routing-machine-3.2.12.tgz",
"integrity": "sha512-HLde58G1YtD9xSIzZavJ6BPABZaV1hHeGst8ouhzuxmSC3s32NVtADT+njbIUMW1maHRCrsgTk/E4hz5QH7FrA==",
"dependencies": {
"@mapbox/corslite": "0.0.7",
"@mapbox/polyline": "^0.2.0",
"osrm-text-instructions": "^0.13.2"
}
},
"node_modules/levn": { "node_modules/levn": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -8164,7 +8231,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"darwin" "darwin"
@ -8184,7 +8250,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"darwin" "darwin"
@ -8204,7 +8269,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"freebsd" "freebsd"
@ -8224,7 +8288,6 @@
"cpu": [ "cpu": [
"arm" "arm"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@ -8244,7 +8307,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@ -8264,7 +8326,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@ -8284,7 +8345,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@ -8304,7 +8364,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@ -8324,7 +8383,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"win32" "win32"
@ -10006,6 +10064,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/open-location-code": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/open-location-code/-/open-location-code-1.0.3.tgz",
"integrity": "sha512-DBm14BSn40Ee241n80zIFXIT6+y8Tb0I+jTdosLJ8Sidvr2qONvymwqymVbHV2nS+1gkDZ5eTNpnOIVV0Kn2fw==",
"optional": true
},
"node_modules/optionator": { "node_modules/optionator": {
"version": "0.9.4", "version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@ -10056,6 +10120,11 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/osrm-text-instructions": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/osrm-text-instructions/-/osrm-text-instructions-0.13.4.tgz",
"integrity": "sha512-ge4ZTIetMQKAHKq2MwWf83ntzdJN20ndRKRaVNoZ3SkDkBNO99Qddz7r6+hrVx38I+ih6Rk5T1yslczAB6Q9Pg=="
},
"node_modules/p-limit": { "node_modules/p-limit": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
@ -10899,8 +10968,7 @@
"node_modules/regenerator-runtime": { "node_modules/regenerator-runtime": {
"version": "0.14.1", "version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
"dev": true
}, },
"node_modules/regexp.prototype.flags": { "node_modules/regexp.prototype.flags": {
"version": "1.5.2", "version": "1.5.2",
@ -12272,7 +12340,6 @@
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz",
"integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==", "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==",
"dev": true,
"dependencies": { "dependencies": {
"@babel/runtime": "^7.24.1" "@babel/runtime": "^7.24.1"
}, },

View File

@ -16,37 +16,32 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^8.2.5", "@astrojs/node": "^8.2.5",
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.4",
"@astrojs/tailwind": "^5.1.0", "@astrojs/tailwind": "^5.1.0",
"@astrolib/analytics": "^0.5.0",
"@astrolib/seo": "^1.0.0-beta.5",
"@fontsource-variable/inter": "^5.0.18",
"@tailwindcss/typography": "^0.5.12", "@tailwindcss/typography": "^0.5.12",
"astro": "^4.8.3",
"astro-embed": "^0.7.2",
"astro-icon": "^1.1.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet-control-geocoder": "^2.4.0",
"leaflet-geosearch": "^4.0.0",
"leaflet-routing-machine": "^3.2.12",
"limax": "4.1.0",
"lodash.merge": "^4.6.2",
"lucide-astro": "^0.372.0", "lucide-astro": "^0.372.0",
"pocketbase": "^0.21.1", "pocketbase": "^0.21.1",
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"simple-icons-astro": "^11.12.0", "simple-icons-astro": "^11.12.0",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.4",
"@astrolib/analytics": "^0.5.0",
"@astrolib/seo": "^1.0.0-beta.5",
"@fontsource-variable/inter": "^5.0.18",
"astro": "^4.8.3",
"astro-embed": "^0.7.2",
"astro-icon": "^1.1.0",
"limax": "4.1.0",
"lodash.merge": "^4.6.2",
"unpic": "^3.18.0" "unpic": "^3.18.0"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/check": "^0", "@astrojs/check": "^0",
"@types/leaflet": "^1.9.12",
"@types/node": "^20",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitest/coverage-v8": "^1",
"eslint": "^8.57.0",
"eslint-plugin-astro": "^0.31.4",
"typescript": "^5",
"vitest": "^1",
"@astrojs/mdx": "^3.0.0", "@astrojs/mdx": "^3.0.0",
"@astrojs/partytown": "^2.1.0", "@astrojs/partytown": "^2.1.0",
"@astrojs/tailwind": "5.1.0", "@astrojs/tailwind": "5.1.0",
@ -57,8 +52,16 @@
"@tailwindcss/typography": "^0.5.13", "@tailwindcss/typography": "^0.5.13",
"@types/eslint__js": "^8.42.3", "@types/eslint__js": "^8.42.3",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/leaflet": "^1.9.12",
"@types/leaflet-routing-machine": "^3.2.8",
"@types/lodash.merge": "^4.6.9", "@types/lodash.merge": "^4.6.9",
"@types/node": "^20",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitest/coverage-v8": "^1",
"astro-eslint-parser": "^1.0.2", "astro-eslint-parser": "^1.0.2",
"eslint": "^8.57.0",
"eslint-plugin-astro": "^0.31.4",
"eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-jsx-a11y": "^6.8.0",
"globals": "^15.2.0", "globals": "^15.2.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
@ -68,8 +71,9 @@
"reading-time": "^1.5.0", "reading-time": "^1.5.0",
"rehype-plugin-image-native-lazy-loading": "^1.2.0", "rehype-plugin-image-native-lazy-loading": "^1.2.0",
"sharp": "0.33.3", "sharp": "0.33.3",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript-eslint": "^7.9.0" "typescript": "^5",
"typescript-eslint": "^7.9.0",
"vitest": "^1"
} }
} }

View File

@ -0,0 +1,30 @@
---
import type { Input as Props } from 'types';
const {value, checked ,name, label, autocomplete, placeholder, divClass, inputClass} = Astro.props;
---
<>
{
name && (
<div class={"flex flex-row items-center " + divClass}>
<input
type="checkbox"
name={name}
id={name}
checked={checked}
value={value}
autocomplete={autocomplete}
placeholder={placeholder}
class={"mr-2 size-5 " + inputClass}
/>
{label && (
<label for={name} class="block text-lg font-medium">
{label}
</label>
)}
</div>
)
}
</>

View File

@ -0,0 +1,28 @@
---
import type { Input as Props } from 'types';
const { type, name, label, autocomplete, placeholder, divClass, inputClass} = Astro.props;
---
<>
{
name && (
<div class={divClass}>
{label && (
<label for={name} class="block text-sm font-medium">
{label}
</label>
)}
<input
type={type}
name={name}
id={name}
autocomplete={autocomplete}
placeholder={placeholder}
class={"py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900" + inputClass}
/>
</div>
)
}
</>

View File

@ -0,0 +1,19 @@
---
export interface Props {
values: Array<{label:String, name:string, checked?:boolean | undefined}>
}
const fields = Astro.props.values
---
<>
<div class="flex, flex-col">
{fields.map(value => (
<input type="radio" id={value.name} name="note-min" value={value.name} checked={value.checked}>
<label for={value.name} class="ml-1">{value.label}</label><br>
))}
</div>
</>

View File

@ -26,7 +26,7 @@ export interface Props {
const { socialLinks = [], secondaryLinks = [], links = [], footNote = '', theme = 'light' } = Astro.props; const { socialLinks = [], secondaryLinks = [], links = [], footNote = '', theme = 'light' } = Astro.props;
--- ---
<footer class:list={[{ dark: theme === 'dark' }, 'relative border-t border-gray-200 dark:border-slate-800 not-prose, mt-auto']}> <footer class:list={[{ dark: theme === 'dark' }, 'relative border-t border-gray-200 dark:border-slate-800 not-prose, mt-auto, h-{11rem}']}>
<div class="dark:bg-dark absolute inset-0 pointer-events-none" aria-hidden="true"></div> <div class="dark:bg-dark absolute inset-0 pointer-events-none" aria-hidden="true"></div>
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 dark:text-slate-300"> <div class="relative max-w-7xl mx-auto px-4 sm:px-6 dark:text-slate-300">
<div class="grid grid-cols-12 gap-4 gap-y-8 sm:gap-8 py-8 md:py-12"> <div class="grid grid-cols-12 gap-4 gap-y-8 sm:gap-8 py-8 md:py-12">

View File

@ -55,7 +55,7 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`
<header <header
class:list={[ class:list={[
{ sticky: isSticky, relative: !isSticky, dark: isDark }, { sticky: isSticky, relative: !isSticky, dark: isDark },
'top-0 z-40 flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out', 'top-0 z-[1001] h-[5rem] bg-page flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out',
]} ]}
{...isSticky ? { 'data-aw-sticky-header': true } : {}} {...isSticky ? { 'data-aw-sticky-header': true } : {}}
{...id ? { id } : {}} {...id ? { id } : {}}
@ -88,7 +88,7 @@ const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`
aria-label="Main navigation" aria-label="Main navigation"
> >
<ul <ul
class="flex flex-col md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center" class="flex flex-col bg-page md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center"
> >
{ {
links.map(({ text, href, links }) => ( links.map(({ text, href, links }) => (

View File

@ -1,6 +1,6 @@
site: site:
name: AstroWind name: EpicRoadTrip
site: 'https://astrowind.vercel.app' site: 'https://front-tweb.cb85.fr'
base: '/' base: '/'
trailingSlash: false trailingSlash: false

6
front/src/env.d.ts vendored
View File

@ -6,10 +6,10 @@
import PocketBase from 'pocketbase' import PocketBase from 'pocketbase'
export interface ImportMetaEnv { export interface ImportMetaEnv {
NODE_ENV: string NODE_ENV: string
APP_URL: string APP_URL: string
POCKETBASE_URL: string POCKETBASE_URL: string
GOOGLE_API_KEY: string GOOGLE_API_KEY: string
} }

View File

@ -80,18 +80,4 @@ const metadata = {
]} ]}
/> />
<Oauth/> <Oauth/>
<form id="account-creation" method="post" enctype="multipart/form-data">
<input type="hidden" name="type" value="userPassword">
<input required name="name" placeholder="Prénom Nom"/>
<input required name="username" placeholder="Pseudo"/>
<input required name="email" type="email" placeholder="Renseignez votre email" />
<input required name="password" type="password" placeholder="Créez un mot de passe" />
<input required name="passwordConfirm" type="password" placeholder="Confirmer votre mot de passe" />
<button>Créer un compte</button>
</form>
<button id="OauthDiscord">connexion avec discord</button>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="type" value="discord2FA">
</form>
</Layout> </Layout>

View File

@ -1,31 +0,0 @@
---
import Layout from 'layouts/PageLayout.astro';
import 'leaflet/dist/leaflet.css'
const metadata = {
title: 'Maps',
ignoreTitleTemplate: true,
};
---
<Layout metadata={metadata}>
<div class="w-full h-96" id="map" />
</Layout>
<script>
import L from 'leaflet'
const map = L.map('map', {
center: [50,0],
zoom: 13,
preferCanvas: true
})
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var marker = L.marker([51.5, -0.09]).addTo(map);
</script>

View File

@ -0,0 +1,89 @@
---
import Layout from 'layouts/PageLayout.astro'
import 'leaflet/dist/leaflet.css'
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css'
import FormContainer from 'components/ui/Form.astro'
import Input from 'components/Input.astro'
import Button from 'components/ui/Button.astro'
const metadata = {
title: 'Maps',
ignoreTitleTemplate: true,
}
---
<Layout metadata={metadata}>
<div class="h-[calc(100vh-16rem)] flex flex-col">
<div class="w-full h-96 grow" id="map" />
<Button id="test-btn">test</Button>
</div>
<!-- TODO: faire en sort que le style soit propre -->
<!-- for remouve footer -->
<!-- <div slot="footer"></div> -->
<!-- penser a rm 11 au rem au dessus pour la taille -->
</Layout>
<script>
import * as L from 'leaflet'
import markerShadow from "leaflet/dist/images/marker-shadow.png"
import markerIcon from "leaflet/dist/images/marker-icon.png"
import 'leaflet-routing-machine/dist/leaflet-routing-machine.js'
import 'leaflet-control-geocoder/dist/Control.Geocoder.js'
const icon = {icon: new L.Icon({iconUrl: markerIcon.src, shadowUrl: markerShadow.src, iconAnchor: [13,41]})}
// declare map
const map = L.map('map', {
center: [51.5, -0.09],
zoom: 13,
preferCanvas: true,
zoomControl: false
})
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map)
// move zoom ctl to bottom
L.control.zoom({
position: 'bottomleft'
}).addTo(map);
const routing = L.Routing.control({
// utile pour afficher des route stocké
// waypoints: [
// L.latLng(46.6705431, -1.4269698),
// L.latLng(47.218536, -1.554075)
// ],
routeWhileDragging: true,
//@ts-ignore
geocoder: L.Control.Geocoder.nominatim(),
//@ts-ignore
position: 'topleft',
showAlternatives: true,
reverseWaypoints: true,
altLineOptions: {
missingRouteTolerance: 50,
extendToWaypoints: true,
styles: [
{color: 'black', opacity: 0.15, weight: 9},
{color: 'white', opacity: 0.2, weight: 6},
{color: 'blue', opacity: 5, weight: 2}
]
}
}).addTo(map).on('routeselected', (e) => {
console.log("iténeraire choisie")
console.log(e)
}).on('routesfound', (e) =>{
console.log("route trouvé")
console.log(e)
})
document.querySelector<HTMLButtonElement>('#test-btn')?.addEventListener('click', () => {
routing.setWaypoints(
[L.latLng(46.6705431, -1.4269698),L.latLng(47.218536, -1.554075)]
)
routing.route();
})
</script>

View File

@ -0,0 +1,281 @@
---
import Layout from 'layouts/PageLayout.astro'
import 'leaflet/dist/leaflet.css'
import 'leaflet-geosearch/dist/geosearch.css'
import CheckBox from 'components/CheckBox.astro'
import Radios from 'components/Radios.astro'
import ListResult, { type RecordModel } from 'pocketbase'
import { Expand, Trash } from 'lucide-astro'
const pb = Astro.locals.pb
const connected = pb.authStore.isValid
const metadata = {
title: 'Maps',
ignoreTitleTemplate: true,
}
let fav = new Array<any>
if(connected){
try {
const request = await pb.collection('user_poi').getList(1,10,{filter:`owner="${pb.authStore.model!.id}"`, expand:"poi_list"})
request.items.forEach(element => {
fav.push(element.expand!.poi_list.Poi)
});
} catch (error) {
console.log(error);
}
}
console.log(fav);
---
<Layout metadata={metadata}>
<div class="h-[calc(100vh-5rem)] flex flex-row">
<div class="w-1/5 flex flex-col">
<p id="message" class="hidden text-center mb-3">pouet</p>
<p class="text-center text-2xl mb-3">Filtre :</p>
<div class="">
<p>note minimal :</p>
<Radios
values={[
{name: "1", label: "1", checked: true},
{name: "2", label: "2"},
{name: "3", label: "3"},
{name: "1h", label: "1h"},
{name: "2h", label: "2h"},
{name: "3h", label: "3h"},
]}
/>
<p class="text-center text-xl mb-3">Type POI :</p>
<CheckBox
label="Bar, Pub, Café,..."
name="filter"
value="drink"
checked
/>
</div>
<div class="mb-3 grow">
<p class="text-center text-xl mb-3">Source :</p>
<CheckBox
label="Open Trip Maps"
name="filter"
value="otm"
checked
/>
</div>
{connected && (
<div class="mb-2">
<p class="text-center text-xl mb-3">Favori :</p>
{fav.map(val =>(
<div class="ml-2 flex flex-row mb-1" id="fav-div">
<p class="grow poi-favori" id={val.id} data-pos={val.geometry.coordinates}>{val.properties.name}</p>
<Trash id={val.id} class="poi-trash"/>
</div>
))}
</div>
)}
</div>
<div class="flex flex-col h-full grow">
<div class="w-full h-full grow" id="map" />
</div>
</div>
<!-- TODO: faire en sort que le style soit propre -->
<!-- for remouve footer -->
<div slot="footer"></div>
<!-- penser a rm 11 au rem au dessus pour la taille -->
</Layout>
<script>
import L, {Popup} from 'leaflet'
import markerShadow from "leaflet/dist/images/marker-shadow.png"
import markerIcon from "leaflet/dist/images/marker-icon.png"
import { OpenStreetMapProvider } from 'leaflet-geosearch'
import { GeoSearchControl } from 'leaflet-geosearch'
const showFav = document.querySelectorAll(".poi-favori")
const trashFav = document.querySelectorAll(".poi-trash")
const favDiv = document.querySelector('#fav-div')
const icon = {icon: new L.Icon({iconUrl: markerIcon.src, shadowUrl: markerShadow.src, iconAnchor: [13,41]})}
// const BACK_URL = "http://localhost:3001/" //XXX : mettre url de prod
const BACK_URL = "https://drink-tweb.cb85.fr/" //XXX : mettre url de prod
// declare map
const map = L.map('map', {
center: [51.5, -0.09],
zoom: 13,
preferCanvas: true,
zoomControl: false
})
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map)
// move zoom ctl to bottom
L.control.zoom({
position: 'bottomleft'
}).addTo(map)
const provider = new OpenStreetMapProvider()
map.addControl(
GeoSearchControl({
notFoundMessage: 'Adresse introuvable !',
provider,
showMarker: false,
style: 'bar',
}),
)
async function saveToFav(element: any, save: boolean){
const url = '/maps/save_poi';
const options = {
method: 'POST',
body: JSON.stringify({Poi : element, save: save})
};
try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
function eventGotoFav(e: Element){
e.addEventListener('click', () =>{
const pose = e.getAttribute('data-pos')?.split(',')
map.panTo(new L.LatLng(parseFloat(pose![1]),parseFloat(pose![0])))
})
}
function eventRemoveFav(e: Element){
e.addEventListener('click', async () => {
await saveToFav({id:e.id, type:"Feature"},false)
document.location.reload()
})
}
showFav.forEach(e => {eventGotoFav(e)})
trashFav.forEach(e => {eventRemoveFav(e)})
let poiMarkers = new Array<L.Marker>
let minimalNote = "1"
let drink = true
let otm = true
// run api search
function searchBox(){
const nordWest = map.getBounds().getNorthWest()
const southEast = map.getBounds().getSouthEast()
const params: URLSearchParams = new URLSearchParams()
params.append("lon1", nordWest.lng.toString())
params.append("lat1", nordWest.lat.toString())
params.append("lon2", southEast.lng.toString())
params.append("lat2", southEast.lat.toString())
params.append("rate", minimalNote)
if(drink && otm){
fetch(`${BACK_URL}otm/box?${params.toString()}`,{method: 'GET',headers: {'Content-Type': 'application/json'}}).then(function (response) {
return response.json()
}).then(function (data) {
poiMarkers.forEach(element => {
element.remove()
})
console.log(data)
data.features.forEach(element => {
const prop = element.properties
const popup: Popup = new Popup()
let tags = new String()
prop.kinds.split(",").forEach(element => {
tags += "- " + element + "<br/>"
})
const poiMarker = L.marker([element.geometry.coordinates[1],element.geometry.coordinates[0]],icon)
.bindPopup(`<b>${prop.name}</b><br/>note : ${prop.rate} <br/>tags:<br/> ${tags} <p>favori : <input type="checkbox" name="like" id=${element.id}/><p>`)
.on("click", () => {
document.querySelectorAll<HTMLInputElement>('input[name="like"]').forEach(e => {
e.addEventListener("click", () => {
console.log(element)
saveToFav(element, e.checked)
document.location.reload()
})
})
})
poiMarker.addTo(map)
poiMarkers.push(poiMarker)
})
}).catch(function (err) {
console.warn('Something went wrong.', err)
})
}
}
// fonciton pour lancer la recherche de box sur l'api
function sender(){
if(map.getZoom() >= 13){
console.log("zoom OKAY")
//TODO: mettre un message de recherche en cour
searchBox()
}else{
console.log("zoom more to see result")
}
}
// envent pour lancer la recherche
const cooldown = 400
sender()
let timeoutHandle = window.setTimeout(sender, cooldown)
window.clearTimeout(timeoutHandle)
map.addEventListener("move",() =>{
window.clearTimeout(timeoutHandle)
timeoutHandle = window.setTimeout(sender, cooldown)
})
map.addEventListener("zoom", () => {
if(map.getZoom() <= 11){
poiMarkers.forEach(element => {
element.remove()
})
}
})
document.querySelectorAll<HTMLInputElement>("input[name='filter']").forEach(e =>{
e.addEventListener("click", () => {
switch (e.value) {
case "drink":
drink = e.checked
break;
case "otm":
otm = e.checked
break;
default:
break;
}
poiMarkers.forEach(element => {
element.remove()
})
searchBox()
})
})
document.querySelectorAll<HTMLInputElement>('input[name="note-min"]').forEach(e => {
e.addEventListener("click", () => {
minimalNote = e.value
searchBox()
})
})
</script>

View File

@ -0,0 +1,47 @@
---
import AstroUtils from "libs/AstroUtils";
import type { RecordModel } from "pocketbase";
const pb = Astro.locals.pb
if(!pb.authStore.isValid){
return Astro.redirect("/account")
}
await AstroUtils.wrap(async () => {
if (Astro.request.method !== 'POST') {
return
}
const poiJson = await Astro.request.json()
const data = {Poi: poiJson.Poi, Poi_id:poiJson.Poi.id}
let record: RecordModel
try {
record = await pb.collection('POI').create(data);
} catch (error) {
try{
record = await pb.collection('POI').getFirstListItem(`Poi_id="${poiJson.Poi.id}"`)
} catch (error2) {
console.log("error 1 :")
console.log(error)
console.log("error 2 :")
console.log(error2)
}
}
try {
if(poiJson.save){
await pb.collection('user_poi').create({owner: pb.authStore.model!.id, poi_list:record!.id})
}else{
record = await pb.collection('user_poi').getFirstListItem(`poi_list="${record!.id}"&&owner="${pb.authStore.model!.id}"`)
await pb.collection('user_poi').delete(record.id)
}
} catch (error) {
console.log(error)
}
})
---

10
front/src/types.d.ts vendored
View File

@ -1,5 +1,5 @@
import type { AstroComponentFactory } from 'astro/runtime/server/index.js' import type { AstroComponentFactory } from 'astro/runtime/server/index.js'
import type { HTMLAttributes, ImageMetadata } from 'astro/types' import type { HTMLAttributes, ImageMetadata, HTMLInputTypeAttribute } from 'astro/types'
export interface Post { export interface Post {
/** A unique ID number that identifies a post. */ /** A unique ID number that identifies a post. */
@ -26,7 +26,7 @@ export interface Post {
/** */ /** */
category?: Taxonomy category?: Taxonomy
/** */ /** */
tags?: Taxonomy[] tags?: Array<Taxonomy>
/** */ /** */
author?: string author?: string
@ -162,11 +162,15 @@ export interface Testimonial {
} }
export interface Input { export interface Input {
type: HTMLInputTypeAttribute type?: HTMLInputTypeAttribute
name: string name: string
label?: string label?: string
autocomplete?: string autocomplete?: string
placeholder?: string placeholder?: string
divClass?: string
inputClass?: string
checked?: bool
value?:string
} }
export interface Textarea { export interface Textarea {

View File

@ -1,24 +1,25 @@
import defaultTheme from 'tailwindcss/defaultTheme'; import defaultTheme from 'tailwindcss/defaultTheme'
import typographyPlugin from '@tailwindcss/typography'; import typographyPlugin from '@tailwindcss/typography'
module.exports = { module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,json,md,mdx,svelte,ts,tsx,vue}'], content: ['./src/**/*.{astro,html,js,jsx,json,md,mdx,svelte,ts,tsx,vue}'],
theme: { theme: {
extend: { extend: {
colors: { colors: {
primary: 'var(--aw-color-primary)', primary: 'var(--aw-color-primary)',
secondary: 'var(--aw-color-secondary)', secondary: 'var(--aw-color-secondary)',
accent: 'var(--aw-color-accent)', accent: 'var(--aw-color-accent)',
default: 'var(--aw-color-text-default)', default: 'var(--aw-color-text-default)',
muted: 'var(--aw-color-text-muted)', muted: 'var(--aw-color-text-muted)',
}, },
fontFamily: { fontFamily: {
sans: ['var(--aw-font-sans, ui-sans-serif)', ...defaultTheme.fontFamily.sans], sans: ['var(--aw-font-sans, ui-sans-serif)', ...defaultTheme.fontFamily.sans],
serif: ['var(--aw-font-serif, ui-serif)', ...defaultTheme.fontFamily.serif], serif: ['var(--aw-font-serif, ui-serif)', ...defaultTheme.fontFamily.serif],
heading: ['var(--aw-font-heading, ui-sans-serif)', ...defaultTheme.fontFamily.sans], heading: ['var(--aw-font-heading, ui-sans-serif)', ...defaultTheme.fontFamily.sans],
}, },
}, },
}, },
plugins: [typographyPlugin], plugins: [typographyPlugin],
darkMode: 'class', darkMode: 'class',
}; }

View File

@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
}