44 Commits

Author SHA1 Message Date
78f0e80136 First tries on using tags 2020-08-27 15:46:45 +02:00
c84be34a37 Place delete, more abstraction for ISPlaceSubmitter and more messages 2020-08-27 10:31:14 +02:00
3959096c95 Place delete 2020-08-27 10:30:50 +02:00
76daa71217 Sign up link in login template 2020-08-27 10:30:36 +02:00
0707d2d51e Icons and icon template tag 2020-08-27 09:06:24 +02:00
d45724b774 Will show x for deleting when allowed 2020-08-26 21:59:21 +02:00
c8e46d42ee Relabeling 2020-08-26 21:36:37 +02:00
591469799f Photoalbums can now be linked by users 2020-08-26 21:36:10 +02:00
3cd44959b1 Config mistake 2020-08-26 21:24:08 +02:00
ffef52269a SVG Icons as a dependency 2020-08-26 19:31:06 +02:00
9a30ced90c Calculates correct map_center for paginated place_list. 2020-08-22 09:58:57 +02:00
d44bf0c0f2 Customized PlaceListView to provide data for map rendering. 2020-08-22 09:24:50 +02:00
cad53c070c Added map to place_list, but place_center_map is still a bit off. 2020-08-22 09:23:12 +02:00
a0627761a7 Fixed indentation again. Because I'm stupid ;-) 2020-08-22 09:22:20 +02:00
04940a0901 Added ol.css.map to static files and noted it down in linklist. 2020-08-22 09:19:50 +02:00
3ef31eda0f Added OSM map to place_detail view and template. 2020-08-22 09:19:01 +02:00
7cb8bc6bac Added place_list sorting to sort by name. 2020-08-22 02:59:04 +02:00
636bb880c1 Removed debug output. 2020-08-21 20:38:52 +02:00
c9d9ca9de0 Indentation fixed to 4 spaces. 2020-08-21 20:38:05 +02:00
5f3be5fc83 Pointed template to new location of static map files. 2020-08-21 10:33:56 +02:00
f916ac9742 Removed obsolete include of static files function. 2020-08-21 10:33:33 +02:00
03af8a0c02 Made the center of the map consider only shown places (dynamic). 2020-08-21 10:31:30 +02:00
65f3642272 Added note to where these files were pulled from. 2020-08-21 10:30:17 +02:00
e00a0f687b Moved static osm_map files to subfolder. 2020-08-21 10:29:59 +02:00
9af55d3f24 Made place urls dynamic, changed zoom level. Works so far - but div is still 0px high :P. 2020-08-20 23:49:16 +02:00
719e75a449 Reverted to paginate by 5 in place_list. 2020-08-20 23:33:33 +02:00
6688536a78 Revert "Reverted to paginate by 5 in place_list."
This reverts commit 7835ddcf16.
2020-08-20 23:32:52 +02:00
7835ddcf16 Reverted to paginate by 5 in place_list. 2020-08-20 23:32:27 +02:00
3caada8f08 Moved additional headers to parent template. 2020-08-20 23:07:52 +02:00
4113811c5f Added and included ol.css. 2020-08-20 22:46:56 +02:00
a660763ea4 Corrected map_center_coords variables. 2020-08-20 22:08:35 +02:00
55fe79b82c Added missing ol.js.map. 2020-08-20 22:02:47 +02:00
b34e88a3ad Formatting. 2020-08-20 21:50:00 +02:00
f52dd733d8 Inluded ol.js. 2020-08-20 21:47:44 +02:00
ff428beaef Added ol.js for map rendering. 2020-08-20 21:44:05 +02:00
e8c4faff8e Minor corrections. 2020-08-20 21:38:35 +02:00
0b0a401486 Added export of place coords to home conext. 2020-08-20 21:38:01 +02:00
2b56eed759 Added OSM map partial, Place model function and added it to home. 2020-08-20 21:37:27 +02:00
e387091da6 Removed obsoleted JS. 2020-08-20 21:07:39 +02:00
5c5ad9502c Updated dependencies 2020-08-18 14:35:13 +02:00
baf3f54e1a Again 2020-08-18 14:24:29 +02:00
8cb7e61274 Fixed formatting 2020-08-18 14:24:08 +02:00
fa1274c595 Merge branch 'master' of mowoe.com:reverend/lostplaces-backend into master 2020-08-18 14:22:35 +02:00
a5839c2c36 Added installation instructions 2020-08-18 14:22:33 +02:00
29 changed files with 1856 additions and 195 deletions

View File

@@ -11,6 +11,7 @@ django = "*"
easy-thumbnails = "*"
image = "*"
django-widget-tweaks = "*"
django-svg-icons = "*"
# Commented out to not explicitly specify Python 3 subversion.
# [requires]

View File

