Commit working map with markers

This commit is contained in:
2025-08-18 00:51:11 +02:00
parent bf061bff08
commit 75453a7303
24 changed files with 515 additions and 402 deletions

54
package-lock.json generated
View File

@@ -15,16 +15,16 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"framer-motion": "^12.23.12", "framer-motion": "^12.23.12",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3", "leaflet-defaulticon-compatibility": "^0.1.2",
"next": "15.4.5", "next": "15.4.5",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-leaflet": "^5.0.0", "react-leaflet": "^5.0.0"
"react-leaflet-markercluster": "^5.0.0-rc.0"
}, },
"devDependencies": { "devDependencies": {
"@types/leaflet": "^1.9.20",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
@@ -1137,6 +1137,23 @@
"tslib": "^2.8.0" "tslib": "^2.8.0"
} }
}, },
"node_modules/@types/geojson": {
"version": "7946.0.16",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/leaflet": {
"version": "1.9.20",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.20.tgz",
"integrity": "sha512-rooalPMlk61LCaLOvBF2VIf9M47HgMQqi5xQ9QRi7c8PkdIe0WrIi5IxXUXQjAdL0c+vcQ01mYWbthzmp9GHWw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.19.9", "version": "20.19.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.9.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.9.tgz",
@@ -2375,14 +2392,11 @@
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/leaflet.markercluster": { "node_modules/leaflet-defaulticon-compatibility": {
"version": "1.5.3", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz", "resolved": "https://registry.npmjs.org/leaflet-defaulticon-compatibility/-/leaflet-defaulticon-compatibility-0.1.2.tgz",
"integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==", "integrity": "sha512-IrKagWxkTwzxUkFIumy/Zmo3ksjuAu3zEadtOuJcKzuXaD76Gwvg2Z1mLyx7y52ykOzM8rAH5ChBs4DnfdGa6Q==",
"license": "MIT", "license": "BSD-2-Clause"
"peerDependencies": {
"leaflet": "^1.3.1"
}
}, },
"node_modules/lines-and-columns": { "node_modules/lines-and-columns": {
"version": "1.2.4", "version": "1.2.4",
@@ -2641,24 +2655,6 @@
"react-dom": "^19.0.0" "react-dom": "^19.0.0"
} }
}, },
"node_modules/react-leaflet-markercluster": {
"version": "5.0.0-rc.0",
"resolved": "https://registry.npmjs.org/react-leaflet-markercluster/-/react-leaflet-markercluster-5.0.0-rc.0.tgz",
"integrity": "sha512-jWa4bPD5LfLV3Lid1RWgl+yKUuQtnqeYtJzzLb/fiRjvX+rtwzY8pMoUFuygqyxNrWxMTQlWKBHxkpI7Sxvu4Q==",
"license": "MIT",
"dependencies": {
"@react-leaflet/core": "^3.0.0",
"leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"react-leaflet": "^5.0.0"
},
"peerDependencies": {
"leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"react": "^19.0.0",
"react-leaflet": "^5.0.0"
}
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.10", "version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",

View File

@@ -16,16 +16,16 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"framer-motion": "^12.23.12", "framer-motion": "^12.23.12",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3", "leaflet-defaulticon-compatibility": "^0.1.2",
"next": "15.4.5", "next": "15.4.5",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-leaflet": "^5.0.0", "react-leaflet": "^5.0.0"
"react-leaflet-markercluster": "^5.0.0-rc.0"
}, },
"devDependencies": { "devDependencies": {
"@types/leaflet": "^1.9.20",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",

5
public/icons/drustva.svg Executable file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M668.28 362.04c29.398-38.398 61.922-76.32 101.16-107.64 21.961-17.52 45.602-33 69.121-48.48 10.68-6.96 27.238 3.84 29.398 19.441 1.2 8.52.602 18-2.04 26.281-14.64 46.801-14.28 95.52-19.32 143.52-1.679 16.199 3.962 28.441 18.72 38.762 45.359 31.32 55.922 24.238 80.52 129.84 10.32 61.68 8.762 109.44-6.238 170.4-7.559 30.719-18.84 56.16-26.762 78.121-13.68 37.922-35.52 69.719-69.48 93.48-54.961 38.52-115.56 59.52-182.76 63.48-37.801 2.16-75.36 6.36-113.04 9.84-56.641 5.281-111-5.52-162.12-28.441-26.88-12.121-59.16-24.602-82.801-42.48-31.441-23.762-54.238-53.762-78.602-86.04-52.68-71.878-52.078-132.24-59.762-182.76-15.36-100.92 19.199-195.96 76.8-216.24 47.52-21.237 43.56-57.237 48.603-89.16 2.879-18.237 5.761-36.601 8.398-54.84 5.281-38.397-12.719-120.6-12.961-124.56-.719-10.44 5.52-15.84 14.879-12 7.2 3 8.16 1.923 19.559 13.442 11.762 11.879 26.16 25.44 77.879 99.602 15.602 22.44 29.762 45.96 44.281 69.12 10.559 16.68 15.84 19.2 34.801 15.962 42.48-7.078 85.078-6.48 127.2 1.32 21.129 3.711 41.168 12.473 64.57 20.031zM323.04 203.16c1.441 19.801 4.922 52.199 4.559 72.121-.48 27.359-2.04 54.84-5.762 81.961-4.32 31.559-3 52.801-36.961 70.078-32.52 15.719-48.84 37.922-57.602 52.441-29.281 48.602-25.078 65.762-24.72 122.76.122 24.602-1.32 64.441 14.88 125.04 8.398 31.559 17.64 44.16 33.238 73.559 23.28 35.762 47.039 59.879 82.078 83.641 17.398 11.762 28.8 17.398 61.922 34.199 42.48 21.602 80.52 30.84 129 27.602 50.64-3.36 101.28-6.719 151.68-12.719 35.879-4.32 69.238-17.52 103.92-30.238 105.84-39 118.44-157.68 126.24-193.8 13.8-64.68 14.398-103.32 5.281-161.64-7.32-47.039-20.398-65.879-63-92.281-6.121-3.84-11.879-8.398-17.64-12.719-13.079-9.719-20.399-21.48-18.239-39.238 3.238-27.238 4.32-54.602 6.84-81.961 1.8-20.398 4.441-40.68 7.078-64.559-28.32 18.84-52.32 36.84-71.281 59.879-22.441 27-50.16 50.398-61.199 85.922-4.32 14.16-17.879 16.32-27.602 3.84-17.641-22.922-42.719-28.801-68.281-33.961-8.64-1.801-17.398-2.762-26.281-2.281-33.238 1.441-67.199-4.32-99.238 10.922-25.68 12.238-30.84 9.238-46.199-15.36-31.672-51.245-99.828-164.17-102.71-163.21z"/>
<path d="M447.96 829.08c22.199 6.719 31.32 9.36 54 14.281 16.559 3.48 44.398-18 49.199-35.879 4.68-17.52 5.16-33.602-7.441-49.441-12.36-15.719-35.398-44.641-33.121-51.84 2.878-8.64 8.039-13.32 18.719-13.922 20.64-.96 41.52-2.398 61.922-5.64 23.879-3.84 38.762 8.761 32.64 32.038-4.921 18.602-12.237 36.72-20.52 54-12.358 25.922-.12 60.121 28.2 67.441 13.199 3.48 28.44 1.2 42.359-.96 15.12-2.282 26.16.238 33.719 11.64 6.96 10.56 3.84 18.602-8.282 21.48-39 9.122-75.12 4.922-106.44-22.44-4.199-3.72-8.761-6.961-13.32-10.68-11.762 8.039-22.8 15.96-34.078 23.397-15 9.84-21.48 14.52-50.039 11.398-17.16-3-27.96-2.878-41.64-7.558-51.599-15.355-31.317-43.316-5.876-37.316zm136.32-109.2c-10.441.719-17.281 1.2-27.359 2.04 5.398 8.878 9.48 15.601 15.48 25.32 4.2-7.438 10.078-21.239 11.879-27.36zM416.04 579.36c-1.078-19.801-2.04-26.281 5.64-45.961 4.923-9.36 9.239-16.199 27.48-19.801 19.442-3 34.079 0 43.68 16.32 15.239 26.039 18 59.762 2.88 87.359-9.239 16.801-22.441 21.48-40.68 15.238-20.758-7.195-37.68-27.234-39-53.156zm50.039-25.559c-15.961-7.32-32.398 35.039-10.801 41.879 18.484 5.762 35.762-30.359 10.801-41.879zM325.08 677.4c46.078-9.719 86.398 2.281 122.88 30.48 3.602 2.879 6.96 6.96 8.52 11.281 1.199 3.121.48 8.52-1.68 10.801-2.04 2.16-6.961 1.559-10.68 2.04-.719.12-1.801-.122-2.281-.602-31.078-27-72.961-28.32-108.36-45.121-2.88-1.32-5.399-3.122-8.04-4.922-.359-.235-.117-1.434-.359-3.957zM425.28 771.36c-18.602 3.48-85.441-16.441-107.28-32.039 15.719-10.078 31.922-10.199 48.238-6 14.039 3.602 27.719 8.52 41.16 13.68 11.043 4.078 19.801 10.559 17.883 24.359zM312.96 810.96c22.68-20.039 47.16-22.32 69.961-27.48 3.84-.84 12.48 7.078 14.52 12.719 3.36 8.64-2.398 15.719-11.52 17.641-22.684 4.68-45.363 6.48-72.961-2.879z"/>
<path d="M454.92 804.72c-13.922-7.8-3.121-30.121 11.762-24.48 3.48 1.32 6.602 4.078 9 9.36 1.922 4.32 2.52 11.761.121 14.878-2.398 3-9.96 4.2-14.398 2.88-2.285-.716-4.445-1.555-6.484-2.637zM530.16 799.32c.36 5.762-3.238 11.16-6.84 12.121-7.922 2.16-22.922-10.199-21.84-18.359.48-4.078 5.88-9.719 9.961-10.801 6.598-1.8 17.758 7.2 18.72 17.039zM495.48 764.64c-14.398.602-22.559-5.762-23.281-15.602-.602-7.2 1.8-12.719 9.84-13.078 8.039-.48 18.96 9.36 18.719 18 .004 4.2 2.402 8.758-5.277 10.68zM826.08 677.88c-45.602-11.762-86.398-1.559-124.08 24.961-3.719 2.64-7.2 6.719-9 10.922-1.32 3.121-.84 8.52 1.2 10.801 1.921 2.281 6.96 1.8 10.558 2.52.719.12 1.801 0 2.281-.481 32.281-25.559 74.16-24.961 110.16-40.199 2.88-1.2 5.641-2.879 8.282-4.559.48-.125.238-1.324.597-3.964zM707.64 758.04c17.879 6.238 87-3.36 110.88-15.602-13.922-12.238-30-14.879-46.801-13.199-14.398 1.441-28.68 4.32-42.84 7.32-11.398 2.403-21 7.442-21.238 21.48zM811.56 807.84c-24.602-17.641-49.078-17.398-72.359-20.281-3.96-.48-11.641 8.398-13.199 14.039-2.398 9 3.96 15.359 13.199 16.32 22.922 2.523 45.723 2.16 72.359-10.078zM623.4 804.48c-13.922-7.8-3.121-30.121 11.762-24.48 3.48 1.32 6.602 4.078 9 9.36 1.922 4.32 2.52 11.761.121 14.878-2.398 3-9.96 4.2-14.398 2.88-2.402-.598-4.562-1.56-6.484-2.637zM698.64 799.08c.36 5.762-3.238 11.16-6.84 12.121-7.922 2.16-22.922-10.199-21.84-18.359.48-4.078 5.88-9.719 9.961-10.801 6.477-1.68 17.637 7.2 18.72 17.039zM663.84 764.52c-14.398.602-22.559-5.762-23.281-15.602-.602-7.2 1.8-12.719 9.84-13.078 8.039-.48 18.96 9.36 18.719 18 .004 4.082 2.402 8.64-5.277 10.68zM607.44 565.44c-1.078-19.801-2.04-26.281 5.64-45.961 4.922-9.36 9.239-16.199 27.48-19.801 19.442-3 34.079 0 43.68 16.32 15.239 26.039 18 59.762 2.88 87.359-9.239 16.801-22.441 21.48-40.68 15.238-20.641-7.2-37.562-27.238-39-53.156zm50.16-25.562c-15.961-7.32-32.398 35.039-10.801 41.879 18.359 5.762 35.758-30.359 10.801-41.879z"/>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

3
public/icons/frizerji.svg Executable file
View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M612.24 292.68v26.762c28.199 2.04 121.56 1.32 141.96 1.8 24.121 0 35.039 6.481 37.559 17.52 2.762 11.52-13.078 21.36-27 21.72-5.16 1.8-143.16-.602-151.8-1.442-.238 21.36 0 23.641-.121 29.16 41.039-.48 105.72 1.079 147.12.48 10.44-.48 20.16-1.32 23.879 6.962 2.879 6.48 3.238 20.398.238 26.398-2.16 4.441-18.12 5.039-24.238 4.8-49.8-1.078-98.039-.718-147.96 1.079-.601 8.039-.48 15.238-1.078 24.238 6.961 0 102.72 2.039 142.92-.48 6-.36 20.641.12 23.641 3.6 5.16 6.122 2.64 14.52 1.922 21.962-.96 9.84-15.961 10.44-25.559 11.039-41.039 2.52-102 .238-143.64 1.32-.48 4.441-.48 7.8-1.078 20.88 5.762.96 130.32.358 133.92.237 14.16-.238 32.039.48 32.398 17.762.48 21.961-15.121 21.72-24.961 21.121-20.762-1.32-133.56-3.238-143.4-3.84-3 64.32-5.52 132-8.762 200.4 5.04 1.079 18.48-1.32 23.641 0 15.121 3.84 12.961 12.48 14.04 27.122 1.679 21.48 4.8 124.92-5.04 157.8-8.879 30-20.52 53.879-40.32 76.922-20.398 23.64-72.602 22.8-90.84-4.2-10.68-15.96-18.238-33-24.48-51.12-14.64-41.88-17.28-88.802-19.922-133.32-1.078-18.36.961-36.962 1.32-55.442.239-12.238 7.078-17.16 18.48-17.28 7.2-.122 14.281 0 20.88 0-2.641-77.763-2.88-480.48 13.68-533.64 3.96-12.84 9.601-25.923 17.52-36.72 25.44-34.44 66.601-28.922 84.358 10.441 1.68 3.602 3.121 7.32 5.641 13.078 58.32-1.199 107.52-.718 176.52-1.558 14.16-.121 23.039 32.28-6.48 33.719-4.442.238-168.12.36-174.24.238.48 4.68-.481 10.801-.36 20.88 21.36 1.558 132.36 2.519 168.48 2.76 28.32.84 19.441 40.56 4.32 39.962-5.402-.477-151.68-3.117-173.16-3.117zm-89.879 453.24c6.84-.36 36.359.238 41.641 0-.84-43.441 1.441-126.12 3.602-164.76 1.921-34.68 3.12-69.359 4.558-104.04 2.52-58.801 3.961-198.84 4.559-210.12.84-17.762 2.398-35.398 2.16-53.16-.121-11.039-.602-25.559-14.398-27.359-14.16-1.8-18 12.359-20.039 23.039-6.121 32.398-7.2 62.281-8.281 95.039-2.399 66.84-7.922 136.44-7.68 203.28.121 51-3.719 208.56-6.121 238.08zm-30.121 37.078c-12.602 44.641 3.36 150.36 28.32 189.24 11.039 17.281 34.559 16.801 48.961 1.68 30.121-27 43.441-123.36 29.16-190.92z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

4
public/icons/ostalo.svg Executable file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M273.84 804c-38.039-23.16-56.52-56.762-65.398-96.961-11.398-52.199-14.16-104.64-12.359-158.28 2.16-66.961 27.121-124.32 62.879-177.48 15.238-22.68 42.121-46.078 64.078-63.48 45.121-35.879 103.68-75.359 221.76-93.48 48.48-7.441 97.441-10.922 146.88-10.199 92.16 1.32 167.64 35.398 227.52 104.52 47.762 55.32 93.238 112.68 116.52 186.12 4.078 12.961 7.2 26.281 9.48 39.719 5.399 30.602 12.72 60.602 11.16 92.398-2.039 42.48-13.921 82.559-26.28 122.52-56.637 134.41-153.12 174.61-173.64 186.48-34.2 23.641-73.2 33-113.52 38.281-23.16 3-191.64 1.559-238.44-16.078-8.641-1.922-31.56-8.64-43.68-13.922-24.72-10.801-35.52-11.641-48.72-8.52-48.48 14.04-89.52 24.84-135.72 38.398-26.52 7.801-44.878-8.16-38.397-35.398 9.718-40.68 21.719-80.879 32.762-121.32.953-3.84 1.793-7.68 3.113-13.32zm.602 135.48c7.8-1.32 81.48-17.039 115.08-24.961 6.84-1.68 14.52-4.559 19.199-9.36 16.68-17.16 31.44-11.64 49.078-.601 14.039 8.762 30.48 14.762 46.559 18.961 97.32 22.801 244.2 21.961 271.32 13.32 26.28-8.398 61.922-23.879 85.922-38.398 33.12-20.16 63.96-43.922 90.238-72.359 30.12-32.641 44.398-73.559 57.359-115.8 23.16-75.84 15.238-149.52-14.398-219.96-30.84-73.441-78.84-136.92-137.28-191.28-42.121-39.121-93.72-61.559-150.96-63.359-51.36-1.559-103.32.602-154.44 6.96-37.2 4.68-113.52 23.763-169.32 64.079-30.72 20.52-62.88 41.398-86.641 68.879-29.398 33.96-50.281 75.48-58.441 120.72-5.16 28.32-6.84 57.602-7.2 86.52-.601 45.12 3 90.12 20.04 132.84 8.761 22.078 20.878 41.762 40.68 55.922 19.558 13.922 23.64 25.199 16.921 48.84-4.312 15.602-26.39 92.402-33.71 119.04z"/>
<path d="M494.04 804.72c-12.48-6.36-26.52-25.801-27.84-39.48-1.68-16.922-.84-33.359 6-49.68 14.762-35.16 33.84-67.441 55.68-98.641 35.398-50.52 111.72-54.84 155.4-13.078 17.398 16.559 27.602 30.238 41.039 50.039 11.039 16.32 37.078 84 41.879 95.879 18.961 47.281-3 62.281-39.961 71.398-26.156 6.484-202.79-1.555-232.2-16.438zm215.28-11.758c21.238-4.2 26.16-13.078 21.719-34.559-2.52-12-6.48-23.641-9.36-35.398-1.44-5.879-2.878-11.879-4.921-17.641-12.72-35.641-27-61.199-52.922-84.961-22.922-20.879-59.281-22.441-84-3.36-28.32 21.84-44.04 52.923-60.48 83.282-6.121 11.16-12.121 22.44-18.84 33.238-11.04 17.64-2.04 40.199 17.28 48 50.165 20.156 169.56 15.719 191.52 11.398zM531.96 559.08c.48 35.641-32.641 63-64.32 53.398-53.281-16.078-94.441-46.68-114.12-101.28-6.96-19.199.36-46.441 17.641-57.84 24.48-15.961 51.359-20.641 77.641-6.121 39.961 22.078 70.199 53.28 81.121 99.602 1.2 4.684 1.68 9.605 2.04 12.242zm-122.88-92.52c-16.078-2.04-29.281 12.84-24.719 27.121 13.078 41.762 40.559 70.199 80.398 86.762 6.602 2.762 16.32 4.2 22.32 1.441 9.36-4.32 7.441-14.879 5.52-23.762-9-40.68-35.04-67.8-70.078-87.48-4.2-2.28-9.36-2.879-13.442-4.082zM515.04 406.44c-1.32-37.922 10.922-51 33.602-55.559 5.64-1.078 21-3.84 35.16 4.32 21.48 12.36 18.48 10.922 35.398 28.441 29.16 30.238 43.801 86.398 24.48 126.24-10.32 21.238-43.801 30-63 17.16-45.84-30.242-64.078-76.684-65.641-120.6zm42-20.52-.238.238c-5.16 4.801-7.442 12-5.88 18.84 12 55.801 23.399 81.121 42.48 91.801 7.2 4.078 16.68.121 19.32-7.68 11.763-33.358.481-69.84-32.64-102.72-6.242-6.363-16.562-6.48-23.043-.48zM784.68 386.52c48 18.48 44.039 57.48 19.32 102.6-11.281 20.52-27.719 37.922-45.602 54.238-6.238 5.762-15.238 9.121-23.52 11.762-21.84 7.078-41.281-1.8-47.398-24.238-4.2-15.121-5.16-31.801-3.96-47.52 1.8-23.52 26.761-71.281 48.358-95.762 10.082-11.641 30.84-9.48 52.801-1.082zm-66.121 138.12c10.559 5.52 23.641-3.36 25.68-5.16 27-22.922 30.359-48.48 40.078-82.801 1.441-5.281 3.238-11.762 1.559-16.56-5.399-16.198-27-15.84-31.2-7.198-8.878 18-20.16 34.922-28.44 53.16-8.157 17.879-28.195 47.879-7.676 58.559zM853.68 527.52c10.801 0 21.121 3.121 29.16 8.04 32.039 19.558 26.281 53.038 7.559 85.198-11.762 20.16-30 33-50.398 42.121-44.04 19.68-91.56-23.16-74.04-68.039 10.923-27.96 33.72-53.64 59.52-63.48 7.56-2.879 16.079-3.84 28.2-3.84zm-41.52 104.04c29.281-9.84 47.641-28.801 54.238-55.441 1.922-7.8-5.52-14.52-13.32-12.602-25.559 6.36-47.16 27.961-54.48 54.961-2.04 8.164 5.64 15.723 13.562 13.082z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

4
public/icons/rejci-zivali.svg Executable file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M427.08 364.8c-20.16-18.48-32.398-20.16-52.922-9.36-36.238 19.2-60.238 48.122-66.84 88.923-5.281 32.039-8.281 64.559-10.922 96.96-3 36.962-3.96 74.399-19.199 108.72-11.641 26.16-25.078 52.079-41.398 75.48-21 30.122-58.801 40.923-93.238 28.079-29.398-10.922-53.879-36.72-56.039-77.762-2.64-52.078 8.879-101.04 25.078-149.64 10.078-30.121 16.078-61.801 28.078-91.078 16.559-40.2 36.238-79.32 56.039-118.08 21.238-41.398 58.441-65.641 97.922-87.121 27.359-14.88 57-21.72 87.48-21.48 54.602.48 97.559 21.238 119.04 76.559 64.078-14.281 125.88-2.04 186.12 18 10.801-15 20.039-30.238 31.559-43.32 22.922-25.922 52.559-39.602 86.641-45.48 61.441-10.56 116.16 3.12 169.08 36 39.48 24.602 64.801 57.602 79.801 99.84 12.359 34.8 26.039 69.48 34.68 105.36 11.762 49.199 12.121 99.602 4.2 149.88-6.481 40.559-36.239 59.52-69.603 69.84-33.238 10.32-63.48-2.16-87.719-28.68-27.719-30.36-40.559-64.801-33.602-105.72 2.16-12.36 4.442-24.72 7.078-37.078 7.2-33.72 3.602-66-12-96.961-7.8-15.36-19.078-25.922-35.879-30.602-27.12-7.68-53.64-8.88-81.48 5.398 8.16 18.121 16.801 35.16 23.762 52.801 24.72 62.52 52.441 124.32 64.32 191.04 5.762 32.039 4.801 64.922-1.922 97.199-5.039 23.762-8.64 48-14.64 71.52-13.2 52.32-47.282 89.52-90.122 119.64-27.719 19.559-58.922 29.641-92.28 35.879-72.239 13.68-142.8 6.96-212.64-13.801-48.84-14.52-84.36-45.121-106.32-90.84-15.48-32.16-27.603-65.879-29.763-101.64-1.32-21.961 2.16-44.16 4.2-66.238 6.12-65.281 25.32-127.68 45-189.6 10.44-32.879 28.68-63.238 43.68-94.559 4.574-9.477 9.976-18.953 14.773-28.074zm411.48 302.28c-.48-21-4.441-43.199-10.078-64.441-18.602-70.199-43.441-138.36-76.32-203.28-16.922-33.48-39.238-63.719-77.398-75.121-26.879-8.04-54.359-15.359-81.961-18.719-22.441-2.64-45.84-.238-68.398 2.52-15.359 1.921-29.641 9.48-39.359 22.8-28.441 38.88-55.32 79.078-73.801 123.84-30.961 75.121-47.641 153.96-58.078 234.24-1.8 13.922-4.8 28.078-3.84 41.88 3 42.719 14.16 83.52 38.04 119.28 19.198 28.8 44.64 50.398 80.038 59.28 27.961 6.961 56.04 12 84.602 16.078 32.04 4.56 63.48 4.56 94.922.36 60.961-8.16 110.76-35.88 145.32-87.961 34.074-51.23 47.754-109.91 46.312-170.75zm-396.84-324c9-11.641 16.559-20.641 23.16-30.238 2.281-3.36 3.36-8.281 3-12.359-1.8-22.559-9.719-42.238-30.84-53.16-18.48-9.602-38.398-15.48-59.641-13.801-54.719 4.32-98.641 31.559-134.52 70.078-32.039 34.32-53.52 77.16-67.441 121.44-18.961 60.359-45.238 119.04-50.762 183.24-.121 1.441-7.922 54-6.238 78.84 1.441 20.52 13.32 37.078 33.238 43.078 18.359 5.52 37.32 2.16 50.762-13.68 26.879-31.559 45.602-67.68 52.44-108.6 5.16-31.32 5.762-63.359 9.481-94.922 3.48-28.559 7.078-57.238 13.078-85.441 6.719-31.32 22.441-57.48 50.04-75.84 35.761-23.633 71.882-40.191 114.24-8.633zm280.32-26.637c12 12.238 40.68 41.762 40.68 41.762s34.922-8.398 44.281-10.199c26.52-5.16 51.84 3 75.961 10.922 13.801 4.559 27.602 15.719 36.238 27.602 19.199 26.398 27.359 57.719 24.602 90.121-2.04 24.121-8.04 48.121-13.801 71.762-8.281 33.719 2.04 60.602 25.922 84.48 31.801 31.68 65.52 25.32 89.039-.48 3.238-3.602 8.64-17.398 9.719-22.32 10.32-50.88 6.601-102.12-4.2-151.92-8.398-38.762-24.84-75.84-37.44-113.76-7.922-23.88-22.68-43.32-40.801-59.88-39-35.761-84.961-53.28-138.24-47.878-51.48 5.273-91.32 27.59-111.96 79.793z"/>
<path d="M600.24 845.4c-29.281 1.2-56.879-7.32-77.281-34.078-20.398-26.879-19.922-75.719 2.52-100.92 4.8-5.398 11.28-9.48 17.762-12.961 9.84-5.398 38.52-12.719 73.68-6.36 24 7.32 39.359 10.442 53.64 31.56 11.04 16.559 11.642 50.039 4.32 74.398-4.437 14.766-41.276 50.887-74.64 48.363zm-57-112.68c-11.52 23.879-9.96 52.199 9 71.641 12.121 12.359 27.84 12.961 42.961 14.879l1.2.121c50.16 6.36 80.397-56.879 42-89.762a96.885 96.885 0 0 0-13.2-9.48c-10.68-6.36-29.64-8.641-41.879-6.36-12.359 2.524-32.52 3.242-40.082 18.961zM639.24 481.2c7.8-10.559 36.121-11.16 47.641-3.719 20.16 13.078 29.52 35.04 24.48 57.121-4.8 21-19.68 34.801-37.32 34.68-21.602-.238-41.762-17.16-45-38.16-.84-5.039-1.32-10.32-1.32-21.719-.117-12.363 4.562-18.723 11.52-28.203zm15.363 44.402c2.64 11.16 17.398 13.801 23.398 4.078 5.762-9.36 6.96-20.16 1.68-28.199-2.64-3.96-9.84-7.32-14.398-6.719-4.078.48-9.961 6.239-10.922 10.56-1.438 6.718-1.32 13.558.242 20.28zM474 481.2c7.8-10.559 36.121-11.16 47.641-3.719 20.16 13.078 29.52 35.04 24.48 57.121-4.8 21-19.68 34.801-37.32 34.68-21.602-.238-41.762-17.16-45-38.16-.84-5.039-1.32-10.32-1.32-21.719-.121-12.363 4.558-18.723 11.52-28.203zm15.359 44.402c2.64 11.16 17.398 13.801 23.52 4.078 5.762-9.36 6.96-20.16 1.68-28.199-2.64-3.96-9.84-7.32-14.398-6.719-4.078.48-9.961 6.239-10.922 10.56-1.438 6.718-1.438 13.558.12 20.28z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

4
public/icons/trgovine.svg Executable file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M227.64 575.52c-9.48 9.238-18.719 18.602-28.32 27.48-12.48 11.52-25.199 22.68-38.039 33.84-3.36 2.879-7.078 5.398-11.039 7.32-11.52 5.64-23.398 10.68-35.398 1.559-12.48-9.48-16.078-22.32-12.602-37.441 4.2-18.238 12-34.2 24.121-49.078 49.559-60.961 108.6-112.56 163.92-167.76 36-35.88 73.801-70.078 110.52-105.36 45.719-43.922 91.441-88.078 136.8-132.48 14.16-13.922 26.641-29.641 40.32-44.04 16.68-17.64 28.078-17.52 47.879-2.519 61.922 47.16 114.6 104.04 167.76 160.44 78.359 83.281 158.16 165.36 236.04 249 24.602 26.398 45.48 56.04 67.801 84.48 4.078 5.16 6.719 11.398 9.719 17.398 5.879 11.52 5.398 21.72-2.762 32.88-15.719 21.48-26.64 24.12-46.922 6.359-18.359-15.961-35.64-33.238-53.039-50.281-6.719-6.602-12.359-14.281-19.8-22.922-9.122 12.602-6.122 23.039-5.161 32.52 5.762 59.52 11.16 119.16 7.441 179.04-1.558 26.398-4.441 52.922-4.441 79.32 0 39.12 2.52 78.238 3.238 117.24.36 18.359-.36 36.84-2.16 55.199-3.121 32.52-25.32 53.64-58.32 54.719-48.48 1.558-97.078 1.558-145.56 2.762-39.719.96-84.121-33.36-86.16-78.84-1.441-32.398-3.96-64.801-7.2-97.2-2.28-22.68-4.921-45.601-10.198-67.68-7.559-31.077-21.72-41.64-53.04-43.8-33.601-2.399-54.48 8.878-66.48 36.238-17.64 40.32-19.44 82.922-18.358 126 .36 15.48.96 30.96.84 46.559-.48 41.762-24.48 68.039-66.121 71.039-15.36 1.078-30.84-.36-46.32-1.2-37.441-1.922-75-4.8-112.44-6-48.121-1.68-79.441-31.44-81.238-83.64-.72-21.36-.121-42.84-.72-64.32-1.32-45.72-4.198-91.442-4.198-137.28 0-48 2.761-96 3.718-144 .602-27.84.122-55.68.122-83.52-1.325-.587-2.766-1.31-4.204-2.028zm378.48-373.44c-7.441 7.441-13.68 13.441-19.68 19.68-22.68 24.121-44.398 49.199-68.16 72.121-39.238 37.922-80.52 73.801-119.64 111.84-45.48 44.281-89.52 90-134.16 134.88-5.281 5.281-9.602 9.84-8.398 18.84 2.28 16.68 3.718 33.719 3.718 50.52.121 53.16-1.8 106.44-.718 159.48 1.68 79.68 5.28 159.36 8.28 239.04.24 5.879.84 11.879 2.161 17.641 5.398 25.559 18.121 37.078 44.04 37.32 31.68.238 63.358 2.52 95.16 3.602 18.48.601 36.96 1.199 55.32.48 26.878-1.078 38.16-12.48 39.84-39.84.96-15.48.48-30.96.12-46.44-1.2-45.36 2.16-89.88 18.48-132.84 12.121-32.04 33.48-51.84 67.801-55.56 16.078-1.68 32.88-3.602 48.48-.719 24.238 4.442 47.281 14.88 59.16 38.281 8.52 16.801 16.32 35.281 18.72 53.762 5.038 38.641 6.359 77.88 9.359 116.88.84 11.04 1.558 22.078 3.48 33 3.96 22.441 24.719 41.281 47.398 42.121 41.281 1.442 82.559 2.64 123.84 2.762 36.238.121 50.039-13.32 50.398-49.32.36-30.961-1.8-61.801-2.04-92.762-.237-32.398-.12-64.922 1.079-97.32 2.16-56.762 8.281-113.4 2.762-170.4-3-30.84-3.961-61.922-3.48-92.879.238-13.559-4.079-21.961-13.2-30.602-36-33.84-71.762-68.039-107.04-102.6-63.359-61.922-122.28-128.16-180.48-195-13.684-15.363-27.96-30.004-42.602-45.965zm453 415.08c1.441-1.559 2.879-3.121 4.32-4.68-17.039-21.12-33.12-43.199-51.238-63.238-22.199-24.602-46.559-47.28-69.359-71.52-51.12-54.238-101.76-109.08-152.76-163.44-59.64-63.602-117.72-128.76-184.8-184.68-3.719-3.12-7.8-5.761-12.359-9.238-3.719 4.559-6.48 7.922-9.238 11.281-22.441 27.359-44.16 55.32-67.441 81.961-14.52 16.68-31.078 31.559-46.68 47.16-30.84 30.84-61.199 62.039-92.52 92.281-46.68 45.238-94.68 89.039-140.76 134.76-30.961 30.602-59.879 63.359-89.039 95.641-8.04 8.879-15.84 19.078-14.641 35.641 11.398-9.48 21.48-16.922 30.48-25.559 31.801-30.719 63.121-61.922 94.922-92.762 73.074-70.93 146.28-141.97 219.48-212.77 14.879-14.398 31.199-27.238 45.48-42.121 17.398-18 33.238-37.559 50.039-56.16 5.879-6.602 11.762-13.32 18.48-19.078 12.359-10.441 21.602-8.52 30.602 4.922 4.559 6.719 9.121 13.44 14.52 19.44 52.32 58.079 104.16 116.64 157.56 173.76 39.719 42.603 80.52 84.36 122.88 124.32 36.84 34.68 76.441 66.36 114.84 99.48 9.242 8.036 18.121 16.435 27.242 24.595z"/>
<path d="M506.16 550.08c40.801 3.602 80.281 7.441 120 10.68 15.48 1.2 30.961.96 46.441 1.078 12.359.121 22.559-2.762 30.602-13.922 4.8-6.84 12.961-12.96 20.762-15.602 15.602-5.16 32.281-7.2 45.48 6.602 9.48 9.96 12.48 39.359 3.602 52.559-7.801 11.64-9.239 21.84-4.801 34.922 2.762 8.039 2.52 17.52 1.8 26.28-1.32 16.68-11.878 23.763-27.718 17.52-9.36-3.718-18-9.96-26.04-16.32-6.718-5.398-12.84-9.238-21.84-7.558-33.96 6.48-67.68.238-100.92-4.8-20.64-3.122-42.718-1.802-61.8-14.16-6.961-4.56-15.48-1.923-22.2 4.44-6.359 6.122-13.32 11.642-20.397 17.04-4.078 3.12-8.52 6.36-13.32 7.68-13.922 3.96-29.04 5.878-39.36-6-9.718-11.282-14.878-26.763-8.519-41.282 5.64-12.84 4.559-23.16-.719-35.52-9.718-22.68-.238-45.359 21.48-55.32 17.04-7.8 39.48.84 51.121 19.801 1.907 3.125 3.348 6.364 6.348 11.883zm247.32 8.523c-17.52-3.359-29.16 5.762-39 18.48-6.48 8.399-13.078 15.121-25.441 14.52-55.199-2.761-110.76-3.84-164.64-17.039-16.32-3.96-36.719-4.441-44.281-26.28-.96-2.88-13.68-5.282-17.398-2.641-6.602 4.558-11.16 12.84-14.879 20.28-.602 1.2 7.441 6.962 11.762 10.079 2.281 1.558 5.52 1.8 8.281 2.762 7.442 2.398 9.48 8.28 10.441 15.359 1.078 7.8-2.039 12.359-9 15.719-5.398 2.64-10.078 6.84-15.12 10.32 4.32 3.84 7.558 4.921 9.359 3.718 9.601-6.601 19.922-12.719 27.719-21.12 7.441-8.04 13.8-11.16 24.84-7.923 22.44 6.48 45.238 11.88 68.16 16.68 10.8 2.282 22.078 1.801 32.879 3.602 29.28 4.922 58.199 6.121 86.039-4.441 13.199 11.039 20.52 29.64 43.078 28.922-1.079-13.32-5.282-23.04-15.36-29.398-12.358-7.922-12.84-18.238-8.16-30.238 30.961 1.68 31.082 1.68 30.723-21.36z"/>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

4
public/icons/veterinarji.svg Executable file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M833.76 549.36c-1.559 8.762-3.238 38.398-5.04 47.879-4.558 24.48-14.64 72.602-39.601 107.64-18.36 26.398-39.48 51-60.36 75.359-31.32 36.48-72.237 38.16-115.44 30-67.921-12.719-119.76-53.281-168.12-99.121-15.12-14.281-27.12-31.922-40.8-49.32-1.8-2.281-5.281-1.68-6.238.96-1.922 5.282-4.079 11.16-6.36 16.923-13.8 35.398-24.359 71.762-29.398 109.56-.84 6.602-1.32 16.199 2.52 20.039 30.602 30.84 60.12 63.48 94.199 90.12 44.52 34.923 98.398 46.802 154.56 46.32 22.559-.237 42.602-8.16 58.8-24.48 24.72-24.96 55.2-34.44 89.642-36 27.359-1.198 54.602-5.16 81.84-7.44 9.84-.84 19.8-1.56 29.64-1.56 36.603.24 61.923 28.68 56.282 64.802-.36 2.16-.72 4.32-1.2 6.602-5.878 27.602-34.44 48.238-62.16 42.48-17.16-3.602-29.16-14.762-34.078-32.88-2.64-9.84-3.12-20.16-4.558-32.878-.238-1.922-2.04-3.481-3.961-3.239-30 2.762-60.602 4.442-90.602 9.602-11.641 2.039-23.039 11.398-32.52 19.68-48.48 42.12-106.92 43.44-189.84 10.68-41.879-16.56-79.32-42.48-111-74.641-13.32-13.56-27.84-26.04-42.121-39.121-1.922-1.801-5.04-1.078-5.879 1.441-6.84 19.078-13.078 40.078-22.559 59.52-8.281 17.16-19.68 33.121-31.922 47.762-19.68 23.762-46.199 28.441-74.64 19.68-10.32-3.12-22.2-9.12-27.962-17.52-22.922-33.719-35.879-70.922-23.64-111.96 17.64-58.8 57.84-77.762 117.72-69.48 12.48 1.68 24.601 6.121 38.038 9.602 1.32-4.68 2.879-8.281 3.36-12.121 6-51.84 22.077-101.16 43.921-147.84 28.68-61.32 195.12-366.72 221.76-403.08 28.68-39 69.48-54.121 114.24-48.961 32.762 3.719 66.238 15.602 95.52 31.199 59.88 31.8 113.64 73.44 163.92 119.04 26.16 23.879 45.121 52.199 51 88.32 7.079 44.039-8.039 80.039-45.602 103.68-24.602 15.48-49.922 30.359-79.8 32.398-19.32 1.316-38.642.355-61.56.355zm32.277-35.16c36.48-1.922 69.238-12.961 97.199-37.078 8.281-7.078 15-15.961 18.84-26.16 14.039-36.961 3.121-70.32-23.16-96.48-45.719-45.602-96.961-85.32-153.72-116.16-35.762-19.441-73.199-34.68-116.76-28.199-24.238 3.602-43.32 12.602-57.359 30.961-36.602 57.84-165 295.68-178.44 333.6-14.762 41.879-20.762 78.84 8.762 111.84 22.199 24.84 48.238 44.398 76.078 62.762 31.8 20.879 66.602 27.48 103.08 29.039 21 .96 39.84-5.16 54.602-21 13.199-14.16 25.922-28.68 39-42.84 42-45.961 60.359-86.398 64.8-147.6.602-7.441-1.679-29.879-3.12-37.559-1.078-5.879-4.68-14.398-2.282-16.922 3.48-3.602 11.641-4.2 17.641-3.719 13.68 1.2 27.238 3.239 40.801 5.16 4.563.356 9.364.598 14.043.356zm-544.8 310.44c.602-1.8-.238-3.719-1.922-4.559-39.238-18.359-83.762-10.078-104.88 18.72-19.68 26.761-20.64 56.64-10.32 87.12 1.8 5.16 7.559 10.32 12.72 12.961 20.038 9.72 41.761 3 60-17.039 25.202-27.605 33.362-62.402 44.401-97.203zm544.2 108.48c-9.36 13.078 9.36 29.52 20.879 18.238l.238-.238c2.52-2.52 4.922-5.281 6.84-8.16 9.121-14.04-8.52-28.922-21-17.762-2.637 2.402-4.918 5.039-6.957 7.921z"/>
<path d="M739.68 273.6c38.879-6.602 51.961-.121 76.801 38.281 1.441.602 3.121 1.922 4.32 1.559 41.04-11.641 71.641 31.44 72.238 65.039.121 6.48-1.32 12.96-.36 19.199.962 6.601 2.642 13.8 6.24 19.32 11.761 17.398 6.839 32.879-14.16 36.84-14.88 2.761-30.603 5.28-45.36 3.718-47.879-5.28-96.12-11.64-137.64-38.762-30.96-20.28-55.559-45.96-63.359-84.48-7.8-38.28 11.398-71.762 48.602-82.68 14.762-4.32 26.762 2.16 38.04 10.32 5.16 3.723 9.96 7.922 14.64 11.645zm-22.32 27.477c-8.52-11.52-25.199-15.359-36.602-6.719-.96.719-1.8 1.442-2.52 2.281-13.32 14.88-12.238 45.961.961 63.48 7.559 10.078 17.398 18.961 27.48 26.52 26.04 19.32 57.961 22.801 88.441 28.68 20.04 3.84 40.801 3.84 60.48 5.52 1.2-13.56 2.282-23.762 2.762-33.961.36-7.2.961-14.52 0-21.602-2.039-13.56-9.719-18.48-22.078-12.84-8.52 3.84-15.48 10.922-23.879 17.039-15-3.719-21.12-14.88-23.398-29.281-1.32-8.64.48-18-8.039-25.078-7.441-6.121-18-6.48-26.52-2.04-5.879 3.122-11.879 6.962-19.68 11.399a2722.522 2722.522 0 0 1-17.41-23.398zM720.36 571.32c.121 13.32-1.2 26.762-3.602 39.84-1.8 9.84-3.718 19.441-7.558 28.32-15.961 37.078-49.078 45.238-84.238 45.602-48.121.602-95.52-38.398-103.44-85.922-8.64-51.602 2.52-98.879 42.602-136.32 22.922-20.039 74.879-18.961 93.359-13.199 53.64 16.68 62.398 66.961 62.879 121.68zm-35.52 11.758c0-39.238 4.8-70.922-34.078-89.762-24.238-11.762-51.84-12-70.078 7.441-22.199 23.52-30.961 52.68-30.84 83.762.121 13.68 10.078 35.52 17.879 46.56 16.68 23.397 49.922 25.077 80.641 12.48 30.957-12.48 36.477-25.68 36.477-60.48z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

3
public/icons/vzgoja.svg Executable file
View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M294.48 985.08c-9.36 1.2-20.52 2.762-31.801 4.078-33.121 3.719-67.441-11.039-79.68-35.039-15.961-31.44-12.961-61.8 10.32-88.44 13.801-15.72 28.199-32.16 45.602-43.2 38.879-24.602 66.719-25.559 112.32-8.16 5.04-6.719 79.441-76.078 85.801-84.121 72-91.32 151.32-176.4 226.8-264.72 28.559-33.48 58.32-67.32 66.359-112.92 6.121-35.04 10.922-70.2 15.238-105.48 5.398-44.04 30-76.441 61.922-103.92 18.48-15.84 56.641-13.56 74.762 5.398 22.801 23.88 51.48 45.36 48 86.762 21-7.558 37.199-.96 52.559 8.88 18.359 11.761 32.641 26.878 39.48 48 19.801 60.48 3.84 99.601-52.922 128.52-19.68 10.077-39.719 19.32-59.762 28.558-53.398 24.72-94.078 65.04-135.24 105.72-58.559 57.72-102.24 127.32-155.88 188.88-39.121 44.762-75.961 91.441-114.24 137.04-17.52 20.762-15.84 44.04-11.281 68.398 3.121 16.922 7.68 34.078 7.559 51-.239 44.52-22.801 69-60.121 76.56-48.84 9.96-92.04-3.84-123.72-43.32-10.082-12.704-14.043-30.466-22.082-48.466zm596.4-764.04c.602-27.48-13.32-41.641-29.398-52.078-15.84-10.32-29.16 2.762-41.281 11.762-21.121 15.719-32.762 38.281-37.68 63.121-5.879 30-9.36 60.719-12.48 91.199-3.719 36.961-10.68 72.48-35.762 101.52-45.121 52.441-90.84 104.28-136.08 156.6-39.602 45.84-78.719 92.16-118.68 137.64-30.359 34.559-66.48 63.961-88.078 106.2-9.48 18.602-26.281 21.121-47.52 13.559-5.398-1.922-10.68-4.441-16.199-6.121-43.801-13.32-111 31.199-115.68 76.559-1.8 17.28 3.602 25.32 20.641 28.199 9.36 1.559 19.199 2.281 28.559.96 23.281-3.12 44.039-12.48 61.922-28.44 13.078-11.641 26.039-12.72 35.879-4.559 12 9.84 12.121 20.52.36 38.04-1.56 2.398-3.481 4.558-5.16 6.96-27.239 36.961-18.122 64.32 23.28 76.801.961.238 1.801.602 2.762.961 44.039 14.88 81.12-9.602 81.96-55.559.24-15-3.718-30.238-6.718-45.238-6.602-33.238-5.52-62.039 20.398-90.238 44.88-48.602 85.078-101.64 127.2-152.64 48.238-58.44 90.84-121.56 145.8-174.72 39.48-38.16 77.641-77.52 127.56-102.36 19.801-9.84 39.84-19.199 59.16-30 21.72-12.12 44.52-23.398 53.52-49.8 7.922-23.04.84-48.36-17.879-61.923-16.32-11.762-28.199-10.078-51.84 8.04-5.281 4.077-10.32 8.64-15.238 13.32-6.96 6.6-13.44 13.8-20.762 20.038-13.199 11.281-24.359 7.922-31.32-8.039-4.922-11.398-1.32-19.559 5.879-28.8 15.836-19.563 27.957-41.286 32.875-60.966z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

3
public/icons/zavetisca.svg Executable file
View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1600" viewBox="0 0 1200 1200">
<path d="M649.32 729.72c-11.039 31.801-8.762 67.68 5.281 88.68 11.641-1.078 23.52-3.238 35.398-3.238 16.922 0 28.922-3.48 39.961-19.801 16.2-23.762 43.32-32.641 72.121-30.602 19.801 1.32 32.398 17.52 30.961 38.762-1.32 20.398-5.64 40.199-22.922 52.8 2.762 13.56 7.078 25.923 7.442 38.399 1.32 39.719-28.56 59.28-64.441 41.762-10.922-5.399-19.32-15.84-31.922-26.52-62.641 6-129.84 12.48-199.44 19.078-6.84 25.199-28.801 32.52-54 35.16-44.762 4.68-58.801-23.16-50.88-60.961 2.641-12.72 1.68-26.281-4.8-37.56-8.88-15.718-11.16-33.601.601-49.198 12.961-17.16 31.56-21.238 52.2-16.32 17.878 4.199 33.48 11.762 40.558 30.48 19.922-1.32 38.281-2.52 52.801-3.48 10.68-14.88 18.961-27.36 28.2-39.239 10.921-14.039 21.601-46.68 21.718-62.762-20.762-3.48-251.4-21.84-267.6-26.52-41.64-12.238-60.48-36.359-62.879-80.398-1.554-28.922 6.723-120.96 10.324-138.24 2.641-12.602 3.121-25.559 6.239-37.922 8.52-33.359 27.359-60.602 55.8-79.44 28.2-18.84 72.72-32.399 107.64-37.68 20.399-3.122 77.04-19.079 184.08-16.079 61.079 1.68 161.16 26.641 220.08 42.84 46.56 12.84 75.122 45.238 78.36 96.238 1.078 16.801 3.718 33.602 6.238 50.398 1.078 7.2-2.04 119.64-6.48 140.88-9.602 45.961-20.763 72.72-67.2 88.32-47.762 16.078-91.44 14.16-142.08 8.399-27.117-3.235-54.355-4.313-81.355-6.235zM301.68 555.6c3 24.48 6.238 48.121 8.64 72 2.88 27.84 9.84 37.32 36.84 43.199 22.802 4.922 456.84 35.16 504 19.441 25.68-8.64 36.603-14.762 46.079-39.602 11.52-30.121 15.96-61.559 21.12-95.281-9.238 3.48-16.198 5.64-22.8 8.64-24.602 11.16-50.641 18.962-77.398 22.68-28.2 3.961-55.922 10.2-84.121 14.04-30.238 4.199-60.72 7.441-91.2 10.44-53.52 5.282-106.2-2.16-158.64-11.038-43.558-7.442-87.358-14.16-130.44-23.52-17.757-3.723-34.077-13.441-52.077-21zm607.92-60.121c-1.922-20.398-3.84-37.078-4.922-53.879-2.398-35.879-23.52-54.961-56.52-63.121-31.922-7.922-63.84-16.441-96.12-22.922-31.442-6.36-110.4-18.48-159.96-18.359-159.48.238-213.36 37.922-242.04 73.078-18.239 22.32-28.079 49.441-25.32 81 19.198-6.84 36.237-14.16 54-18.84 76.198-20.398 153.48-30.238 232.44-20.039 19.921 2.64 52.8 5.16 72.84 6.719 75.237 5.762 150.24 13.684 225.6 36.363zm-18.242 29.16c-26.879-5.04-53.16-14.879-80.16-18-77.52-9.121-155.16-18.48-233.04-24-80.641-5.64-158.76 9.96-234.36 38.16-4.8 1.8-9.121 5.281-18.121 10.801 193.08 58.199 379.56 56.52 565.68-6.96zm-446.76 401.4c17.879 2.281 35.039 7.559 47.16-12.48 3.238-5.398 11.52-8.762 18.121-10.801 8.281-2.52 17.281-3 26.039-3.84 54.48-4.8 108.84-11.16 162.24-23.52 11.762-2.762 20.879-1.32 29.762 9.36 7.32 8.761 18.359 15.359 28.922 20.28 13.441 6.239 28.199 1.922 32.281-6.96 4.922-10.801-1.922-20.88-19.199-28.078-.719-.36-1.559-.36-2.398-.48-8.282-1.56-12.36-6.122-12.36-15 0-8.282 3.239-14.04 10.923-16.923 5.28-1.922 10.922-2.52 16.199-4.441 17.039-6 22.559-14.52 22.44-34.078-2.16-.602-4.44-1.801-6.601-1.68-21.238.961-38.281 9.48-51.602 26.762-6.36 8.399-15.602 19.2-24.602 20.281-48.48 5.879-97.32 9.238-146.04 13.32-24 2.04-48 3.238-71.879 5.64-10.922 1.079-17.762-2.878-19.199-13.198-1.922-14.281-11.398-18.36-23.281-19.922-11.398-1.442-22.922-2.64-28.68 11.039 4.559 15.12 15.84 21.12 30.238 24.238 11.762 2.52 17.398 11.039 17.398 22.922 0 12.12-7.559 16.922-18.48 18-11.164 1.199-17.523 6.36-17.402 19.559zm164.28-120.96c-5.281 8.04-8.64 13.199-15.121 22.922 12.48-2.52 19.199-3.84 28.922-5.879-5.398-6.723-8.16-10.082-13.801-17.043z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,46 +0,0 @@
@import "leaflet/dist/leaflet.css";
@import "leaflet.markercluster/dist/MarkerCluster.css";
@import "leaflet.markercluster/dist/MarkerCluster.Default.css";
/*:root {*/
/* --background: #ffffff;*/
/* --foreground: #171717;*/
/*}*/
/*@media (prefers-color-scheme: dark) {*/
/* :root {*/
/* --background: #0a0a0a;*/
/* --foreground: #ededed;*/
/* }*/
/*}*/
/*html,*/
/*body {*/
/* max-width: 100vw;*/
/* overflow-x: hidden;*/
/*}*/
/*body {*/
/* color: var(--foreground);*/
/* background: var(--background);*/
/* font-family: Arial, Helvetica, sans-serif;*/
/* -webkit-font-smoothing: antialiased;*/
/* -moz-osx-font-smoothing: grayscale;*/
/*}*/
/** {*/
/* box-sizing: border-box;*/
/* padding: 0;*/
/* margin: 0;*/
/*}*/
/*a {*/
/* color: inherit;*/
/* text-decoration: none;*/
/*}*/
/*@media (prefers-color-scheme: dark) {*/
/* html {*/
/* color-scheme: dark;*/
/* }*/
/*}*/

View File

@@ -1,7 +1,8 @@
import type {Metadata} from "next"; import type {Metadata} from "next";
import {Geist, Geist_Mono} from "next/font/google"; import {Geist, Geist_Mono} from "next/font/google";
import 'leaflet/dist/leaflet.css';
import "./globals.css"; import "./globals.css";
import {Provider} from "@/components/ui/provider" import {Provider} from "@/components/ui/provider";
const geistSans = Geist({ const geistSans = Geist({
variable: "--font-geist-sans", variable: "--font-geist-sans",

View File

@@ -1,23 +1,14 @@
import Image from "next/image";
import styles from "./page.module.css"; import styles from "./page.module.css";
import { Container, Heading } from "@chakra-ui/react"
import Header from "@/components/Header"; import Header from "@/components/Header";
import HeroBanner from "@/components/HeroBanner"; import HeroBanner from "@/components/HeroBanner";
import CompaniesExplorer from "@/components/Map/CompaniesExplorer.tsx"; import ListingsMap from "@/components/Map/ListingsMap";
import type { Company } from "@/components/Map/CompanyMap.tsx";
import Articles from "@/components/Articles"; import Articles from "@/components/Articles";
import Calendar from "@/components/Calendar"; import Calendar from "@/components/Calendar";
import Sponsor from "@/components/Sponsor"; import Sponsor from "@/components/Sponsor";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
const seed: Company[] = [
{ id: "1", name: "ByteForge", industry: "Tech", lat: 46.0569, lng: 14.5058, address: "Ljubljana" },
{ id: "2", name: "GreenPlate", industry: "Food", lat: 46.2389, lng: 15.2675, address: "Celje" },
{ id: "3", name: "Medicus+", industry: "Healthcare", lat: 46.5547, lng: 15.6459, address: "Maribor" },
{ id: "4", name: "ShopNook", industry: "Retail", lat: 45.5481, lng: 13.7302, address: "Koper" },
{ id: "5", name: "Steelworks d.o.o.", industry: "Manufacturing", lat: 46.2396, lng: 14.3556, address: "Kranj" },
{ id: "6", name: "CloudLynx", industry: "Tech", lat: 46.3607, lng: 14.0888, address: "Škofja Loka" },
];
export default function Home() { export default function Home() {
return ( return (
@@ -26,8 +17,8 @@ export default function Home() {
<Header/> <Header/>
</header> </header>
<main className={styles.main}> <main className={styles.main}>
<HeroBanner/> <HeroBanner />
<CompaniesExplorer companies={seed} /> <ListingsMap />
<Articles /> <Articles />
<Sponsor /> <Sponsor />
<Calendar initialDate={new Date()} /> <Calendar initialDate={new Date()} />

View File

@@ -3,7 +3,11 @@ import { Container, Button, Card, Heading, Image, Text, SimpleGrid, GridItem } f
export default async function Articles() { export default async function Articles() {
const supabase = await createClient(); const supabase = await createClient();
const { data: articles } = await supabase.from("articles").select().order("published_at", {ascending: false}).limit(8); const {data: articles} = await supabase
.from("articles")
.select()
.order("published_at", {ascending: false})
.limit(8);
return ( return (
<Container> <Container>

View File

@@ -1,5 +1,6 @@
import {Box, Flex, Button, HStack, Wrap, Link, Text, Heading} from "@chakra-ui/react"; import {Box, Flex, Button, HStack, Wrap, Link, Text, Heading} from "@chakra-ui/react";
import NextLink from "next/link"; import NextLink from "next/link";
import Image from 'next/image'
import {RiArrowRightLine, RiMailLine} from "react-icons/ri" import {RiArrowRightLine, RiMailLine} from "react-icons/ri"
import {MENU_ITEMS} from "../lib/constants"; import {MENU_ITEMS} from "../lib/constants";
@@ -47,7 +48,13 @@ export default function Banner() {
variant="solid" variant="solid"
asChild asChild
> >
<a href={item.href}><RiMailLine/> {item.label}</a> <a href={item.href}>
<Image
src={item.icon}
alt={item.label}
width={100}
height={100}
/><RiMailLine/> {item.label}</a>
</Button> </Button>
))} ))}
</Wrap> </Wrap>

View File

View File

@@ -1,147 +0,0 @@
"use client";
import { Box, Flex, Heading, HStack, Input, Stack, Text, Badge } from "@chakra-ui/react";
import { useMemo, useState } from "react";
import dynamic from "next/dynamic";
import type { Company } from "./CompanyMap";
// dynamic import to avoid SSR issues
const CompanyMap = dynamic(() => import("./CompanyMap"), { ssr: false });
export type CompaniesExplorerProps = {
companies: Company[];
industries?: Array<Company["industry"]>;
initialIndustry?: Company["industry"] | "All";
showAutoFit?: boolean;
};
const defaultIndustries: Array<Company["industry"]> = [
"Tech",
"Retail",
"Manufacturing",
"Food",
"Healthcare",
];
export default function CompaniesExplorer({
companies,
industries = defaultIndustries,
initialIndustry = "All",
showAutoFit = true,
}: CompaniesExplorerProps) {
const [query, setQuery] = useState("");
const [industry, setIndustry] = useState<string>(initialIndustry);
const [selectedId, setSelectedId] = useState<string | null>(null);
const filtered = useMemo(() => {
const q = query.trim().toLowerCase();
return companies.filter((c) => {
const matchesQ =
!q ||
c.name.toLowerCase().includes(q) ||
(c.address?.toLowerCase().includes(q) ?? false);
const matchesInd = industry === "All" || c.industry === industry;
return matchesQ && matchesInd;
});
}, [companies, query, industry]);
const selected = useMemo(
() => filtered.find((c) => c.id === selectedId),
[filtered, selectedId]
);
return (
<Flex h="100dvh" w="100%" p={4} gap={4} wrap={{ base: "wrap", lg: "nowrap" }}>
{/* Left panel */}
<Box
w={{ base: "100%", lg: "35%" }}
h={{ base: "48dvh", lg: "100%" }}
borderRadius="2xl"
p={4}
bg="white"
boxShadow="sm"
overflow="hidden"
>
<HStack justify="space-between" mb={3}>
<Heading size="md">Companies</Heading>
</HStack>
<HStack mb={3} spacing={2}>
<Input
placeholder="Search by name or city..."
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
<Box as="select"
value={industry}
onChange={(e) => setIndustry(e.target.value)}
maxW="44"
borderWidth="1px"
borderRadius="md"
px={3}
py={2}
>
<option value="All">All</option>
{industries.map((i) => (
<option key={i} value={i}>{i}</option>
))}
</Box>
</HStack>
<Box overflowY="auto" h={{ base: "calc(48dvh - 120px)", lg: "calc(100% - 120px)" }} pr={2}>
<Stack spacing={2}>
{filtered.map((c) => {
const active = c.id === selectedId;
return (
<Box
key={c.id}
p={3}
borderRadius="xl"
borderWidth={active ? "2px" : "1px"}
borderColor={active ? "blue.400" : "gray.200"}
bg={active ? "blue.50" : "transparent"}
cursor="pointer"
onClick={() => setSelectedId(c.id)}
_hover={{ borderColor: "blue.300" }}
>
<HStack justify="space-between" align="start">
<Stack spacing={0}>
<Text fontWeight="semibold">{c.name}</Text>
{c.address && (
<Text fontSize="sm" color="gray.500">
{c.address}
</Text>
)}
</Stack>
<Badge>{c.industry}</Badge>
</HStack>
</Box>
);
})}
{filtered.length === 0 && (
<Text color="gray.500" textAlign="center" mt={6}>
No companies match your filters.
</Text>
)}
</Stack>
</Box>
</Box>
{/* Right panel */}
<Box
flex="1"
h={{ base: "48dvh", lg: "100%" }}
borderRadius="2xl"
overflow="hidden"
boxShadow="sm"
>
<CompanyMap
companies={filtered}
selectedId={selected?.id ?? null}
onSelect={(id) => setSelectedId(id)}
autoFit={showAutoFit}
/>
</Box>
</Flex>
);
}

View File

@@ -1,151 +0,0 @@
"use client";
import { Box, Badge, Flex, Text } from "@chakra-ui/react";
import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
import L, { DivIcon, LatLngBoundsLiteral } from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
import MarkerClusterGroup from "react-leaflet-markercluster";
import { useEffect, useMemo } from "react";
export type Company = {
id: string;
name: string;
industry: "Tech" | "Retail" | "Manufacturing" | "Food" | "Healthcare";
lat: number;
lng: number;
address?: string;
};
type Props = {
companies: Company[];
selectedId?: string | null;
onSelect?: (id: string) => void;
autoFit?: boolean;
};
const industryEmoji: Record<Company["industry"], string> = {
Tech: "💻",
Retail: "🛒",
Manufacturing: "🏭",
Food: "🍽️",
Healthcare: "🏥",
};
const industryColor: Record<Company["industry"], string> = {
Tech: "#3b82f6",
Retail: "#f59e0b",
Manufacturing: "#6b7280",
Food: "#10b981",
Healthcare: "#ef4444",
};
function makeIcon(industry: Company["industry"], highlighted: boolean): DivIcon {
const size = highlighted ? 40 : 32;
const color = industryColor[industry];
const emoji = industryEmoji[industry];
const border = highlighted ? `3px solid ${color}` : `2px solid ${color}`;
return L.divIcon({
className: "company-div-icon",
html: `
<div style="
width:${size}px;height:${size}px;border-radius:50%;
display:flex;align-items:center;justify-content:center;
background:#fff;border:${border};
box-shadow:0 2px 8px rgba(0,0,0,.15);
font-size:${Math.round(size * 0.55)}px;
">${emoji}</div>
`,
iconSize: [size, size],
iconAnchor: [size / 2, size / 2],
popupAnchor: [0, -size / 2],
});
}
function FlyTo({ lat, lng }: { lat: number; lng: number }) {
const map = useMap();
useEffect(() => {
map.flyTo([lat, lng], Math.max(map.getZoom(), 13), { duration: 0.7 });
}, [lat, lng, map]);
return null;
}
function FitBoundsOnData({ points }: { points: { lat: number; lng: number }[] }) {
const map = useMap();
useEffect(() => {
if (!points?.length) return;
let bounds: LatLngBoundsLiteral = [
[points[0].lat, points[0].lng],
[points[0].lat, points[0].lng],
];
for (const p of points) {
bounds = L.latLngBounds(bounds).extend([p.lat, p.lng]) as any;
}
map.fitBounds(bounds, { padding: [30, 30] });
}, [points, map]);
return null;
}
export default function CompanyMap({ companies, selectedId, onSelect, autoFit = true }: Props) {
const selected = useMemo(
() => companies.find((c) => c.id === selectedId),
[companies, selectedId]
);
const center = useMemo<[number, number]>(() => {
if (!companies.length) return [46.0569, 14.5058]; // Ljubljana fallback
const lat = companies.reduce((a, c) => a + c.lat, 0) / companies.length;
const lng = companies.reduce((a, c) => a + c.lng, 0) / companies.length;
return [lat, lng];
}, [companies]);
return (
<Box w="100%" h="100%" borderRadius="2xl" overflow="hidden" bg="white">
<MapContainer
center={center}
zoom={6}
style={{ width: "100%", height: "100%" }}
preferCanvas
>
<TileLayer
attribution="&copy; OpenStreetMap"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MarkerClusterGroup chunkedLoading>
{companies.map((c) => (
<Marker
key={c.id}
position={[c.lat, c.lng]}
icon={makeIcon(c.industry, c.id === selectedId)}
eventHandlers={{
click: () => onSelect?.(c.id),
mouseover: (e) => e.target.openPopup(),
}}
>
<Popup>
<Flex direction="column" gap={1}>
<Text fontWeight="bold">{c.name}</Text>
<Badge
w="fit-content"
colorScheme="gray"
style={{ background: industryColor[c.industry], color: "#fff" }}
>
{c.industry}
</Badge>
{c.address && <Text fontSize="sm">{c.address}</Text>}
</Flex>
</Popup>
</Marker>
))}
</MarkerClusterGroup>
{autoFit && companies.length > 0 && !selected && (
<FitBoundsOnData points={companies.map(({ lat, lng }) => ({ lat, lng }))} />
)}
{selected && <FlyTo lat={selected.lat} lng={selected.lng} />}
</MapContainer>
</Box>
);
}

View File

@@ -0,0 +1,32 @@
import { Container, Stack, Box, HStack, Button, Card, Heading, Image, Text, SimpleGrid, GridItem } from "@chakra-ui/react";
import ServicesList from "./ServicesList";
import MapWrapper from "./MapWrapper";
export default function ListingsMap() {
return (
<Container maxW="full" px={4}>
<Stack direction={{base: "column", md: "row"}} gap="5" h="80vh">
<Box p="2"
borderWidth="1px"
borderColor="border.disabled"
color="fg.disabled"
w={{base: "100%", md: "50%"}}
h="full"
>
<ServicesList />
</Box>
<Box p="2"
borderWidth="1px"
borderColor="border.disabled"
color="fg.disabled"
w={{base: "100%", md: "50%"}}
h="full"
>
<MapWrapper />
</Box>
</Stack>
</Container>
)
}

252
src/components/Map/Map.tsx Normal file
View File

@@ -0,0 +1,252 @@
"use client";
import { MapContainer, TileLayer, Marker, Popup, useMapEvents } from "react-leaflet";
import { useEffect, useState, useCallback } from "react";
import L from "leaflet";
import markerIcon2x from "leaflet/dist/images/marker-icon-2x.png";
import markerIcon from "leaflet/dist/images/marker-icon.png";
import markerShadow from "leaflet/dist/images/marker-shadow.png";
import { createClient } from "@/utils/supabase/client";
const DefaultIcon = L.icon({
iconRetinaUrl: (markerIcon2x as unknown as { src: string }).src || (markerIcon2x as unknown as string),
iconUrl: (markerIcon as unknown as { src: string }).src || (markerIcon as unknown as string),
shadowUrl: (markerShadow as unknown as { src: string }).src || (markerShadow as unknown as string),
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41],
});
L.Marker.prototype.options.icon = DefaultIcon;
interface ServiceProvider {
id: string;
name: string;
address: string;
category: string;
phone?: string;
email?: string;
website?: string;
latitude?: number;
longitude?: number;
}
interface MapBounds {
north: number;
south: number;
east: number;
west: number;
}
function MapBoundsTracker({
onBoundsChange,
userLocation
}: {
onBoundsChange: (bounds: MapBounds) => void;
userLocation?: { lat: number; lng: number } | null;
}) {
const map = useMapEvents({
moveend: () => {
const bounds = map.getBounds();
onBoundsChange({
north: bounds.getNorth(),
south: bounds.getSouth(),
east: bounds.getEast(),
west: bounds.getWest()
});
},
zoomend: () => {
const bounds = map.getBounds();
onBoundsChange({
north: bounds.getNorth(),
south: bounds.getSouth(),
east: bounds.getEast(),
west: bounds.getWest()
});
}
});
// Center map on user location when it becomes available
useEffect(() => {
if (userLocation && map) {
console.log("🎯 Centering map on user location:", userLocation);
map.setView([userLocation.lat, userLocation.lng], 13);
}
}, [userLocation, map]);
return null;
}
export default function Map(props: any) {
const [visibleProviders, setVisibleProviders] = useState<ServiceProvider[]>([]);
const [loading, setLoading] = useState(false);
const [userLocation, setUserLocation] = useState<{ lat: number; lng: number } | null>(null);
const [mapCenter, setMapCenter] = useState<[number, number]>([46.1512, 14.9955]); // Default to Slovenia center
const [locationPermissionRequested, setLocationPermissionRequested] = useState(false);
const fetchProvidersInBounds = useCallback(async (bounds: MapBounds) => {
console.log("🗺️ Fetching providers for bounds:", bounds);
setLoading(true);
try {
const supabase = createClient();
// Fetch all providers with coordinates, then filter by bounds
const { data: allProviders, error } = await supabase
.from("service_providers")
.select("*");
console.log("🔍 Supabase query result:", { data: allProviders?.length, error });
if (error) {
console.error("❌ Supabase error:", error);
setVisibleProviders([]);
return;
}
// Filter to only providers with coordinates
const providersWithCoords = allProviders?.filter(provider =>
provider.latitude != null && provider.longitude != null
) || [];
console.log("📊 Total providers with coordinates:", providersWithCoords?.length);
// Filter by bounds on the client side for now
const serviceProviders = providersWithCoords?.filter(provider =>
provider.latitude >= bounds.south &&
provider.latitude <= bounds.north &&
provider.longitude >= bounds.west &&
provider.longitude <= bounds.east
) || [];
console.log("📊 Providers in bounds:", serviceProviders?.length);
setVisibleProviders(serviceProviders);
} catch (error) {
console.error("Error fetching providers:", error);
setVisibleProviders([]);
} finally {
setLoading(false);
}
}, []);
const handleBoundsChange = useCallback((bounds: MapBounds) => {
fetchProvidersInBounds(bounds);
}, [fetchProvidersInBounds]);
// Request user location on component mount
useEffect(() => {
if (!locationPermissionRequested && navigator.geolocation) {
setLocationPermissionRequested(true);
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude } = position.coords;
console.log("📍 User location detected:", { latitude, longitude });
const userLoc = { lat: latitude, lng: longitude };
setUserLocation(userLoc);
setMapCenter([latitude, longitude]);
// Fetch providers around user location (wider area)
const userBounds: MapBounds = {
north: latitude + 2.0,
south: latitude - 2.0,
east: longitude + 2.0,
west: longitude - 2.0
};
console.log("👤 User location bounds:", userBounds);
fetchProvidersInBounds(userBounds);
},
(error) => {
console.warn("Geolocation error:", error.message);
// Fall back to Slovenia bounds
const sloveniaInitialBounds: MapBounds = {
north: 46.9,
south: 45.4,
east: 16.6,
west: 13.4
};
fetchProvidersInBounds(sloveniaInitialBounds);
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 300000 // 5 minutes
}
);
}
}, [locationPermissionRequested, fetchProvidersInBounds, setUserLocation, setMapCenter, setLocationPermissionRequested]);
return (
<MapContainer
center={mapCenter}
zoom={8}
scrollWheelZoom={true}
style={{width: "100%", height: "100%"}}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MapBoundsTracker onBoundsChange={handleBoundsChange} userLocation={userLocation} />
{/* User location marker */}
{userLocation && (
<Marker position={[userLocation.lat, userLocation.lng]}>
<Popup>
<div>
<h3 style={{ margin: "0 0 8px 0", fontSize: "14px", fontWeight: "bold" }}>
📍 Your Location
</h3>
<p style={{ margin: "0", fontSize: "12px" }}>
You are here
</p>
</div>
</Popup>
</Marker>
)}
{!loading && visibleProviders.map((provider: ServiceProvider) => {
if (provider.latitude && provider.longitude) {
return (
<Marker
key={provider.id}
position={[provider.latitude, provider.longitude]}
>
<Popup>
<div>
<h3 style={{ margin: "0 0 8px 0", fontSize: "14px", fontWeight: "bold" }}>
{provider.name}
</h3>
{provider.category && (
<p style={{ margin: "0 0 4px 0", fontSize: "12px", color: "#666" }}>
{provider.category}
</p>
)}
{provider.address && (
<p style={{ margin: "0 0 8px 0", fontSize: "12px" }}>
📍 {provider.address}
</p>
)}
{provider.phone && (
<p style={{ margin: "0 0 4px 0", fontSize: "12px" }}>
📞 <a href={`tel:${provider.phone}`}>{provider.phone}</a>
</p>
)}
{provider.website && (
<p style={{ margin: "0", fontSize: "12px" }}>
🌐 <a href={provider.website} target="_blank" rel="noopener noreferrer">
Website
</a>
</p>
)}
</div>
</Popup>
</Marker>
);
}
return null;
})}
</MapContainer>
)
}

View File

@@ -0,0 +1,15 @@
"use client";
import dynamic from "next/dynamic";
import { Container, Stack, Box, HStack, Button, Card, Heading, Image, Text, SimpleGrid, GridItem } from "@chakra-ui/react";
const Map = dynamic(() => import("./Map"), {
ssr: false,
});
export default function MapWrapper() {
return (
<Map />
)
}

View File

@@ -0,0 +1,125 @@
import { Box, Heading, Text, Stack, VStack, HStack, Badge, Link } from "@chakra-ui/react";
import { FiPhone, FiMail, FiMapPin, FiExternalLink } from "react-icons/fi";
import { createClient } from '@/utils/supabase/server';
export default async function ServicesList() {
const supabase = await createClient();
const { data:providers } = await supabase.from("service_providers").select();
return (
<VStack align="stretch" gap={4} h="full">
<Box position="sticky" top={0} bg="white" zIndex={1} pb={2}>
<Heading as="h3" size="lg" color="gray.800">
Service Providers ({providers?.length || 0})
</Heading>
</Box>
{providers?.length === 0 ? (
<Text color="gray.500">Ni vsebin</Text>
) : (
<Box
flex="1"
overflowY="auto"
h="full"
pr={2}
css={{
'&::-webkit-scrollbar': {
width: '6px',
},
'&::-webkit-scrollbar-track': {
background: '#f1f1f1',
borderRadius: '3px',
},
'&::-webkit-scrollbar-thumb': {
background: '#c1c1c1',
borderRadius: '3px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: '#a8a8a8',
},
}}
>
<Stack gap={3}>
{providers?.map((provider) => (
<Box
key={provider.id}
p={3}
borderWidth="1px"
borderColor="gray.200"
borderRadius="md"
bg="white"
shadow="sm"
_hover={{
shadow: "md",
borderColor: "blue.300"
}}
transition="all 0.2s"
cursor="pointer"
>
<VStack align="start" gap={1.5}>
<HStack justify="space-between" w="full">
<Heading
as="h4"
size="sm"
color="gray.800"
truncate
maxW="60%"
>
{provider.name}
</Heading>
{provider.category && (
<Badge colorScheme="blue" variant="subtle" fontSize="xs">
{provider.category}
</Badge>
)}
</HStack>
{provider.address && (
<HStack color="gray.600" fontSize="xs" gap={1}>
<FiMapPin size={12} />
<Text truncate>{provider.address}</Text>
</HStack>
)}
<HStack gap={3} fontSize="xs" flexWrap="wrap">
{provider.phone && (
<HStack color="gray.600" gap={1}>
<FiPhone size={10} />
<Link href={`tel:${provider.phone}`} color="blue.500">
{provider.phone}
</Link>
</HStack>
)}
{provider.email && (
<HStack color="gray.600" gap={1}>
<FiMail size={10} />
<Link href={`mailto:${provider.email}`} color="blue.500">
Email
</Link>
</HStack>
)}
{provider.website && (
<HStack color="gray.600" gap={1}>
<FiExternalLink size={10} />
<Link
href={provider.website}
color="blue.500"
target="_blank"
rel="noopener noreferrer"
>
Website
</Link>
</HStack>
)}
</HStack>
</VStack>
</Box>
))}
</Stack>
</Box>
)}
</VStack>
)
}

View File

@@ -1,42 +1,42 @@
export const MENU_ITEMS = [ export const MENU_ITEMS = [
{ {
label: "Veterinarji", label: "Veterinarji",
icon: "", icon: "icons/veterinarji.svg",
href: "/veterinarji" href: "/veterinarji"
}, },
{ {
label: "Trgovine", label: "Trgovine",
icon: "", icon: "icons/trgovine.svg",
href: "/trgovine" href: "/trgovine"
}, },
{ {
label: "Vzgoja", label: "Vzgoja",
icon: "", icon: "icons/vzgoja.svg",
href: "/vzgoja" href: "/vzgoja"
}, },
{ {
label: "Varstvo in sprehajanje", label: "Varstvo in sprehajanje",
icon: "", icon: "icons/varstvo-in-sprehajanje.svg",
href: "/varstvo-in-sprehajanje" href: "/varstvo-in-sprehajanje"
},{ },{
label: "Frizerji", label: "Frizerji",
icon: "", icon: "icons/frizerji.svg",
href: "/frizerji" href: "/frizerji"
},{ },{
label: "Društva", label: "Društva",
icon: "", icon: "icons/drustva.svg",
href: "/drustva" href: "/drustva"
},{ },{
label: "Rejci živali", label: "Rejci živali",
icon: "", icon: "icons/rejci-zivali.svg",
href: "/rejci-zivali" href: "/rejci-zivali"
},{ },{
label: "Zavetišča", label: "Zavetišča",
icon: "", icon: "icons/zavetisca.svg",
href: "/zavetisca" href: "/zavetisca"
},{ },{
label: "Ostalo", label: "Ostalo",
icon: "", icon: "icons/ostalo.svg",
href: "/ostalo" href: "/ostalo"
}, },
] ]