@@ -9,7 +9,11 @@ Right now it depends on the following non-core Python 3 libraries. These can be
* [django](https://www.djangoproject.com/) django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.
* [easy-thumbnails](https://github.com/SmileyChris/easy-thumbnails) A powerful, yet easy to implement thumbnailing application for Django 1.11+
* [image](https://github.com/francescortiz/image) Image cropping for django
* [django-widget-tweaks](https://github.com/jazzband/django-widget-tweaks) Tweak the form field rendering in templates, not in python-level form definitions.
## Development
### Setting up a (pipenv) virtual environment for development
After having obtained the repository contents (either via .zip download or git clone), you can easily setup a pipenv virtual environment. The repo provides a Pipfile for easy dependency management that does not mess with your system.
@@ -18,6 +22,7 @@ After having obtained the repository contents (either via .zip download or git c
$ cd lostplaces-backend
$ pipenv install
$ pipenv shell
(lostplaces-backend) $ lostplaces/manage.py makemigrations
(lostplaces-backend) $ lostplaces/manage.py migrate
(lostplaces-backend) $ lostplaces/manage.py createsuperuser
(lostplaces-backend) $ lostplaces/manage.py runserver
@@ -33,4 +38,65 @@ $ pipenv shell
Visit: [admin](http://localhost:8000/admin) for administrative backend or
[frontend](http://localhost:8000/)
## Installing lostplaces
### Install dependencies
Python3, Django3, easy-thumbnails, image, django-widget-tweaks
```
pip install --user django easy-thumbnails image django-widget-tweaks
```
Or, if you use pipenv
```
pipenv install
```
### Add 'lostplaces_app' to your INSTALLED_APPS setting like this
```
INSTALLED_APPS = [
...
'lostplaces_app',
'easy_thumbnails',
'widget_tweaks',
]
```
### Add this configuration to your settings.py
```
from django.urls import reverse_lazy
...
AUTH_USER_MODEL = 'lostplaces_app.Explorer'
LOGIN_URL = reverse_lazy('login')
THUMBNAIL_ALIASES = {
'': {
'thumbnail': {'size': (300, 300), 'crop': False},
'hero': {'size': (700, 700), 'crop': False},
'large': {'size': (1920, 1920), 'crop': False},
},
}
```
### Include the lostplaces URLconf in your project urls.py like this
```
from django.urls import path, include
...
urlpatterns = [
...
path('lostplaces/', include('lostplaces_app.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```
Run ``python manage.py migrate`` to create the lost places models.
Start the development server and visit http://127.0.0.1:8000/admin/
Visit http://127.0.0.1:8000/lostplaces/ to CRUD lost places.
Happy developing ;-)

View File

@@ -29,7 +29,7 @@ SECRET_KEY = 'n$(bx8(^)*wz1ygn@-ekt7rl^1km*!_c+fwwjiua8m@-x_rpl0'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['localhost', '192.168.178.49']
# Application definition
@@ -43,7 +43,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'easy_thumbnails',
'widget_tweaks',
'widget_tweaks'
]
MIDDLEWARE = [
@@ -148,3 +148,5 @@ THUMBNAIL_ALIASES = {
'large': {'size': (1920, 1920), 'crop': False},
},
}
SVG_ICONS_SOURCE_FILE = os.path.join(BASE_DIR, 'lostplaces_app', 'static', 'icons', 'icons.icomoon.json')

View File

@@ -26,3 +26,4 @@ admin.site.register(Explorer, ExplorerAdmin)
admin.site.register(Voucher, VoucherAdmin)
admin.site.register(Place)
admin.site.register(PlaceImage)
admin.site.register(PhotoAlbum)

View File

@@ -55,6 +55,19 @@ class Place (models.Model):
longitude = models.FloatField()
description = models.TextField()
# Get center position of LP-geocoordinates.
def average_latlon(place_list):
amount = len(place_list)
# Init fill values to prevent None
longitude = 0
latitude = 0
for place in place_list:
longitude += place.longitude
latitude += place.latitude
return (latitude / amount, longitude / amount)
def __str__(self):
return self.name
@@ -126,3 +139,24 @@ def auto_delete_file_on_change(sender, instance, **kwargs):
if not old_file == new_file:
if os.path.isfile(old_file.path):
os.remove(old_file.path)
class ExternalLink(models.Model):
url = models.URLField(max_length=200)
label = models.CharField(max_length=100)
submitted_by = models.ForeignKey(
Explorer,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='external_links'
)
submitted_when = models.DateTimeField(auto_now_add=True, null=True)
class PhotoAlbum(ExternalLink):
place = models.ForeignKey(
Place,
on_delete=models.CASCADE,
related_name='photo_albums',
null=True
)

View File

@@ -0,0 +1 @@
<svg height="427pt" viewBox="-40 0 427 427.00131" width="427pt" xmlns="http://www.w3.org/2000/svg"><path d="m232.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0"/><path d="m114.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0"/><path d="m28.398438 127.121094v246.378906c0 14.5625 5.339843 28.238281 14.667968 38.050781 9.285156 9.839844 22.207032 15.425781 35.730469 15.449219h189.203125c13.527344-.023438 26.449219-5.609375 35.730469-15.449219 9.328125-9.8125 14.667969-23.488281 14.667969-38.050781v-246.378906c18.542968-4.921875 30.558593-22.835938 28.078124-41.863282-2.484374-19.023437-18.691406-33.253906-37.878906-33.257812h-51.199218v-12.5c.058593-10.511719-4.097657-20.605469-11.539063-28.03125-7.441406-7.421875-17.550781-11.5546875-28.0625-11.46875h-88.796875c-10.511719-.0859375-20.621094 4.046875-28.0625 11.46875-7.441406 7.425781-11.597656 17.519531-11.539062 28.03125v12.5h-51.199219c-19.1875.003906-35.394531 14.234375-37.878907 33.257812-2.480468 19.027344 9.535157 36.941407 28.078126 41.863282zm239.601562 279.878906h-189.203125c-17.097656 0-30.398437-14.6875-30.398437-33.5v-245.5h250v245.5c0 18.8125-13.300782 33.5-30.398438 33.5zm-158.601562-367.5c-.066407-5.207031 1.980468-10.21875 5.675781-13.894531 3.691406-3.675781 8.714843-5.695313 13.925781-5.605469h88.796875c5.210937-.089844 10.234375 1.929688 13.925781 5.605469 3.695313 3.671875 5.742188 8.6875 5.675782 13.894531v12.5h-128zm-71.199219 32.5h270.398437c9.941406 0 18 8.058594 18 18s-8.058594 18-18 18h-270.398437c-9.941407 0-18-8.058594-18-18s8.058593-18 18-18zm0 0"/><path d="m173.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1 +1,4 @@
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30px" height="30px"><path d="M 3 7 A 1.0001 1.0001 0 1 0 3 9 L 27 9 A 1.0001 1.0001 0 1 0 27 7 L 3 7 z M 3 14 A 1.0001 1.0001 0 1 0 3 16 L 27 16 A 1.0001 1.0001 0 1 0 27 14 L 3 14 z M 3 21 A 1.0001 1.0001 0 1 0 3 23 L 27 23 A 1.0001 1.0001 0 1 0 27 21 L 3 21 z"/></svg>
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30px" height="30px">
<path
d="M 3 7 A 1.0001 1.0001 0 1 0 3 9 L 27 9 A 1.0001 1.0001 0 1 0 27 7 L 3 7 z M 3 14 A 1.0001 1.0001 0 1 0 3 16 L 27 16 A 1.0001 1.0001 0 1 0 27 14 L 3 14 z M 3 21 A 1.0001 1.0001 0 1 0 3 23 L 27 23 A 1.0001 1.0001 0 1 0 27 21 L 3 21 z" />
</svg>

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 358 B

View File

@@ -0,0 +1,13 @@
{
"trash": {
"paths": [
"m232.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0",
"m114.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0",
"m28.398438 127.121094v246.378906c0 14.5625 5.339843 28.238281 14.667968 38.050781 9.285156 9.839844 22.207032 15.425781 35.730469 15.449219h189.203125c13.527344-.023438 26.449219-5.609375 35.730469-15.449219 9.328125-9.8125 14.667969-23.488281 14.667969-38.050781v-246.378906c18.542968-4.921875 30.558593-22.835938 28.078124-41.863282-2.484374-19.023437-18.691406-33.253906-37.878906-33.257812h-51.199218v-12.5c.058593-10.511719-4.097657-20.605469-11.539063-28.03125-7.441406-7.421875-17.550781-11.5546875-28.0625-11.46875h-88.796875c-10.511719-.0859375-20.621094 4.046875-28.0625 11.46875-7.441406 7.425781-11.597656 17.519531-11.539062 28.03125v12.5h-51.199219c-19.1875.003906-35.394531 14.234375-37.878907 33.257812-2.480468 19.027344 9.535157 36.941407 28.078126 41.863282zm239.601562 279.878906h-189.203125c-17.097656 0-30.398437-14.6875-30.398437-33.5v-245.5h250v245.5c0 18.8125-13.300782 33.5-30.398438 33.5zm-158.601562-367.5c-.066407-5.207031 1.980468-10.21875 5.675781-13.894531 3.691406-3.675781 8.714843-5.695313 13.925781-5.605469h88.796875c5.210937-.089844 10.234375 1.929688 13.925781 5.605469 3.695313 3.671875 5.742188 8.6875 5.675782 13.894531v12.5h-128zm-71.199219 32.5h270.398437c9.941406 0 18 8.058594 18 18s-8.058594 18-18 18h-270.398437c-9.941407 0-18-8.058594-18-18s8.058593-18 18-18zm0 0",
"m173.398438 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.523437 0 10-4.480469 10-10v-189c0-5.523437-4.476563-10-10-10zm0 0"
],
"height": "427pt",
"width": "427pt",
"viewBox": "-40 0 427 427.00131"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,428 @@
.pink {
background-color: pink; }
.RV-Alignment__Container {
display: grid; }
.RV-Alignment__Container--top {
display: grid;
align-content: start; }
.RV-Alignment__Container--bottom {
display: grid;
align-content: end; }
.RV-Alignment__Container--left {
display: grid;
justify-content: start; }
.RV-Alignment__Container--right {
display: grid;
justify-content: end; }
.RV-Alignment__Container--horizontalCenter {
display: grid;
justify-content: center; }
.RV-Alignment__Container--verticalCenter {
display: grid;
align-items: center; }
.RV-Alignment__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.RV-FlexRow__Container {
display: flex;
flex-direction: row;
height: 100%; }
.RV-FlexRow__Container--multiRow {
flex-wrap: wrap; }
.RV-FlexRow__Container--column {
display: flex;
flex-direction: column; }
.RV-FlexRow__Item {
min-width: min-content;
width: 100%; }
.RV-FlexRow__Item__Container {
display: grid; }
.RV-FlexRow__Item__Container--top {
display: grid;
align-content: start; }
.RV-FlexRow__Item__Container--bottom {
display: grid;
align-content: end; }
.RV-FlexRow__Item__Container--left {
display: grid;
justify-content: start; }
.RV-FlexRow__Item__Container--right {
display: grid;
justify-content: end; }
.RV-FlexRow__Item__Container--horizontalCenter {
display: grid;
justify-content: center; }
.RV-FlexRow__Item__Container--verticalCenter {
display: grid;
align-items: center; }
.RV-FlexRow__Item__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.RV-FlexRow__Item, .RV-FlexRow__Item--normal {
flex-grow: 3;
flex-shrink: 3; }
.RV-FlexRow__Item--narrower {
flex-grow: 1;
flex-shrink: 5; }
.RV-FlexRow__Item--narrow {
flex-grow: 2;
flex-shrink: 4; }
.RV-FlexRow__Item--wide {
flex-grow: 4;
flex-shrink: 2; }
.RV-FlexRow__Item--wider {
flex-grow: 5;
flex-shrink: 1; }
.RV-FlexRow__Item--fixedSize {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: 100px; }
.RV-FlexGrid__Container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-rows: repeat(auto-fill, minmax(300px, 1fr));
grid-auto-rows: minmax(300px, 1fr); }
.RV-FlexGrid__Item__Container {
display: grid; }
.RV-FlexGrid__Item__Container--top {
display: grid;
align-content: start; }
.RV-FlexGrid__Item__Container--bottom {
display: grid;
align-content: end; }
.RV-FlexGrid__Item__Container--left {
display: grid;
justify-content: start; }
.RV-FlexGrid__Item__Container--right {
display: grid;
justify-content: end; }
.RV-FlexGrid__Item__Container--horizontalCenter {
display: grid;
justify-content: center; }
.RV-FlexGrid__Item__Container--verticalCenter {
display: grid;
align-items: center; }
.RV-FlexGrid__Item__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.RV-ContentCrop__Container, .RV-ContentCrop__Container * {
overflow: hidden;
word-break: break-all; }
.RV-ContentCrop__Container img {
width: 100%;
height: 100%;
object-fit: cover; }
.RV-ContentCrop__Container--left img {
object-position: left; }
.RV-ContentCrop__Container--center img {
object-position: center; }
.RV-ContentCrop__Container--top img {
object-position: top; }
.RV-ContentCrop__Container--bottom img {
object-position: botom; }
.RV-ContentCrop__Container--center img {
object-position: center; }
.RV-Fan__Container--vertical {
flex-direction: column;
width: max-content; }
.RV-Fan__Container--vertical .RV-Fan__Surface {
width: 320px;
min-height: 280px; }
.RV-Fan__Container--horizontal {
flex-direction: row; }
.RV-Fan__Container--horizontal .RV-Fan__Surface {
min-width: 320px;
height: 280px; }
.RV-Fan__Container--auto {
flex-flow: row wrap; }
.RV-Fan__Container--auto .RV-Fan__Surface {
width: calc(100% - 320px);
min-width: 320px;
height: 280px; }
.RV-Fan__Container--fullWidth .RV-Fan__Base, .RV-Fan__Container--fullWidth .RV-Fan__Surface {
flex-grow: 1; }
.RV-Fan__Container {
display: flex; }
.RV-Fan__Base {
height: 280px;
width: 320px;
flex: 0 0 auto; }
.RV-Fan__Surface, .RV-Fan__Surface * {
overflow: hidden;
word-break: break-all; }
.RV-Fan__Surface img {
width: 100%;
height: 100%;
object-fit: cover; }
.RV-Fan__Surface--left img {
object-position: left; }
.RV-Fan__Surface--center img {
object-position: center; }
.RV-Fan__Surface--top img {
object-position: top; }
.RV-Fan__Surface--bottom img {
object-position: botom; }
.RV-Fan__Surface--center img {
object-position: center; }
.RV-FullWidthContent__Container {
width: 100%; }
.RV-FullWidthContent__Item {
width: 100%; }
.RV-FullWidthContent__Item, .RV-FullWidthContent__Item * {
overflow: hidden;
word-break: break-all; }
.RV-FullWidthContent__Item img {
width: 100%;
height: 100%;
object-fit: cover; }
.RV-FullWidthContent__Item--left img {
object-position: left; }
.RV-FullWidthContent__Item--center img {
object-position: center; }
.RV-FullWidthContent__Item--top img {
object-position: top; }
.RV-FullWidthContent__Item--bottom img {
object-position: botom; }
.RV-FullWidthContent__Item--center img {
object-position: center; }
.RV-BoxShadow {
position: relative;
float: left; }
.RV-BoxShadow:before, .RV-BoxShadow:after {
content: "";
position: absolute;
z-index: -2; }
.RV-BoxShadow--simple {
box-shadow: 0 0 10px #6b5690; }
.RV-BoxShadow--raised:after {
box-shadow: 0 15px 10px -10px rgba(0, 0, 0, 0.5), 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset; }
.RV-BoxShadow--liftedCorners:before, .RV-BoxShadow--liftedCorners:after {
bottom: 15px;
left: 10px;
width: 50%;
height: 20%;
max-width: 300px;
box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
transform: rotate(-3deg); }
.RV-BoxShadow--liftedCorners:after {
right: 10px;
left: auto;
transform: rotate(3deg); }
.RV-ElementList__Container {
list-style-type: none;
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.RV-ElementList__Item {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.RV-Spacing__Outer--small {
margin: 10px; }
.RV-Spacing__Outer--medium {
margin: 25px; }
.RV-Spacing__Outer--large {
margin: 35px; }
.RV-Spacing__Inner--small {
padding: 10px; }
.RV-Spacing__Inner--small {
gap: 10px; }
.RV-Spacing__Inner--medium {
padding: 25px; }
.RV-Spacing__Inner--medium {
gap: 25px; }
.RV-Spacing__Inner--large {
padding: 35px; }
.RV-Spacing__Inner--large {
gap: 35px; }
.RV-Iconized__Container {
position: relative; }
.RV-Iconized__Container--small {
top: -.25em; }
.RV-Iconized__Container--medium {
top: -.5em; }
.RV-Iconized__Container--large {
top: -1.03073em; }
.RV-Iconized__Container--huge {
top: -2.05em; }
.RV-Iconized__Icon {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.RV-Iconized__Container--extraSmall .RV-Iconized__Icon {
width: 1em;
height: 1em;
position: relative;
top: .125em; }
.RV-Iconized__Container--small .RV-Iconized__Icon {
width: 1.5em;
height: 1.5em;
position: relative;
top: .45em; }
.RV-Iconized__Container--medium .RV-Iconized__Icon {
width: 2em;
height: 2em;
position: relative;
top: .625em; }
.RV-Iconized__Container--large .RV-Iconized__Icon {
width: 3em;
height: 3em;
position: relative;
top: 1.15573em; }
.RV-Iconized__Container--huge .RV-Iconized__Icon {
width: 5em;
height: 5em;
position: relative;
top: 2.175em; }
.RV-ImageGrid__Container {
list-style-type: none;
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.RV-ImageGrid__Item {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.RV-ImageGrid__Container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-rows: repeat(auto-fill, minmax(300px, 1fr));
grid-auto-rows: minmax(300px, 1fr); }
.RV-ImageGrid__Item__Container {
display: grid; }
.RV-ImageGrid__Item__Container--top {
display: grid;
align-content: start; }
.RV-ImageGrid__Item__Container--bottom {
display: grid;
align-content: end; }
.RV-ImageGrid__Item__Container--left {
display: grid;
justify-content: start; }
.RV-ImageGrid__Item__Container--right {
display: grid;
justify-content: end; }
.RV-ImageGrid__Item__Container--horizontalCenter {
display: grid;
justify-content: center; }
.RV-ImageGrid__Item__Container--verticalCenter {
display: grid;
align-items: center; }
.RV-ImageGrid__Item__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.RV-ImageGrid__Container {
padding: 25px; }
.RV-ImageGrid__Container__Container {
gap: 25px; }
.RV-ImageGrid__Item, .RV-ImageGrid__Item * {
overflow: hidden;
word-break: break-all; }
.RV-ImageGrid__Item img {
width: 100%;
height: 100%;
object-fit: cover; }
.RV-ImageGrid__Item--left img {
object-position: left; }
.RV-ImageGrid__Item--center img {
object-position: center; }
.RV-ImageGrid__Item--top img {
object-position: top; }
.RV-ImageGrid__Item--bottom img {
object-position: botom; }
.RV-ImageGrid__Item--center img {
object-position: center; }
.RV-ImageGrid__Item img {
object-position: center; }
@font-face {
font-family: Crimson;
src: url("fonts/Crimson/CrimsonText-Regular.ttf"), url("fonts/Crimson/CrimsonText-Bold.ttf"), url("fonts/Crimson/CrimsonText-Italic.ttf"); }
@@ -178,8 +603,9 @@ body {
.LP-Input .LP-Input__Field {
border: none;
border-bottom: 1px solid #565656;
padding: 8px;
margin-bottom: 30px; }
padding: 8px 0;
margin-bottom: 30px;
width: 100%; }
.LP-Input .LP-Input__Field:focus, .LP-Input .LP-Input__Field:active, .LP-Input .LP-Input__Field:invalid {
margin-bottom: 29px;
border-bottom: 2px solid #76323F;
@@ -199,14 +625,17 @@ body {
color: #f9f9f9; }
.LP-Input .LP-Input__Label {
font-family: Montserrat, Helvetica, sans-serif;
font-size: 16px; }
font-size: 16px;
white-space: wrap;
overflow: hidden; }
.LP-Input .LP-Input__Message {
font-family: Montserrat, Helvetica, sans-serif;
font-style: italic;
font-size: 13px;
padding: 3px;
position: relative;
top: -30px; }
top: -30px;
overflow: hidden; }
.LP-Input--error .LP-Input__Field {
margin-bottom: 25px;
border-bottom: 2px solid #76323F;
@@ -583,44 +1012,161 @@ body {
.LP-PlaceList .LP-Pagination {
margin-top: 50px; }
.LP-LinkList__List {
list-style-type: none;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
margin: 0;
padding: 0; }
.LP-LinkList__List .LP-LinkList__Item {
.LP-LinkList {
padding: 10px;
align-items: center; }
.LP-LinkList__Container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-rows: repeat(auto-fill, minmax(3em, 1fr));
grid-auto-rows: minmax(3em, 1fr); }
.LP-LinkList__Item__Container {
display: grid; }
.LP-LinkList__Item__Container--top {
display: grid;
align-content: start; }
.LP-LinkList__Item__Container--bottom {
display: grid;
align-content: end; }
.LP-LinkList__Item__Container--left {
display: grid;
justify-content: start; }
.LP-LinkList__Item__Container--right {
display: grid;
justify-content: end; }
.LP-LinkList__Item__Container--horizontalCenter {
display: grid;
justify-content: center; }
.LP-LinkList__Item__Container--verticalCenter {
display: grid;
align-items: center; }
.LP-LinkList__Item__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.LP-LinkList__Container {
list-style-type: none;
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.LP-LinkList__Item {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.LP-LinkList__Container {
gap: 10px; }
.LP-LinkList .LP-LinkList__Item {
border-left: 1px solid #C09F80;
width: calc(100% - 1px);
margin-top: 12px; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link {
padding: 1em 0 1em 1em;
width: calc(100% - 1em);
overflow: hidden;
display: grid;
align-items: center;
display: flex;
flex-direction: row;
height: 100%; }
.LP-LinkList .LP-LinkList__Item--multiRow {
flex-wrap: wrap; }
.LP-LinkList .LP-LinkList__Item--column {
display: flex;
flex-direction: column; }
.LP-LinkList .LP-LinkList__Item .LP-LinkList__ItemHover {
opacity: 0.5;
display: grid;
justify-content: end;
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: min-content; }
.LP-LinkList .LP-LinkList__Item:hover {
background-color: #f9f9f9; }
.LP-LinkList .LP-LinkList__Item:hover .LP-LinkList__ItemHover {
opacity: 1; }
.LP-LinkList .LP-Link {
min-width: min-content;
width: 100%;
padding: 10px; }
.LP-LinkList .LP-Link__Container {
display: grid; }
.LP-LinkList .LP-Link__Container--top {
display: grid;
align-content: start; }
.LP-LinkList .LP-Link__Container--bottom {
display: grid;
align-content: end; }
.LP-LinkList .LP-Link__Container--left {
display: grid;
justify-content: start; }
.LP-LinkList .LP-Link__Container--right {
display: grid;
justify-content: end; }
.LP-LinkList .LP-Link__Container--horizontalCenter {
display: grid;
justify-content: center; }
.LP-LinkList .LP-Link__Container--verticalCenter {
display: grid;
align-items: center; }
.LP-LinkList .LP-Link__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.LP-LinkList .LP-Link, .LP-LinkList .LP-Link--normal {
flex-grow: 3;
flex-shrink: 3; }
.LP-LinkList .LP-Link--narrower {
flex-grow: 1;
flex-shrink: 5; }
.LP-LinkList .LP-Link--narrow {
flex-grow: 2;
flex-shrink: 4; }
.LP-LinkList .LP-Link--wide {
flex-grow: 4;
flex-shrink: 2; }
.LP-LinkList .LP-Link--wider {
flex-grow: 5;
flex-shrink: 1; }
.LP-LinkList .LP-Link--fixedSize {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: 100px; }
.LP-LinkList .LP-Link__Container {
gap: 10px; }
.LP-LinkList .LP-LinkAdd {
height: 0; }
.LP-LinkList .LP-LinkAdd__Container {
position: relative;
top: -39px; }
.LP-LinkList .LP-LinkAdd__Container .LP-Form__Fieldset {
min-width: unset; }
.LP-LinkList .LP-LinkAdd__Container .LP-Form {
display: block;
color: #565656; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link--iconized {
padding-top: 0;
padding-bottom: 1.1em; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link--iconized:hover {
background-color: #ccc !important; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link--iconized .LP-Text {
padding-top: .1em; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link:hover {
background-color: #f9f9f9;
color: #76323F; }
.LP-LinkList__List .LP-LinkList__Item .LP-Link .LP-Text {
color: inherit; }
min-width: 0px; }
.LP-Link__Icon {
width: 2em;
height: 2em;
fill: #76323F;
line-height: 5em; }
.LP-LinkAdd {
display: none; }
.LP-LinkList__Item .LP-Link__Icon {
position: relative;
top: .7em;
margin-right: .6em; }
.LP-LinkAdd__Trigger {
display: none; }
.LP-LinkAdd__TriggerLabel {
cursor: pointer;
display: contents; }
.LP-LinkAdd__Trigger:checked, .LP-LinkAdd__Trigger:checked + .LP-LinkAdd__TriggerLabel {
display: none; }
.LP-LinkAdd__Trigger:checked ~ .LP-LinkAdd {
display: block; }
.LP-Footer {
margin-top: 75px;
@@ -643,98 +1189,195 @@ body {
.LP-Footer .LP-LinkList__List .LP-LinkList__Item .LP-Link:hover {
background-color: inherit; }
.LP-Form {
display: flex;
flex-direction: column;
align-items: center; }
.LP-Form .LP-Form__Fieldset {
border: none;
max-width: 1200px;
min-width: 750px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Legend {
margin: 0;
padding: 0;
font-family: Montserrat, Helvetica, sans-serif;
font-size: 21px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition {
display: flex;
flex-direction: row;
justify-content: space-between; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field {
flex: 3 2 100px;
padding: 6px 15px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field--wider {
flex: 5 2; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field--wide {
flex: 4 2; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field--narrow {
flex: 2 1; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field--narrower {
flex: 1 2; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition--buttons {
justify-content: flex-end; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Button {
flex-grow: 0;
padding-left: 0;
min-width: 130px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Button .LP-Link {
display: contents; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__InfoText .LP-Paragraph {
font-family: Montserrat, Helvetica, sans-serif;
color: #565656; }
.LP-Form--inline .LP-Form__Legend, .LP-Form--inline .LP-Input__Label {
display: none; }
@media (max-width: 750px) {
.LP-Form .LP-Form__Fieldset {
min-width: unset; } }
@media (max-width: 650px) {
.LP-Form .LP-Form__Fieldset .LP-Form__Composition--breakable {
display: flex;
flex-direction: column;
justify-content: space-between; } }
.LP-Form--inline .LP-Form__Button {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: max-content; }
@media (max-width: 450px) {
.LP-Form .LP-Form__Fieldset .LP-Form__Composition {
.LP-Form:not(.LP-Form--inline) .LP-Form__Composition {
flex-wrap: wrap; } }
.LP-Form:not(.LP-Form--inline) .LP-Form__Button {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: 130px; }
@media (max-width: 450px) {
.LP-Form:not(.LP-Form--inline) .LP-Form__Button {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: 100%; } }
.LP-Form .LP-Form__Fieldset {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none;
max-width: 1200px;
min-width: 750px; }
@media (max-width: 750px) {
.LP-Form .LP-Form__Fieldset {
min-width: unset; } }
.LP-Form .LP-Form__Legend {
margin: 0;
padding: 0;
font-family: Montserrat, Helvetica, sans-serif;
font-size: 21px; }
.LP-Form .LP-Form__Composition {
display: flex;
flex-direction: row;
height: 100%;
padding: 10px; }
.LP-Form .LP-Form__Composition--multiRow {
flex-wrap: wrap; }
.LP-Form .LP-Form__Composition--column {
display: flex;
flex-direction: column;
justify-content: space-between; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Field:not(.LP-Form__Button) {
flex: 3 1 100px;
padding: 12px 15px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition .LP-Form__Button {
padding: 0 15px; }
.LP-Form .LP-Form__Fieldset .LP-Form__Composition--buttons {
justify-content: flex-end; } }
flex-direction: column; }
.LP-Form .LP-Form__Composition {
gap: 10px; }
@media (max-width: 650px) {
.LP-Form .LP-Form__Composition--breakable {
flex-wrap: wrap; } }
.LP-Form .LP-Form__Composition--buttons {
justify-content: flex-end;
padding: 10px; }
.LP-Form .LP-Form__Composition--buttons__Container {
gap: 10px; }
.LP-ImageGrid .LP-ImageGrid__List {
list-style-type: none;
display: grid;
grid-template-columns: repeat(auto-fit, 300px);
align-content: space-around;
justify-content: center;
margin: 0px;
padding: 0px; }
.LP-Form .LP-Form__Field {
min-width: min-content;
width: 100%; }
.LP-Form .LP-Form__Field__Container {
display: grid; }
.LP-Form .LP-Form__Field__Container--top {
display: grid;
align-content: start; }
.LP-Form .LP-Form__Field__Container--bottom {
display: grid;
align-content: end; }
.LP-Form .LP-Form__Field__Container--left {
display: grid;
justify-content: start; }
.LP-Form .LP-Form__Field__Container--right {
display: grid;
justify-content: end; }
.LP-Form .LP-Form__Field__Container--horizontalCenter {
display: grid;
justify-content: center; }
.LP-Form .LP-Form__Field__Container--verticalCenter {
display: grid;
align-items: center; }
.LP-Form .LP-Form__Field__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.LP-Form .LP-Form__Field, .LP-Form .LP-Form__Field--normal {
flex-grow: 3;
flex-shrink: 3; }
.LP-Form .LP-Form__Field--narrower {
flex-grow: 1;
flex-shrink: 5; }
.LP-Form .LP-Form__Field--narrow {
flex-grow: 2;
flex-shrink: 4; }
.LP-Form .LP-Form__Field--wide {
flex-grow: 4;
flex-shrink: 2; }
.LP-Form .LP-Form__Field--wider {
flex-grow: 5;
flex-shrink: 1; }
.LP-Form .LP-Form__Field--fixedSize {
flex-grow: 0;
flex-shrink: 0;
width: min-content;
flex-basis: 100px; }
.LP-ImageGrid .LP-ImageGrid__Item {
margin-top: 10px; }
.LP-Form .LP-Form__InfoText .LP-Paragraph {
font-family: Montserrat, Helvetica, sans-serif;
color: #565656; }
.LP-ImageGrid .LP-Link {
overflow: hidden; }
.LP-ImageGrid .LP-Image {
box-shadow: 0 0 5px #565656;
height: 200px;
width: 290px;
object-fit: cover; }
@media (max-width: 650px) {
.LP-ImageGrid .LP-ImageGrid__List {
grid-template-columns: 1fr; }
.LP-ImageGrid .LP-ImageGrid__List .LP-Image {
box-shadow: 0 0 5px #565656;
height: auto;
.LP-ImageGrid {
padding: 10px; }
.LP-ImageGrid__Container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
grid-template-rows: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: minmax(200px, 1fr); }
.LP-ImageGrid__Item__Container {
display: grid; }
.LP-ImageGrid__Item__Container--top {
display: grid;
align-content: start; }
.LP-ImageGrid__Item__Container--bottom {
display: grid;
align-content: end; }
.LP-ImageGrid__Item__Container--left {
display: grid;
justify-content: start; }
.LP-ImageGrid__Item__Container--right {
display: grid;
justify-content: end; }
.LP-ImageGrid__Item__Container--horizontalCenter {
display: grid;
justify-content: center; }
.LP-ImageGrid__Item__Container--verticalCenter {
display: grid;
align-items: center; }
.LP-ImageGrid__Item__Container--center {
display: grid;
justify-content: center;
display: grid;
align-items: center; }
.LP-ImageGrid__Container {
list-style-type: none;
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.LP-ImageGrid__Item {
margin: 0;
padding: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: none; }
.LP-ImageGrid__Container {
gap: 10px; }
.LP-ImageGrid .LP-ImageGrid__Item {
box-shadow: 0 0 10px #565656; }
.LP-ImageGrid .LP-ImageGrid__Item, .LP-ImageGrid .LP-ImageGrid__Item * {
overflow: hidden;
word-break: break-all; }
.LP-ImageGrid .LP-ImageGrid__Item img {
width: 100%;
object-fit: cover; } }
height: 100%;
object-fit: cover; }
.LP-ImageGrid .LP-ImageGrid__Item--left img {
object-position: left; }
.LP-ImageGrid .LP-ImageGrid__Item--center img {
object-position: center; }
.LP-ImageGrid .LP-ImageGrid__Item--top img {
object-position: top; }
.LP-ImageGrid .LP-ImageGrid__Item--bottom img {
object-position: botom; }
.LP-ImageGrid .LP-ImageGrid__Item--center img {
object-position: center; }
.LP-MainContainer {
margin: 0 auto;
@@ -751,6 +1394,7 @@ body {
width: 700px;
max-height: 500px;
box-shadow: 0 0 10px #565656;
box-shadow: 0 0 10px #565656;
object-fit: cover;
object-position: 0 0;
margin: 0;

View File

@@ -0,0 +1,2 @@
.ol-box{box-sizing:border-box;border-radius:2px;border:2px solid #00f}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;transition:all .25s}.ol-scale-bar{position:absolute;bottom:8px;left:8px}.ol-scale-step-marker{width:1px;height:15px;background-color:#000;float:right;z-Index:10}.ol-scale-step-text{position:absolute;bottom:-5px;font-size:12px;z-Index:11;color:#000;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.ol-scale-text{position:absolute;font-size:14px;text-align:center;bottom:25px;color:#000;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.ol-scale-singlebar{position:relative;height:10px;z-Index:9;border:1px solid #000}.ol-unsupported{display:none}.ol-unselectable,.ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ol-overlaycontainer,.ol-overlaycontainer-stopevent{pointer-events:none}.ol-overlaycontainer-stopevent>*,.ol-overlaycontainer>*{pointer-events:auto}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px}.ol-control:hover{background-color:rgba(255,255,255,.6)}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-control button span{pointer-events:none}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:focus,.ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7)}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em)}.ol-attribution ul{margin:0;padding:0 .5em;color:#000;text-shadow:0 0 2px #fff}.ol-attribution li{display:inline;list-style:none}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button,.ol-attribution ul{display:inline-block}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:inline-block}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:1px;left:2px;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move}
/*# sourceMappingURL=ol.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["src/ol/ol.css"],"names":[],"mappings":"AAAA,QACE,WAAY,WACZ,cAAe,IACf,OAAQ,IAAI,MAAM,KAGpB,mBACE,IAAK,IACL,MAAO,IACP,SAAU,SAGZ,eACE,WAAY,kBACZ,cAAe,IACf,OAAQ,IACR,KAAM,IACN,QAAS,IACT,SAAU,SAEZ,qBACE,OAAQ,IAAI,MAAM,KAClB,WAAY,KACZ,MAAO,KACP,UAAW,KACX,WAAY,OACZ,OAAQ,IACR,YAAa,QAAQ,CAAE,MACvB,WAAY,IAAI,KAElB,cACE,SAAU,SACV,OAAQ,IACR,KAAM,IAER,sBACE,MAAO,IACP,OAAQ,KACR,iBAAkB,KAClB,MAAO,MACP,QAAS,GAEX,oBACE,SAAU,SACV,OAAQ,KACR,UAAW,KACX,QAAS,GACT,MAAO,KACP,YAAa,KAAK,EAAE,IAAO,CAAE,EAAE,IAAI,IAAO,CAAE,IAAI,EAAE,IAAO,CAAE,EAAE,KAAK,KAEpE,eACE,SAAU,SACV,UAAW,KACX,WAAY,OACZ,OAAQ,KACR,MAAO,KACP,YAAa,KAAK,EAAE,IAAO,CAAE,EAAE,IAAI,IAAO,CAAE,IAAI,EAAE,IAAO,CAAE,EAAE,KAAK,KAEpE,oBACE,SAAU,SACV,OAAQ,KACR,QAAS,EACT,OAAQ,IAAI,MAAM,KAGpB,gBACE,QAAS,KAEG,iBAAd,aACE,sBAAuB,KACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KACb,4BAA6B,YAE/B,qBAAsB,+BACpB,eAAgB,KAEQ,iCAA1B,uBACE,eAAgB,KAElB,eACE,sBAAuB,QACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAEf,aACE,OAAQ,iBACR,OAAQ,cACR,OAAQ,SAEV,SACE,OAAQ,KACR,OAAQ,aACR,OAAQ,UACR,OAAQ,KAEV,YACE,SAAU,SACV,iBAAkB,qBAClB,cAAe,IACf,QAAS,IAEX,kBACE,iBAAkB,qBAEpB,SACE,IAAK,KACL,KAAM,KAER,WACE,IAAK,KACL,MAAO,KACP,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAEjD,qBACE,QAAS,EACT,WAAY,OACZ,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAAO,KAExD,gBACE,IAAK,QACL,KAAM,KAER,gBACE,MAAO,KACP,IAAK,KAGP,mBACE,QAAS,MACT,OAAQ,IACR,QAAS,EACT,MAAO,KACP,UAAW,OACX,YAAa,IACb,gBAAiB,KACjB,WAAY,OACZ,OAAQ,QACR,MAAO,QACP,YAAa,KACb,iBAAkB,kBAClB,OAAQ,KACR,cAAe,IAEjB,qCACE,OAAQ,KACR,QAAS,EAEX,wBACE,eAAgB,KAElB,uBACE,YAAa,MAEf,YACE,QAAS,MACT,YAAa,IACb,UAAW,MACX,YAAa,UAEf,6BACE,UAAW,MAEb,0BACE,IAAK,MAGP,yBADA,yBAEE,gBAAiB,KACjB,iBAAkB,kBAEpB,qBACE,cAAe,IAAI,IAAI,EAAE,EAE3B,sBACE,cAAe,EAAE,EAAE,IAAI,IAIzB,gBACE,WAAY,MACZ,OAAQ,KACR,MAAO,KACP,UAAW,mBAGb,mBACE,OAAQ,EACR,QAAS,EAAE,KACX,MAAO,KACP,YAAa,EAAE,EAAE,IAAI,KAEvB,mBACE,QAAS,OACT,WAAY,KAEd,0CACE,QAAS,IAEX,oBACE,WAAY,IACZ,UAAW,QACX,eAAgB,OAEE,uBAApB,mBACE,QAAS,aAEX,gCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,iCACE,OAAQ,EACR,MAAO,EACP,cAAe,IAAI,EAAE,EAEvB,qCACE,WAAY,MACZ,WAAY,MAEd,wCACE,QAAS,KAGX,eACE,IAAK,MACL,KAAM,KACN,OAAQ,MAEV,sBACE,SAAU,SACV,OAAQ,KAGV,yBACE,IAAK,MAGP,gBACE,KAAM,KACN,OAAQ,KAEV,iCACE,OAAQ,EACR,KAAM,EACN,cAAe,EAAE,IAAI,EAAE,EAEzB,oCACA,uBACE,QAAS,aAEX,oCACE,OAAQ,IAAI,MAAM,QAClB,OAAQ,MACR,OAAQ,IACR,MAAO,MAET,0CACE,OAAQ,IACR,KAAM,IACN,SAAU,SAEZ,iDACA,wCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,oBACE,OAAQ,IAAI,OAAO,kBAGrB,0CACE,OAAQ"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
# Keeping these files up-to-date is something for CI / release management.
# But for now I noted the source urls down here for later reference.
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/css/ol.css
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/css/ol.css.map
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/build/ol.js
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/build/ol.js.map

View File

@@ -0,0 +1,548 @@
:root {
--tagify-dd-color-primary: rgb(53, 149, 246);
--tagify-dd-bg-color: white
}
.tagify {
--tags-border-color: #DDD;
--tags-hover-border-color: #CCC;
--tags-focus-border-color: #3595f6;
--tag-bg: #E5E5E5;
--tag-hover: #D3E2E2;
--tag-text-color: black;
--tag-text-color--edit: black;
--tag-pad: 0.3em 0.5em;
--tag-inset-shadow-size: 1.1em;
--tag-invalid-color: #D39494;
--tag-invalid-bg: rgba(211, 148, 148, 0.5);
--tag-remove-bg: rgba(211, 148, 148, 0.3);
--tag-remove-btn-color: black;
--tag-remove-btn-bg: none;
--tag-remove-btn-bg--hover: #c77777;
--input-color: inherit;
--tag--min-width: 1ch;
--tag--max-width: auto;
--tag-hide-transition: .3s;
--placeholder-color: rgba(0, 0, 0, 0.4);
--placeholder-color-focus: rgba(0, 0, 0, 0.25);
--loader-size: .8em;
display: flex;
align-items: flex-start;
flex-wrap: wrap;
border: 1px solid #ddd;
border: 1px solid var(--tags-border-color);
padding: 0;
line-height: 1.1;
cursor: text;
outline: 0;
position: relative;
transition: .1s
}
@keyframes tags--bump {
30% {
transform: scale(1.2)
}
}
@keyframes rotateLoader {
to {
transform: rotate(1turn)
}
}
.tagify:hover {
border-color: #ccc;
border-color: var(--tags-hover-border-color)
}
.tagify.tagify--focus {
transition: 0s;
border-color: #3595f6;
border-color: var(--tags-focus-border-color)
}
.tagify[readonly]:not(.tagify--mix) {
cursor: default
}
.tagify[readonly]:not(.tagify--mix)>.tagify__input {
visibility: hidden;
width: 0;
margin: 5px 0
}
.tagify[readonly]:not(.tagify--mix) .tagify__tag__removeBtn {
display: none
}
.tagify[readonly]:not(.tagify--mix) .tagify__tag>div {
padding: .3em .5em;
padding: var(--tag-pad)
}
.tagify[readonly]:not(.tagify--mix) .tagify__tag>div::before {
background: linear-gradient(45deg, var(--tag-bg) 25%, transparent 25%, transparent 50%, var(--tag-bg) 50%, var(--tag-bg) 75%, transparent 75%, transparent) 0/5px 5px;
box-shadow: none;
filter: brightness(.95)
}
.tagify--loading .tagify__input::before {
content: none
}
.tagify--loading .tagify__input::after {
content: '';
vertical-align: middle;
opacity: 1;
width: .7em;
height: .7em;
width: var(--loader-size);
height: var(--loader-size);
border: 3px solid;
border-color: #eee #bbb #888 transparent;
border-radius: 50%;
animation: rotateLoader .4s infinite linear;
margin: -2px 0 -2px .5em
}
.tagify--loading .tagify__input:empty::after {
margin-left: 0
}
.tagify+input,
.tagify+textarea {
display: none !important
}
.tagify__tag {
display: inline-flex;
align-items: center;
margin: 5px 0 5px 5px;
position: relative;
z-index: 1;
outline: 0;
cursor: default;
transition: .13s ease-out
}
.tagify__tag>div {
vertical-align: top;
box-sizing: border-box;
max-width: 100%;
padding: .3em .5em;
padding: var(--tag-pad);
color: #000;
color: var(--tag-text-color);
line-height: inherit;
border-radius: 3px;
-webkit-user-select: none;
user-select: none;
white-space: nowrap;
transition: .13s ease-out
}
.tagify__tag>div>* {
white-space: pre-wrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: top;
min-width: var(--tag--min-width);
max-width: var(--tag--max-width);
transition: .8s ease, .1s color
}
.tagify__tag>div>[contenteditable] {
outline: 0;
-webkit-user-select: text;
user-select: text;
cursor: text;
margin: -2px;
padding: 2px;
max-width: 350px
}
.tagify__tag>div::before {
content: '';
position: absolute;
border-radius: inherit;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: -1;
pointer-events: none;
transition: 120ms ease;
animation: tags--bump .3s ease-out 1;
box-shadow: 0 0 0 1.1em #e5e5e5 inset;
box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-bg) inset
}
.tagify__tag:hover:not([readonly]) div::before {
top: -2px;
right: -2px;
bottom: -2px;
left: -2px;
box-shadow: 0 0 0 1.1em #d3e2e2 inset;
box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-hover) inset
}
.tagify__tag--loading {
pointer-events: none
}
.tagify__tag--loading .tagify__tag__removeBtn {
display: none
}
.tagify__tag--loading::after {
--loader-size: .4em;
content: '';
vertical-align: middle;
opacity: 1;
width: .7em;
height: .7em;
width: var(--loader-size);
height: var(--loader-size);
border: 3px solid;
border-color: #eee #bbb #888 transparent;
border-radius: 50%;
animation: rotateLoader .4s infinite linear;
margin: 0 .5em 0 -.1em
}
.tagify__tag--flash div::before {
animation: none
}
.tagify__tag--hide {
width: 0 !important;
padding-left: 0;
padding-right: 0;
margin-left: 0;
margin-right: 0;
opacity: 0;
transform: scale(0);
transition: .3s;
transition: var(--tag-hide-transition);
pointer-events: none
}
.tagify__tag.tagify--noAnim>div::before {
animation: none
}
.tagify__tag.tagify--notAllowed:not(.tagify__tag--editable) div>span {
opacity: .5
}
.tagify__tag.tagify--notAllowed:not(.tagify__tag--editable) div::before {
box-shadow: 0 0 0 1.1em rgba(211, 148, 148, .5) inset !important;
box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-invalid-bg) inset !important;
transition: .2s
}
.tagify__tag[readonly] .tagify__tag__removeBtn {
display: none
}
.tagify__tag[readonly]>div::before {
background: linear-gradient(45deg, var(--tag-bg) 25%, transparent 25%, transparent 50%, var(--tag-bg) 50%, var(--tag-bg) 75%, transparent 75%, transparent) 0/5px 5px;
box-shadow: none;
filter: brightness(.95)
}
.tagify__tag--editable>div {
color: #000;
color: var(--tag-text-color--edit)
}
.tagify__tag--editable>div::before {
box-shadow: 0 0 0 2px #d3e2e2 inset !important;
box-shadow: 0 0 0 2px var(--tag-hover) inset !important
}
.tagify__tag--editable.tagify--invalid>div::before {
box-shadow: 0 0 0 2px #d39494 inset !important;
box-shadow: 0 0 0 2px var(--tag-invalid-color) inset !important
}
.tagify__tag__removeBtn {
order: 5;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50px;
cursor: pointer;
font: 14px/1 Arial;
background: 0 0;
background: var(--tag-remove-btn-bg);
color: #000;
color: var(--tag-remove-btn-color);
width: 14px;
height: 14px;
margin-right: 4.66667px;
margin-left: -4.66667px;
transition: .2s ease-out
}
.tagify__tag__removeBtn::after {
content: "\00D7"
}
.tagify__tag__removeBtn:hover {
color: #fff;
background: #c77777;
background: var(--tag-remove-btn-bg--hover)
}
.tagify__tag__removeBtn:hover+div>span {
opacity: .5
}
.tagify__tag__removeBtn:hover+div::before {
box-shadow: 0 0 0 1.1em rgba(211, 148, 148, .3) inset !important;
box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-remove-bg) inset !important;
transition: .2s
}
.tagify:not(.tagify--mix) .tagify__input br {
display: none
}
.tagify:not(.tagify--mix) .tagify__input * {
display: inline;
white-space: nowrap
}
.tagify__input {
flex-grow: 1;
display: inline-block;
min-width: 110px;
margin: 5px;
padding: .3em .5em;
padding: var(--tag-pad, .3em .5em);
line-height: inherit;
position: relative;
white-space: pre-wrap;
color: inherit;
color: var(--input-color)
}
.tagify__input:empty::before {
transition: .2s ease-out;
opacity: 1;
transform: none;
display: inline-block;
width: auto
}
.tagify--mix .tagify__input:empty::before {
display: inline-block
}
.tagify__input:focus {
outline: 0
}
.tagify__input:focus::before {
transition: .2s ease-out;
opacity: 0;
transform: translatex(6px)
}
@media all and (-ms-high-contrast:none),
(-ms-high-contrast:active) {
.tagify__input:focus::before {
display: none
}
}
@supports (-ms-ime-align:auto) {
.tagify__input:focus::before {
display: none
}
}
.tagify__input:focus:empty::before {
transition: .2s ease-out;
opacity: 1;
transform: none;
color: rgba(0, 0, 0, .25);
color: var(--placeholder-color-focus)
}
@-moz-document url-prefix() {
.tagify__input:focus:empty::after {
display: none
}
}
.tagify__input::before {
content: attr(data-placeholder);
height: 1em;
line-height: 1em;
margin: auto 0;
z-index: 1;
color: rgba(0, 0, 0, .4);
color: var(--placeholder-color);
white-space: nowrap;
pointer-events: none;
opacity: 0;
position: absolute
}
.tagify--mix .tagify__input::before {
display: none;
position: static;
line-height: inherit
}
.tagify__input::after {
content: attr(data-suggest);
display: inline-block;
white-space: pre;
color: #000;
opacity: .3;
pointer-events: none;
max-width: 100px
}
.tagify__input .tagify__tag {
margin: 0
}
.tagify__input .tagify__tag>div {
padding-top: 0;
padding-bottom: 0
}
.tagify--mix {
display: block
}
.tagify--mix .tagify__input {
padding: 5px;
margin: 0;
width: 100%;
height: 100%;
line-height: 1.5
}
.tagify--mix .tagify__input::before {
height: auto
}
.tagify--mix .tagify__input::after {
content: none
}
.tagify--select::after {
content: '>';
opacity: .5;
position: absolute;
top: 50%;
right: 0;
bottom: 0;
font: 16px monospace;
line-height: 8px;
height: 8px;
pointer-events: none;
transform: translate(-150%, -50%) scaleX(1.2) rotate(90deg);
transition: .2s ease-in-out
}
.tagify--select[aria-expanded=true]::after {
transform: translate(-150%, -50%) rotate(270deg) scaleY(1.2)
}
.tagify--select .tagify__tag {
position: absolute;
top: 0;
right: 1.8em;
bottom: 0
}
.tagify--select .tagify__tag div {
display: none
}
.tagify--select .tagify__input {
width: 100%
}
.tagify--invalid {
--tags-border-color: #D39494
}
.tagify__dropdown {
position: absolute;
z-index: 9999;
transform: translateY(1px);
overflow: hidden
}
.tagify__dropdown[placement=top] {
margin-top: 0;
transform: translateY(-100%)
}
.tagify__dropdown[placement=top] .tagify__dropdown__wrapper {
border-top-width: 1px;
border-bottom-width: 0
}
.tagify__dropdown[position=text] {
box-shadow: 0 0 0 3px rgba(var(--tagify-dd-color-primary), .1);
font-size: .9em
}
.tagify__dropdown[position=text] .tagify__dropdown__wrapper {
border-width: 1px
}
.tagify__dropdown__wrapper {
max-height: 300px;
overflow: hidden;
background: #fff;
background: var(--tagify-dd-bg-color);
border: 1px solid #3595f6;
border-color: var(--tagify-dd-color-primary);
border-top-width: 0;
box-shadow: 0 2px 4px -2px rgba(0, 0, 0, .2);
transition: .25s cubic-bezier(0, 1, .5, 1)
}
.tagify__dropdown__wrapper:hover {
overflow: auto
}
.tagify__dropdown--initial .tagify__dropdown__wrapper {
max-height: 20px;
transform: translateY(-1em)
}
.tagify__dropdown--initial[placement=top] .tagify__dropdown__wrapper {
transform: translateY(2em)
}
.tagify__dropdown__item {
box-sizing: inherit;
padding: .3em .5em;
margin: 1px;
cursor: pointer;
border-radius: 2px;
position: relative;
outline: 0
}
.tagify__dropdown__item--active {
background: #3595f6;
background: var(--tagify-dd-color-primary);
color: #fff
}
.tagify__dropdown__item:active {
filter: brightness(105%)
}

File diff suppressed because one or more lines are too long

View File

@@ -12,19 +12,6 @@
{% block additional_head %}
{% endblock additional_head %}
<script>
document.addEventListener("DOMContentLoaded", function(){
Array.from(document.getElementsByClassName('LP-Main__Sidebar')).forEach(function(element){
element.classList.add('LP-Main__Sidebar--hidden')
})
setTimeout(function(){
Array.from(document.getElementsByClassName('LP-Main__Sidebar')).forEach(function(element){
element.classList.remove('LP-Main__Sidebar--hidden')
})
}, 500)
})
</script>
</head>

View File

@@ -1,10 +1,15 @@
{% extends 'global.html'%}
{% load static %}
{% block additional_head %}
<link rel="stylesheet" href="{% static 'maps/ol.css' %}" type="text/css">
<script src="{% static 'maps/ol.js' %}"></script>
{% endblock additional_head %}
# {% block title %}Start{% endblock %}
{% block maincontent %}
{% include 'partials/osm_map.html' %}
<div class="LP-PlaceGrid">
<h1 class="LP-Headline LP-Headline">Explore the latest locations</h1>
<ul class="LP-PlaceGrid__Grid">

View File

@@ -0,0 +1,69 @@
<div id="map" class="map" style="height: 300px"></div>
<div id="info" class="map-popup"></div>
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
view: new ol.View({
center: ol.proj.fromLonLat([{{place_map_center|last}}, {{place_map_center|first}}]),
zoom: 9
})
});
var vectorSource = new ol.source.Vector({
features: [
{% for place in place_list %}
new ol.Feature({
geometry: new ol.geom.Point(
ol.proj.fromLonLat([{{place.longitude}},{{place.latitude}}])
),
url: '{% url 'place_detail' pk=place.pk %}',
name: '{{place.name}}'
}),
{% endfor %}
]
});
var markerVectorLayer = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
scale: 0.3,
src: 'http://icons.iconarchive.com/icons/paomedia/small-n-flat/128/map-marker-icon.png'
})
})
});
map.addLayer(markerVectorLayer);
var overlay = new ol.Overlay({
element: document.getElementById('info'),
positioning: 'bottom-left'
});
overlay.setMap(map);
map.on(['singleclick'], function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) {
window.open(feature.get('url'), '_blank');
});
});
map.on(['pointermove'], function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) {
overlay.setPosition(evt.coordinate.map(element => element + 1));
overlay.getElement().innerHTML = feature.get('name');
return feature;
});
overlay.getElement().style.display = feature ? '' : 'none';
document.body.style.cursor = feature ? 'pointer' : '';
});
</script>

View File

@@ -0,0 +1,41 @@
{% extends 'global.html'%}
{% block title %}Submit a photo album{% endblock %}
{% block additional_menu_items %}
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_edit' pk=place.pk %}" class="LP-Link"><span
class="LP-Link__Text">Edit place</span></a></li>
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_delete' pk=place.pk %}" class="LP-Link"><span
class="LP-Link__Text">Delete place</span></a></li>
{% endblock additional_menu_items %}
{% block maincontent %}
<form class="LP-Form" method="POST">
<fieldset class="LP-Form__Fieldset">
<legend class="LP-Form__Legend">Submit a photo album for {{place.name}}</legend>
{% csrf_token %}
<div class="LP-Form__Composition">
<div class="LP-Form__Field">
{% include 'partials/form/inputField.html' with field=form.url %}
</div>
</div>
<div class="LP-Form__Composition">
<div class="LP-Form__Field">
{% include 'partials/form/inputField.html' with field=form.label %}
</div>
</div>
<div class="LP-Form__Composition LP-Form__Composition--buttons">
<div class="LP-Form__Field LP-Form__Button LP-Input">
<button class="LP-Button">Submit</button>
</div>
<div class="LP-Form__Field LP-Form__Button LP-Input">
<a class="LP-Link" href="{% url 'place_detail' pk=place.id%}">
<button type="button" class="LP-Button LP-Button--cancel">Cancel</button>
</a>
</div>
</div>
</fieldset>
</form>
{% endblock maincontent %}

View File

@@ -1,53 +1,125 @@
{% extends 'global.html'%}
{% load static %}
{% load thumbnail %}
{% load svg_icon %}
{% block additional_head %}
<link rel="stylesheet" href="{% static 'maps/ol.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'tagify.css' %}">
<script src="{% static 'maps/ol.js' %}"></script>
<script src="{% static 'tagify.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'minimal.css' %}" type="text/css">
{% endblock additional_head %}
{% block title %}{{place.name}}{% endblock %}
{% block additional_menu_items %}
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_edit' pk=place.pk %}" class="LP-Link"><span class="LP-Link__Text">Edit place</span></a></li>
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_delete' pk=place.pk %}" class="LP-Link"><span class="LP-Link__Text">Delete place</span></a></li>
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_edit' pk=place.pk %}" class="LP-Link"><span
class="LP-Link__Text">Edit place</span></a></li>
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_delete' pk=place.pk %}" class="LP-Link"><span
class="LP-Link__Text">Delete place</span></a></li>
{% endblock additional_menu_items %}
{% block maincontent %}
<article class="LP-PlaceDetail">
<header class="LP-PlaceDetail__Header">
<h1 class="LP-Headline">{{ place.name }}</h1>
{% if place.images.first.filename.hero.url %}
<figure class="LP-PlaceDetail__Image">
<img src="{{ place.images.first.filename.hero.url }}" class="LP-Image" />
</figure>
{% endif %}
</header>
<header class="LP-PlaceDetail__Header">
<h1 class="LP-Headline">{{ place.name }}</h1>
{% if place.images.first.filename.hero.url %}
<figure class="LP-PlaceDetail__Image">
<img src="{{ place.images.first.filename.hero.url }}" class="LP-Image" />
</figure>
{% endif %}
</header>
<div class="LP-PlaceDetail__Description">
<p class="LP-Paragraph">{{ place.description }}</p>
</div>
<div class="LP-PlaceDetail__Description">
<p class="LP-Paragraph">{{ place.description }}</p>
</div>
<section class="LP-Section">
<h1 class="LP-Headline">Map-Links</h1>
{% include 'partials/osm_map.html' %}
<div class="LP-LinkList">
<ul class="LP-LinkList__Container">
<li class="LP-LinkList__Item"><a target="_blank"
href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}"
class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank"
href="https://www.tim-online.nrw.de/tim-online2/?center={{place.latitude}},{{place.longitude}}&icon=true&bg=dop"
class="LP-Link"><span class="LP-Text">TIM Online</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank"
href="http://www.openstreetmap.org/?mlat={{place.latitude}}&mlon={{place.longitude}}&zoom=16"
class="LP-Link"><span class="LP-Text">OSM</span></a></li>
</ul>
</div>
</section>
<section class="LP-Section">
<input name='basic' value='tag1, tag2'>
<script>
// The DOM element you wish to replace with Tagify
var input = document.querySelector('input[name=basic]');
// initialize Tagify on the above input node reference
new Tagify(input, {
'whitelist': ['wurstwasser']
})
</script>
</section>
<section class="LP-Section">
<h1 class="LP-Headline">Photoalben</h1>
<div class="LP-LinkList">
<ul class="LP-LinkList__Container">
{% for photo_album in place.photo_albums.all %}
<li class="LP-LinkList__Item">
<a target="_blank" href="{{photo_album.url}}" class="LP-Link">
<span class="LP-Text">{{photo_album.label}}</span>
</a>
{% if user == photo_album.submitted_by or user == place.submitted_by %}
<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
<div class="RV-Iconized__Container RV-Iconized__Container--small">
{% icon 'trash' className="RV-Iconized__Icon" %}
</div>
</a>
{% endif %}
</li>
{% endfor %}
<li class="LP-LinkList__Item">
<a href="{% url 'photo_album_create' place_id=place.id %}" class="LP-Link">
<div class="RV-Iconized__Container RV-Iconized__Container--small">
<svg class="RV-Iconized__Icon" version="1.1" id="Capa_1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 512 512" xml:space="preserve">
<g>
<path d="M492,236H276V20c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v216H20c-11.046,0-20,8.954-20,20s8.954,20,20,20h216
v216c0,11.046,8.954,20,20,20s20-8.954,20-20V276h216c11.046,0,20-8.954,20-20C512,244.954,503.046,236,492,236z" />
</g>
</svg>
<span class="RV-Iconized__Text">Fotoalbum hinzufügen</span>
</div>
</a>
</li>
</ul>
</div>
</section>
<section class="LP-Section">
<h1 class="LP-Headline">Bilder</h1>
<div class="LP-ImageGrid">
<ul class="LP-ImageGrid__Container">
{% for place_image in place.images.all %}
<li class="LP-ImageGrid__Item">
<a href="{{ place_image.filename.large.url }}" class="LP-Link"><img class="LP-Image"
src="{{ place_image.filename.thumbnail.url }}"></a>
</li>
{% endfor %}
</ul>
</div>
</section>
<section class="LP-Section">
<h1 class="LP-Headline">Map-Links</h1>
<div class="LP-LinkList">
<ul class="LP-LinkList__List">
<li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank" href="https://www.tim-online.nrw.de/tim-online2/?center={{place.latitude}},{{place.longitude}}&icon=true&bg=dop" class="LP-Link"><span class="LP-Text">TIM Online</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank" href="http://www.openstreetmap.org/?mlat={{place.latitude}}&mlon={{place.longitude}}&zoom=16" class="LP-Link"><span class="LP-Text">OSM</span></a></li>
</ul>
</div>
</section>
<section class="LP-Section">
<h1 class="LP-Headline">Bilder</h1>
<div class="LP-ImageGrid">
<ul class="LP-ImageGrid__List">
{% for place_image in place.images.all %}
<li class="LP-ImageGrid__Item">
<a href="{{ place_image.filename.large.url }}" class="LP-Link"><img class="LP-Image" src="{{ place_image.filename.thumbnail.url }}"></a>
</li>
{% endfor %}
</ul>
</div>
</section>
</article>
{% endblock maincontent %}

View File

@@ -1,9 +1,16 @@
{% extends 'global.html'%}
{% load static %}
{% block additional_head %}
<link rel="stylesheet" href="{% static 'maps/ol.css' %}" type="text/css">
<script src="{% static 'maps/ol.js' %}"></script>
{% endblock additional_head %}
{% block title %}Lost Places{% endblock %}
{% block maincontent %}
{% include 'partials/osm_map.html' %}
<div class="LP-PlaceList">
<h1 class="LP-Headline">Listing our places</h1>
<ul class="LP-PlaceList__List">

View File

@@ -0,0 +1,5 @@
<svg width="{{ width }}" height="{{ height }}" viewBox="{{viewBox}}" class="svg{% if className %} {{ className }}{% endif %}">
{% for path in paths %}
<path d="{{ path }}"></path>
{% endfor %}
</svg>

After

Width:  |  Height:  |  Size: 209 B

View File

@@ -0,0 +1,30 @@
import json
from importlib import import_module
from django.core.cache import cache
from django.conf import settings
from django.template import Library, TemplateSyntaxError
icons_json_path = getattr(settings, 'SVG_ICONS_SOURCE_FILE')
icons_json = json.load(open(icons_json_path))
register = Library()
@register.inclusion_tag('svg_icon/icon.html')
def icon(name, **kwargs):
icon_config = icons_json.get(name, None)
if icon_config:
width = kwargs.get('width', icon_config.get('width', 16))
height = kwargs.get('height', icon_config.get('heigh', 16))
viewBox = kwargs.get('viewBox', icon_config.get('viewBox', '0 0 1024 1024'))
return {
'width': kwargs.get('size', width),
'height': kwargs.get('size', height),
'className': kwargs.get('className'),
'viewBox': viewBox,
'paths': icon_config.get('paths', [''])
}

View File

@@ -6,7 +6,9 @@ from .views import (
SignUpView,
PlaceCreateView,
PlaceUpdateView,
PlaceDeleteView
PlaceDeleteView,
PhotoAlbumCreateView,
PhotoAlbumDeleteView
)
urlpatterns = [
@@ -14,6 +16,8 @@ urlpatterns = [
path('signup/', SignUpView.as_view(), name='signup'),
path('place/<int:pk>/', PlaceDetailView.as_view(), name='place_detail'),
path('place/create/', PlaceCreateView.as_view(), name='place_create'),
path('photo_album/create/<int:place_id>', PhotoAlbumCreateView.as_view(), name='photo_album_create'),
path('photo_album/delete/<int:pk>', PhotoAlbumDeleteView.as_view(), name='photo_album_delete'),
path('place/update/<int:pk>/', PlaceUpdateView.as_view(), name='place_edit'),
path('place/delete/<int:pk>/', PlaceDeleteView.as_view(), name='place_delete'),
path('place/', PlaceListView.as_view(), name='place_list')

View File

@@ -5,6 +5,7 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic import ListView
from django.views import View
from django.http import Http404
@@ -18,29 +19,43 @@ from .forms import (
PlaceForm,
PlaceImageCreateForm
)
from .models import Place, PlaceImage, Voucher
from .models import Place, PlaceImage, Voucher, PhotoAlbum
# Create your views here.
# BaseView that checks if user is logged in.
class IsAuthenticated(LoginRequiredMixin, View):
redirect_field_name = 'redirect_to'
login_required_message = 'Please login to proceed'
def handle_no_permission(self):
messages.error(self.request, self.login_required_message)
return super().handle_no_permission()
# BaseView that checks if logged in user is submitter of place.
class IsSubmitter(UserPassesTestMixin, View):
class IsPlaceSubmitter(UserPassesTestMixin, View):
place_submitter_error_message = None
def get_place(self):
pass
def test_func(self):
""" Check if user is eligible to modify place. """
if not hasattr(self.request, 'user'):
return False
if self.request.user.is_superuser:
return True
# Check if currently logged in user was the submitter
place_obj = self.get_object()
place_obj = self.get_place()
if self.request.user == place_obj.submitted_by:
if place_obj and hasattr(place_obj, 'submitted_by') and self.request.user == place_obj.submitted_by:
return True
messages.error(
self.request, 'You do not have permission to do this.')
if self.place_submitter_error_message:
messages.error(self.request, self.place_submitter_error_message)
return False
class SignUpView(SuccessMessageMixin, CreateView):
@@ -50,34 +65,49 @@ class SignUpView(SuccessMessageMixin, CreateView):
success_message = 'User created.'
class PlaceListView(IsAuthenticated, ListView):
paginate_by = 2
paginate_by = 5
model = Place
template_name = 'place/place_list.html'
ordering = ['name']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['place_map_center'] = Place.average_latlon(context['place_list'])
return context
class PlaceDetailView(IsAuthenticated, View):
def get(self, request, pk):
place = Place.objects.get(pk=pk)
context = {
'place': Place.objects.get(pk=pk)
'place': place,
'place_list': [ place ],
'place_map_center': [ place.latitude, place.longitude ]
}
return render(request, 'place/place_detail.html', context)
class HomeView(View):
def get(self, request, *args, **kwargs):
place_list = Place.objects.all().order_by('-submitted_when')[:10]
place_map_center = Place.average_latlon(place_list)
context = {
'place_list': place_list
'place_list': place_list,
'place_map_center': place_map_center
}
return render(request, 'home.html', context)
class PlaceUpdateView(IsAuthenticated, IsSubmitter, SuccessMessageMixin, UpdateView):
class PlaceUpdateView(IsAuthenticated, IsPlaceSubmitter, SuccessMessageMixin, UpdateView):
template_name = 'place/place_update.html'
model = Place
form_class = PlaceForm
success_message = 'Successfully updated place.'
place_submitter_error_message = 'You do no have permissions to alter this place'
def get_success_url(self):
return reverse_lazy('place_detail', kwargs={'pk':self.get_object().pk})
def get_place(self):
return self.get_object()
class PlaceCreateView(IsAuthenticated, View):
def get(self, request, *args, **kwargs):
@@ -134,13 +164,82 @@ class PlaceCreateView(IsAuthenticated, View):
)
place_image.save()
class PlaceDeleteView(IsAuthenticated, IsSubmitter, DeleteView):
class PlaceDeleteView(IsAuthenticated, IsPlaceSubmitter, DeleteView):
template_name = 'place/place_delete.html'
model = Place
success_message = 'Successfully deleted place.'
success_url = reverse_lazy('place_list')
success_message = 'Place deleted'
place_submitter_error_message = 'You do no have permission to delete this place'
def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message)
return super().delete(request, *args, **kwargs)
def get_place(self):
return self.get_object()
class AlbumCreateView(IsAuthenticated, View):
def get(self, request, *args, **kwargs):
url = request.GET['url']
place_id = request.GET['place_id']
place = Place.objects.get(pk=place_id)
photo_album = PhotoAlbum()
photo_album.url = url
photo_album.place = place
photo_album.submitted_by = request.user
photo_album.save()
print(photo_album)
return redirect(reverse_lazy('place_detail', kwargs={'pk': place_id}))
class PhotoAlbumCreateView(IsAuthenticated, SuccessMessageMixin, CreateView):
model = PhotoAlbum
fields = ['url', 'label']
template_name = 'photo_album/photo_album_create.html'
success_message = 'Photo Album submitted'
def get(self, request, place_id, *args, **kwargs):
self.place = Place.objects.get(pk=place_id)
return super().get(request, *args, **kwargs)
def post(self, request, place_id, *args, **kwargs):
self.place = Place.objects.get(pk=place_id)
response = super().post(request, *args, **kwargs)
self.object.place = self.place
self.object.submitted_by = request.user
self.object.save()
return response
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['place'] = self.place
return context
def get_success_url(self):
return reverse_lazy('place_detail', kwargs={'pk': self.place.id})
class PhotoAlbumDeleteView(IsAuthenticated, IsPlaceSubmitter, SingleObjectMixin, View):
model = PhotoAlbum
pk_url_kwarg = 'pk'
success_message = 'Photo Album deleted'
def get_place(self):
place_id = self.get_object().place.id
return Place.objects.get(pk=place_id)
def test_func(self):
can_edit_place = super().test_func()
if can_edit_place:
return True
if self.get_object().submitted_by == self.request.user:
return True
messages.error(self.request, 'You do not have permissions to alter this photo album')
return False
def get(self, request, *args, **kwargs):
place_id = self.get_object().place.id
self.get_object().delete()
messages.success(self.request, self.success_message)
return redirect(reverse_lazy('place_detail', kwargs={'pk': place_id}))

View File

@@ -16,16 +16,16 @@
<div class="LP-Form__Field">
{% include 'partials/form/inputField.html' with field=form.password %}
</div>
</div>
</div>
<div class="LP-Form__Composition LP-Form__Composition--buttons">
<div class="LP-Form__Field LP-Form__Button LP-Input">
<button class="LP-Button">Login</button>
</div>
</div>
</div>
<div class="LP-Form__Composition LP-Form__Composition--buttons">
<div class="LP-Form__Field LP-Form__Button LP-Input">
<button class="LP-Button">Login</button>
</div>
</div>
</fieldset>
</form>
<p class="LP-Headline">No account? <a class="LP-Link" href="{% url 'signup' %}"><span class="LP-Link__Text">Sign up here</span></a></p>
{% endblock maincontent %}