Initial commit

This commit is contained in:
2025-07-15 23:39:10 +02:00
parent 1d3986a901
commit fb14214612
181 changed files with 31070 additions and 50 deletions

View File

@ -0,0 +1,64 @@
<div class="sp_nav sp_nav__vertical">
<a href="{{ path('bo_dashboard') }}" class="sp_nav__item {% if route == 'bo_dashboard' %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">Contributors<br>Tracking</span>
</a>
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('bo_region_index') }}" class="sp_nav__item {% if route|start_with('bo_region') %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">Regions</span>
</a>
{% endif %}
<a href="{{ path('bo_item_category_index') }}" class="sp_nav__item {% if route|start_with('bo_item') %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">Items<br>Categories</span>
</a>
{% if route|start_with('bo_item') %}
{% for _category in itemsCategories %}
<a href="{{ path('bo_item_index', {'itemCategoryId': _category.id}) }}" class="sp_nav__item sp_nav__sub-item {% if not route|start_with('bo_item_category') and itemCategory is defined and itemCategory.id == _category.id %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">{{ _category|split(' ')|join('<br>')|raw }}</span>
</a>
{% endfor %}
{% endif %}
<a href="{{ path('bo_monster_category_index') }}" class="sp_nav__item {% if route|start_with('bo_monster') %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">Monsters<br>Categories</span>
</a>
{% if route|start_with('bo_monster') %}
{% for _category in monstersCategories %}
<a href="{{ path('bo_monster_index', {'monsterCategoryId': _category.id}) }}" class="sp_nav__item sp_nav__sub-item {% if not route|start_with('bo_monster_category') and monsterCategory is defined and monsterCategory.id == _category.id %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">{{ _category|split(' ')|join('<br>')|raw }}</span>
</a>
{% endfor %}
{% endif %}
<a href="{{ path('bo_worldmark_category_index') }}" class="sp_nav__item {% if route|start_with('bo_worldmark') %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">Worldmarks<br>Categories</span>
</a>
{% if route|start_with('bo_worldmark') %}
{% for _category in worldmarksCategories %}
<a href="{{ path('bo_worldmark_index', {'worldmarkCategoryId': _category.id}) }}" class="sp_nav__item sp_nav__sub-item {% if not route|start_with('bo_worldmark_category') and worldmarkCategory is defined and worldmarkCategory.id == _category.id %}sp_nav__active{% endif %}">
<span class="sp_nav__indicator"></span>
<span class="sp_nav__cursor"></span>
<span class="sp_nav__underline"></span>
<span class="sp_nav__title">{{ _category|split(' ')|join('<br>')|raw }}</span>
</a>
{% endfor %}
{% endif %}
</div>

View File

@ -0,0 +1,11 @@
{% extends 'base.html.twig' %}
{% block body %}
<div id="main-section-container" class="sp_section_container__horizontal">
{#<a href="{{ path('bo_region_index') }}">Regions</a>#}
{% include '_dashboard/_menu.html.twig' %}
<div class="sp_dashboard__container">
{% block page_content %}{% endblock %}
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,5 @@
<form method="post" action="{{ path('bo_region_grid_delete', {'regionId': region.id, 'id': grid.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ grid.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,9 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Create new Grid</h1>
{{ include('_dashboard/grid/_form.html.twig') }}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id}) }}">back to list</a>
{% endblock %}

View File

@ -0,0 +1,28 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Grid</h1>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ grid.id }}</td>
</tr>
<tr>
<th>Row</th>
<td>{{ grid.row }}</td>
</tr>
<tr>
<th>Col</th>
<td>{{ grid.col }}</td>
</tr>
</tbody>
</table>
<a href="{{ path('bo_region_grid_index', {'regionId': region.id}) }}">back to list</a>
<a href="{{ path('bo_region_grid_edit', {'regionId': region.id, 'id': grid.id}) }}">edit</a>
{{ include('_dashboard/grid/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,28 @@
{% for _log in logs %}
<div>{{ _log }}</div>
{% endfor %}
{{ form_start(form) }}
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.positions, null, {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.positions %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.positions.setRendered %}
</div>
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_region_index') }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,11 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Edit {{ region.name }}'s Grid</h1>
{{ include('_dashboard/grid/_form.html.twig', {'button_label': 'Update'}) }}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id}) }}">back to list</a>
{# {{ include('_dashboard/grid/_delete_form.html.twig') }}#}
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% set previousVersion = null %}
{% set nextVersion = null %}
{% for _gameVersion in supportedGameVersion %}
{% if _gameVersion < version %}
{% set previousVersion = _gameVersion %}
{% endif %}
{% if nextVersion is null and _gameVersion > version %}
{% set nextVersion = _gameVersion %}
{% endif %}
{% endfor %}
<div id="map-editor">
<div class="sp_map_editor__header_container">
{% if version > supportedGameVersion|first %}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id, 'v': previousVersion}) }}"><img src="{{ asset(assets.img.ui~'back.png') }}" alt></a>
{% else %}
<div class="sp_grayscale"><img src="{{ asset(assets.img.ui~'back.png') }}" alt></div>
{% endif %}
<div>Game version : {{ version }}</div>
{% if version < supportedGameVersion|last %}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id, 'v': nextVersion}) }}"><img src="{{ asset(assets.img.ui~'forward.png') }}" alt></a>
{% else %}
<div class="sp_grayscale"><img src="{{ asset(assets.img.ui~'forward.png') }}" alt></div>
{% endif %}
</div>
<div class="sp_grid__container sp_map_editor__grid_container" data-region-width="{{ region.gridWidth }}" data-region-height="{{ region.gridHeight }}">
{% for row in 1..region.gridHeight %}
{% for col in 1..region.gridWidth %}
<div class="sp_grid__cell">
{% set idHash = '_g' ~ grid[row][col]['id'] ~ '_v' ~ version %}
<img id="{{ 'map' ~ idHash }}" class="sp_grid__map" {% if grid[row][col]['map_data']['map'].id is not null %}data-src="{{ asset(assets.map.upload_path ~ grid[row][col]['map_data']['map'].file) }}"{% endif%} src="{{ asset(assets.img._black) }}" alt="{{ region.name }}" draggable="false">
{% include '_dashboard/map/_form.html.twig' with {'form': grid[row][col]['map_data']['form'], 'idHash': idHash} %}
</div>
{% endfor %}
{% endfor %}
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,50 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% set previousVersion = null %}
{% set nextVersion = null %}
{% for _gameVersion in supportedGameVersion %}
{% if _gameVersion < version %}
{% set previousVersion = _gameVersion %}
{% endif %}
{% if nextVersion is null and _gameVersion > version %}
{% set nextVersion = _gameVersion %}
{% endif %}
{% endfor %}
<div id="map-editor">
<div class="sp_map_editor__header_container">
{% if version > supportedGameVersion|first %}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id, 'v': previousVersion}) }}"><img src="{{ asset(assets.img.ui~'back.png') }}" alt></a>
{% else %}
<div class="sp_grayscale"><img src="{{ asset(assets.img.ui~'back.png') }}" alt></div>
{% endif %}
<div>Game version : {{ version }}</div>
{% if version < supportedGameVersion|last %}
<a href="{{ path('bo_region_grid_index', {'regionId': region.id, 'v': nextVersion}) }}"><img src="{{ asset(assets.img.ui~'forward.png') }}" alt></a>
{% else %}
<div class="sp_grayscale"><img src="{{ asset(assets.img.ui~'forward.png') }}" alt></div>
{% endif %}
</div>
<div class="sp_map_editor__grid_container">
<div class="sp_grid__container">
{% for row in 1..region.gridHeight %}
<div class="sp_grid__row">
{% for col in 1..region.gridWidth %}
<div class="sp_grid__column">
{% set idHash = '_g' ~ grid[row][col]['id'] ~ '_v' ~ version %}
<img id="{{ 'map' ~ idHash }}" class="sp_grid__map" {% if grid[row][col]['map_data']['map'].id is not null %}data-src="{{ asset(assets.map.upload_path ~ grid[row][col]['map_data']['map'].file) }}"{% endif%} src="{{ asset(assets.img._black) }}" alt="{{ region.name }}" draggable="false">
{% include '_dashboard/map/_form.html.twig' with {'form': grid[row][col]['map_data']['form'], 'idHash': idHash} %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_item_delete', {'itemCategoryId': itemCategory.id, 'id': item.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ item.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,40 @@
{{ form_start(form, {'attr': {'class': 'sp_form__xhr'}}) }}
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__textarea">
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.icon) }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="item-icon-preview" src="{{ asset(item.icon ? assets.item.upload_path ~ item.icon : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.icon, {'attr': {'data-file-preview-target': 'item-icon-preview'}}) }}
</div>
<div class="sp_form-row__select">
{{ form_label(form.version) }}
{{ form_widget(form.version) }}
</div>
{% if route|end_with('_edit') %}
<div>
{{ form_label(form.removeFile) }}
{{ form_widget(form.removeFile) }}
</div>
{% endif %}
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_item_index', {'itemCategoryId': itemCategory.id}) }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,11 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Edit Item</h1>
{{ include('_dashboard/item/_form.html.twig', {'button_label': 'Update'}) }}
<a href="{{ path('bo_item_index', {'itemCategoryId': itemCategory.id}) }}">back to list</a>
{{ include('_dashboard/item/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_SENIOR') %}
<p>
<a href="{{ path('bo_item_new', {'itemCategoryId': itemCategory.id}) }}">Create new</a>
</p>
{% endif %}
<table class="table">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
<th>Description</th>
{#<th>Icon</th>#}
<th>Version</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
{#<td>{{ item.id }}</td>#}
<td><img {% if item.icon %}data-src="{{ asset(assets.item.upload_path ~ item.icon) }}"{% endif %} src="{{ asset(assets.img._black_xs) }}" alt="{{ item.name }}" style="height: 48px; width: auto;"> {{ item.name }}</td>
<td>{{ item.slug }}</td>
<td>{{ item.description }}</td>
{#<td>{{ item.icon }}</td>#}
<td>{{ item.version }}</td>
{% if is_granted('ROLE_SENIOR') %}
<td>
<a href="{{ path('bo_item_edit', {'itemCategoryId': itemCategory.id, 'id': item.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_SENIOR') ? '4' : '3' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Create new Item</h1>
{{ include('_dashboard/item/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_item_category_delete', {'id': itemCategory.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ itemCategory.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,22 @@
{{ form_start(form) }}
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.sortOrder) }}
{{ form_widget(form.sortOrder) }}
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_item_category_index') }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,9 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Edit ItemCategory</h1>
{{ include('_dashboard/item_category/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/item_category/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,42 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_ADMIN') %}
<p>
<a href="{{ path('bo_item_category_new') }}">Create new</a>
</p>
{% endif %}
<table class="table">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
<th>SortOrder</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for _itemCategory in itemsCategories %}
<tr>
{#<td>{{ _itemCategory.id }}</td>#}
<td>{{ _itemCategory.name }}</td>
<td>{{ _itemCategory.slug }}</td>
<td>{{ _itemCategory.sortOrder }}</td>
{% if is_granted('ROLE_ADMIN') %}
<td>
<a href="{{ path('bo_item_category_edit', {'id': _itemCategory.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_ADMIN') ? '4' : '3' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Create new ItemCategory</h1>
{{ include('_dashboard/item_category/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_map_delete', {'id': map.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ map.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,11 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Edit Map</h1>
{{ include('map/_form.html.twig', {'button_label': 'Update'}) }}
<a href="{{ path('bo_map_index') }}">back to list</a>
{{ include('map/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Map index</h1>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>File</th>
<th>ModifiedAt</th>
<th>Version</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for map in maps %}
<tr>
<td>{{ map.id }}</td>
<td>{{ map.file }}</td>
<td>{{ map.modifiedAt ? map.modifiedAt|date('Y-m-d H:i:s') : '' }}</td>
<td>{{ map.version }}</td>
<td>
{#<a href="{{ path('map_show', {'id': map.id}) }}">show</a>#}
<a href="{{ path('bo_map_edit', {'id': map.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="5">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('bo_map_new') }}">Create new</a>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Create new Map</h1>
{{ include('map/_form.html.twig') }}
<a href="{{ path('bo_map_index') }}">back to list</a>
{% endblock %}

View File

@ -0,0 +1,32 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Map</h1>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ map.id }}</td>
</tr>
<tr>
<th>File</th>
<td>{{ map.file }}</td>
</tr>
<tr>
<th>ModifiedAt</th>
<td>{{ map.modifiedAt ? map.modifiedAt|date('Y-m-d H:i:s') : '' }}</td>
</tr>
<tr>
<th>Version</th>
<td>{{ map.version }}</td>
</tr>
</tbody>
</table>
<a href="{{ path('bo_map_index') }}">back to list</a>
<a href="{{ path('bo_map_edit', {'id': map.id}) }}">edit</a>
{{ include('map/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,10 @@
{{ form_start(form, {'name': "", 'attr': {'class': 'sp_grid__map-form sp_form__xhr sp_form__onchange'}}) }}
{{ form_widget(form.file, {'id': 'map_file' ~ idHash, 'attr': {'data-file-preview-target': 'map' ~ idHash}}) }}
{% if route|end_with('_new') %}
{{ form_widget(form.version, {'id': 'map_version' ~ idHash}) }}
{% endif %}
{{ form_widget(form._token, {'id': 'map__token' ~ idHash}) }}
{#<button class="btn">Save</button>#}
{{ form_end(form) }}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_monster_delete', {'monsterCategoryId': monsterCategory.id, 'id': monster.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ monster.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,40 @@
{{ form_start(form, {'attr': {'class': 'sp_form__xhr'}}) }}
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__textarea">
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.icon) }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="item-icon-preview" src="{{ asset(monster.icon ? assets.monster.upload_path ~ monster.icon : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.icon, {'attr': {'data-file-preview-target': 'item-icon-preview'}}) }}
</div>
<div class="sp_form-row__select">
{{ form_label(form.version) }}
{{ form_widget(form.version) }}
</div>
{% if route|end_with('_edit') %}
<div>
{{ form_label(form.removeFile) }}
{{ form_widget(form.removeFile) }}
</div>
{% endif %}
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_monster_index', {'monsterCategoryId': monsterCategory.id}) }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,11 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Edit Monster</h1>
{{ include('_dashboard/monster/_form.html.twig', {'button_label': 'Update'}) }}
<a href="{{ path('bo_monster_index', {'monsterCategoryId': monsterCategory.id}) }}">back to list</a>
{{ include('_dashboard/monster/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_SENIOR') %}
<p>
<a href="{{ path('bo_monster_new', {'monsterCategoryId': monsterCategory.id}) }}">Create new</a>
</p>
{% endif %}
<table class="table">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
<th>Description</th>
{#<th>Icon</th>#}
<th>Version</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for monster in monsters %}
<tr>
{#<td>{{ monster.id }}</td>#}
<td><img {% if monster.icon %}data-src="{{ asset(assets.monster.upload_path ~ monster.icon) }}"{% endif %} src="{{ asset(assets.img._black_xs) }}" alt="{{ monster.name }}" style="height: 48px; width: auto;"> {{ monster.name }}</td>
<td>{{ monster.slug }}</td>
<td>{{ monster.description }}</td>
{#<td>{{ monster.icon }}</td>#}
<td>{{ monster.version }}</td>
{% if is_granted('ROLE_SENIOR') %}
<td>
<a href="{{ path('bo_monster_edit', {'monsterCategoryId': monsterCategory.id, 'id': monster.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_SENIOR') ? '4' : '3' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Create new Monster</h1>
{{ include('_dashboard/monster/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_monster_category_delete', {'id': monsterCategory.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ monsterCategory.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,18 @@
{{ form_start(form) }}
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_monster_category_index') }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,9 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Edit MonsterCategory</h1>
{{ include('_dashboard/monster_category/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/monster_category/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,40 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_ADMIN') %}
<p>
<a href="{{ path('bo_monster_category_new') }}">Create new</a>
</p>
{% endif %}
<table class="table">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for monsterCategory in monstersCategories %}
<tr>
{#<td>{{ monsterCategory.id }}</td>#}
<td>{{ monsterCategory.name }}</td>
<td>{{ monsterCategory.slug }}</td>
{% if is_granted('ROLE_ADMIN') %}
<td>
<a href="{{ path('bo_monster_category_edit', {'id': monsterCategory.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_ADMIN') ? '3' : '2' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<h1>Create new MonsterCategory</h1>
{{ include('_dashboard/monster_category/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,15 @@
{{ form_start(form, {'attr': {'class': 'sp_modal sp_modal__warn sp_form__xhr'}}) }}
<div class="sp_modal__body">
<div>Do you really want to delete this node?</div>
<div>This action can't be canceled.</div>
</div>
<div class="sp_form-row__button">
<button class="sp_button" data-type="validate" type="button">
<span>Cancel</span>
</button>
<button class="sp_button" data-type="cancel" type="submit">
<span>Delete</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,114 @@
{#<div class="sp_panel__header"></div>#}
<div class="sp_panel__content">
{{ form_start(form, {'attr': {'id': 'node-form', 'class': 'sp_form__xhr'}}) }}
<section class="sp_panel__section">
<div class="sp_panel__section-title">
<label>1) Drag and place the node to the desired location</label>
</div>
<div class="sp_form-row_inline-container">
<div class="sp_form-row__text">
{{ form_label(form.coordX, 'Pos X') }}
{{ form_widget(form.coordX) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.coordY, 'Pos Y') }}
{{ form_widget(form.coordY) }}
</div>
</div>
<div class="sp_panel__section-title">
<label>2) Set quantity</label>
</div>
<div class="sp_form-row__text">
{{ form_label(form.quantity) }}
{{ form_widget(form.quantity) }}
</div>
<div class="sp_panel__section-title">
<label>3) Set primogems quantity</label>
</div>
<div class="sp_form-row__text">
{{ form_label(form.primogem) }}
{{ form_widget(form.primogem) }}
</div>
<div class="sp_panel__section-title">
<label>4) Write some helping text </label>
</div>
<div class="sp_form-row__textarea">
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="sp_panel__section-title">
<label>5) Add a screenshot if any</label>
</div>
<div class="sp_form-row__file">
{{ form_label(form.screenshotA, 'Screenshot 1') }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="screenshot-a-preview" src="{{ asset(node.screenshotA ? assets.screenshot.thumbnail_path ~ node.screenshotA : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.screenshotA, {'attr': {'class': 'sp_input__format-screenshot', 'data-file-preview-target': 'screenshot-a-preview'}}) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.screenshotB, 'Screenshot 2') }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="screenshot-b-preview" src="{{ asset(node.screenshotB ? assets.screenshot.thumbnail_path ~ node.screenshotB : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.screenshotB, {'attr': {'class': 'sp_input__format-screenshot', 'data-file-preview-target': 'screenshot-b-preview'}}) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.screenshotC, 'Screenshot 3') }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="screenshot-c-preview" src="{{ asset(node.screenshotC ? assets.screenshot.thumbnail_path ~ node.screenshotC : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.screenshotC, {'attr': {'class': 'sp_input__format-screenshot', 'data-file-preview-target': 'screenshot-c-preview'}}) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.screenshotD, 'Screenshot 4') }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="screenshot-d-preview" src="{{ asset(node.screenshotD ? assets.screenshot.thumbnail_path ~ node.screenshotD : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.screenshotD, {'attr': {'class': 'sp_input__format-screenshot', 'data-file-preview-target': 'screenshot-d-preview'}}) }}
</div>
<div class="sp_form-row__file">
{{ form_label(form.screenshotE, 'Screenshot 5') }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="screenshot-e-preview" src="{{ asset(node.screenshotE ? assets.screenshot.thumbnail_path ~ node.screenshotE : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.screenshotE, {'attr': {'class': 'sp_input__format-screenshot', 'data-file-preview-target': 'screenshot-e-preview'}}) }}
</div>
<div class="sp_panel__section-title">
<label>6) Add YouTube video link if any</label>
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.version, null, {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.version %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.version.setRendered %}
</div>
</div>
<div class="sp_form-row__button">
<button class="sp_button" data-type="cancel" type="button">
<span>Cancel</span>
</button>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
</section>
{{ form_end(form) }}
<label id="node-form-coordinate-tracker" class="sp_node__item" hidden>
<span class="sp_node__background">
<img src="{{ asset(worldmark.icon ? assets.worldmark.upload_path ~ worldmark.icon : assets.img._blank_xs) }}" alt>
</span>
<span class="sp_node__guidelines"></span>
</label>
</div>

View File

@ -0,0 +1,11 @@
{% extends 'base.html.twig' %}
{% block title %}Edit Node{% endblock %}
{% block body %}
<h1>Edit Node</h1>
{{ include('_dashboard/node/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/node/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends 'base.html.twig' %}
{% block title %}Node index{% endblock %}
{% block body %}
<h1>Node index</h1>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Quantity</th>
<th>Coordinate</th>
<th>Youtube</th>
<th>CreateAt</th>
<th>ModifiedAt</th>
<th>Version</th>
<th>IsDeleted</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for node in nodes %}
<tr>
<td>{{ node.id }}</td>
<td>{{ node.quantity }}</td>
<td>{{ node.coordinate ? node.coordinate|json_encode : '' }}</td>
<td>{{ node.youtube }}</td>
<td>{{ node.createAt ? node.createAt|date('Y-m-d H:i:s') : '' }}</td>
<td>{{ node.modifiedAt ? node.modifiedAt|date('Y-m-d H:i:s') : '' }}</td>
<td>{{ node.version }}</td>
<td>{{ node.isDeleted ? 'Yes' : 'No' }}</td>
<td>
<a href="{{ path('bo_node_edit', {'id': node.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="9">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{#<a href="{{ path('bo_node_new') }}">Create new</a>#}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends 'base.html.twig' %}
{% block title %}New Node{% endblock %}
{% block body %}
<h1>Create new Node</h1>
{{ include('_dashboard/node/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,48 @@
{% extends 'base.html.twig' %}
{% block title %}Node{% endblock %}
{% block body %}
<h1>Node</h1>
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ node.id }}</td>
</tr>
<tr>
<th>Quantity</th>
<td>{{ node.quantity }}</td>
</tr>
<tr>
<th>Coordinate</th>
<td>{{ node.coordinate ? node.coordinate|json_encode : '' }}</td>
</tr>
<tr>
<th>Youtube</th>
<td>{{ node.youtube }}</td>
</tr>
<tr>
<th>CreateAt</th>
<td>{{ node.createAt ? node.createAt|date('Y-m-d H:i:s') : '' }}</td>
</tr>
<tr>
<th>ModifiedAt</th>
<td>{{ node.modifiedAt ? node.modifiedAt|date('Y-m-d H:i:s') : '' }}</td>
</tr>
<tr>
<th>Version</th>
<td>{{ node.version }}</td>
</tr>
<tr>
<th>IsDeleted</th>
<td>{{ node.isDeleted ? 'Yes' : 'No' }}</td>
</tr>
</tbody>
</table>
<a href="{{ path('bo_node_edit', {'gridId': grid.id, 'worldmarkId': worldmark.id, 'id': node.id}) }}">edit</a>
{{ include('node/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_region_delete', {'id': region.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ region.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,108 @@
{{ form_start(form) }}
<div class="sp_form-row__select">
{{ form_label(form.parentRegion) }}
{{ form_widget(form.parentRegion) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.isAlias, 'Is it an alias of parent region ?', {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.isAlias %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.isAlias.setRendered %}
</div>
</div>
<div class="sp_form-row__text">
{{ form_label(form.anchor, 'Alias anchor') }}
{{ form_widget(form.anchor) }}
</div>
<div class="sp_form-row__textarea">
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="sp_form-row__radio sp_radio__layout-inline sp_radio__style-button">
<div class="sp_radio__container">
{% for key, choice in form.icon %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-icon">
<img src="{{ asset(choice.vars.name == 'placeholder' ? assets.img.none : assets.img.region~choice.vars.value) }}" alt="{{ choice.vars.value }}">
</span>
<input name="{{ choice.vars.full_name }}" type="radio" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.icon.setRendered %}
</div>
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.mapBackground, 'Is region active ?', {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.mapBackground %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.mapBackground.setRendered %}
</div>
</div>
{% if route|end_with('_new') %}
<div class="sp_form-row__text">
{{ form_label(form.gridHeight) }}
{{ form_widget(form.gridHeight) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.gridWidth) }}
{{ form_widget(form.gridWidth) }}
</div>
{% endif %}
<div class="sp_form-row__select">
{{ form_label(form.version) }}
{{ form_widget(form.version) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.sortOrder) }}
{{ form_widget(form.sortOrder) }}
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.isActive, 'Is region active ?', {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.isActive %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.isActive.setRendered %}
</div>
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_region_index') }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/region/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/region/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,69 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
<table class="table" style="width: 100%;">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
{#<th>Icon</th>#}
{#<th>GridHeight</th>#}
{#<th>GridWidth</th>#}
<th>Version</th>
<th>SortOrder</th>
<th>isActive</th>
<th style="width: 260px">actions</th>
</tr>
</thead>
<tbody>
{% for _region in regions %}
<tr>
{#<td>{{ region.id }}</td>#}
<td><img {% if _region.icon %}data-src="{{ asset(assets.img.region ~ _region.icon) }}{% endif %}" src="{{ asset(assets.img._black_xs) }}" alt style="height: 48px; width: auto;"> {{ _region.name }}</td>
{#<td>{{ region.icon }}</td>#}
{#<td>{{ region.gridHeight }}</td>#}
{#<td>{{ region.gridWidth }}</td>#}
<td>{{ _region.version }}</td>
<td>{{ _region.sortOrder }}</td>
<td>{{ _region.isActive ? 'yes' : 'no' }}</td>
<td>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); text-align: center">
<a href="{{ path('bo_region_grid_index', {'regionId': _region.id}) }}">Show map</a>
<a href="{{ path('bo_region_edit', {'id': _region.id}) }}">Edit region</a>
<a href="{{ path('bo_region_grid_edit', {'regionId': _region.id}) }}">Edit grid</a>
</div>
</td>
</tr>
{% for _subRegion in _region.subRegions %}
<tr>
{#<td>{{ region.id }}</td>#}
<td><img src="{{ asset(_subRegion.icon ? assets.img.region ~ _subRegion.icon : assets.img._black_xs) }}" alt style="height: 48px; width: auto;"> {{ _subRegion.name }}</td>
{#<td>{{ region.icon }}</td>#}
{#<td>{{ region.gridHeight }}</td>#}
{#<td>{{ region.gridWidth }}</td>#}
<td>{{ _subRegion.version }}</td>
<td>{{ _subRegion.sortOrder }}</td>
<td>{{ _subRegion.isActive ? 'yes' : 'no' }}</td>
<td>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); text-align: center">
{% if _subRegion.isAlias %}
<a href="{{ path('bo_region_edit', {'id': _subRegion.id}) }}">Edit region</a>
{% else %}
<a href="{{ path('bo_region_grid_index', {'regionId': _subRegion.id}) }}" style="margin-right: 20px;">Show map</a>
<a href="{{ path('bo_region_edit', {'id': _subRegion.id}) }}">Edit region</a>
<a href="{{ path('bo_region_grid_edit', {'regionId': _region.id}) }}">Edit grid</a>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="6">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('bo_region_new') }}">Create new</a>
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/region/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_worldmark_delete', {'worldmarkCategoryId': worldmarkCategory.id, 'id': worldmark.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ worldmark.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,82 @@
<div class="sp_form-row__select" {{ route|end_with('_edit') ? 'hidden' }}>
<label for="worldmark__content-filter">Worldmark type</label>
<select id="worldmark__content-filter">
<option value></option>
<option value="item" {{ worldmark.id is not null and worldmark.item is not null ? 'selected' : '' }}>Item</option>
<option value="monster" {{ worldmark.id is not null and worldmark.monster is not null ? 'selected' : '' }}>Monster</option>
<option value="custom" {{ worldmark.id is not null and worldmark.item is null and worldmark.monster is null ? 'selected' : '' }}>Custom</option>
</select>
</div>
{{ form_start(form, {'attr': {'id': 'form__worldmark', 'class': 'sp_form__xhr', 'data-content-for': 'worldmark__content-filter', 'data-filter-values': ['item','monster', 'custom']|json_encode, 'hidden': true}}) }}
<div class="sp_form-row__select" data-content-for="worldmark__content-filter" data-filter-values="item" hidden>
{{ form_label(form.item) }}
{{ form_widget(form.item) }}
</div>
<div class="sp_form-row__select" data-content-for="worldmark__content-filter" data-filter-values="monster" hidden>
{{ form_label(form.monster) }}
{{ form_widget(form.monster) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__textarea" data-content-for="worldmark__content-filter" data-filter-values="custom" hidden>
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.defaultQuantityValue) }}
{{ form_widget(form.defaultQuantityValue) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.defaultPrimogemValue) }}
{{ form_widget(form.defaultPrimogemValue) }}
</div>
<div class="sp_form-row__file" data-content-for="worldmark__content-filter" data-filter-values="custom" hidden>
{{ form_label(form.icon) }}
<input name="file-path" type="text" disabled>
<span class="sp_input__file-preview">
<img id="worldmark-icon-preview" src="{{ asset(worldmark.icon ? assets.worldmark.upload_path ~ worldmark.icon : assets.img._blank_xs) }}" alt>
</span>
{{ form_widget(form.icon, {'attr': {'data-file-preview-target': 'worldmark-icon-preview'}}) }}
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-b sp_radio__style-text">
{{ form_label(form.regions, null, {'label_attr': {'class': 'sp_radio__main-label'}}) }}
<div class="sp_radio__container">
{% for key, choice in form.regions %}
<label class="sp_radio__input-wrapper" title="{{ choice.vars.label }}">
{#<span class="sp_radio__input-icon"></span>#}
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">{{ choice.vars.label }}</span>
<input name="{{ choice.vars.full_name }}" type="{{ choice.parent.vars.multiple ? 'checkbox' : 'radio' }}" value="{{ choice.vars.value }}" {% if key == 0 and choice.vars.required %}required{% endif%} {% if choice.vars.checked %}checked{% endif %}>
</label>
{% endfor %}
{% do form.regions.setRendered %}
</div>
</div>
<br>
{{ form_row(form.canBeHidden) }}
<br>
<div class="sp_form-row__select">
{{ form_label(form.version) }}
{{ form_widget(form.version) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.sortOrder) }}
{{ form_widget(form.sortOrder) }}
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_worldmark_index', {'worldmarkCategoryId': worldmarkCategory.id}) }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/worldmark/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/worldmark/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_SENIOR') %}
<p>
<a href="{{ path('bo_worldmark_new', {'worldmarkCategoryId': worldmarkCategory.id}) }}">Create new</a>
</p>
{% endif %}
<table class="table">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
<th>Description</th>
<th>SortOrder</th>
<th>Version</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for worldmark in worldmarks %}
<tr>
{#<td>{{ worldmark.id }}</td>#}
<td><img {% if worldmark.icon %}data-src="{{ asset(assets.worldmark.upload_path ~ worldmark.icon) }}"{% endif %} src="{{ asset(assets.img._black_xs) }}" alt="{{ worldmark.name }}" style="height: 48px; width: auto;"> {{ worldmark.name }}</td>
<td>{{ worldmark.slug }}</td>
<td>{{ worldmark.description }}</td>
<td>{{ worldmark.sortOrder }}</td>
<td>{{ worldmark.version }}</td>
{% if is_granted('ROLE_SENIOR') %}
<td>
<a href="{{ path('bo_worldmark_edit', {'worldmarkCategoryId': worldmarkCategory.id, 'id': worldmark.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_SENIOR') ? '5' : '6' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/worldmark/_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,4 @@
<form method="post" action="{{ path('bo_worldmark_category_delete', {'id': worldmarkCategory.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ worldmarkCategory.id) }}">
<button class="btn">Delete</button>
</form>

View File

@ -0,0 +1,22 @@
{{ form_start(form) }}
<div class="sp_form-row__text">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.slug) }}
{{ form_widget(form.slug) }}
</div>
<div class="sp_form-row__text">
{{ form_label(form.sortOrder) }}
{{ form_widget(form.sortOrder) }}
</div>
<div class="sp_form-row__button">
<a class="sp_button" href="{{ path('bo_worldmark_category_index') }}" data-type="cancel">
<span>Cancel</span>
</a>
<button class="sp_button" data-type="validate" type="submit">
<span>Save</span>
</button>
</div>
{{ form_end(form) }}

View File

@ -0,0 +1,7 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/worldmark_category/_form.html.twig', {'button_label': 'Update'}) }}
{{ include('_dashboard/worldmark_category/_delete_form.html.twig') }}
{% endblock %}

View File

@ -0,0 +1,42 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{% if is_granted('ROLE_ADMIN') %}
<p>
<a href="{{ path('bo_worldmark_category_new') }}">Create new</a>
</p>
{% endif %}
<table class="table" style="width: 100%;">
<thead>
<tr>
{#<th>Id</th>#}
<th>Name</th>
<th>Slug</th>
<th>SortOrder</th>
{% if is_granted('ROLE_ADMIN') %}
<th>actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for worldmarkCategory in worldmarksCategories %}
<tr>
{#<td>{{ worldmarkCategory.id }}</td>#}
<td>{{ worldmarkCategory.name }}</td>
<td>{{ worldmarkCategory.slug }}</td>
<td>{{ worldmarkCategory.sortOrder }}</td>
{% if is_granted('ROLE_ADMIN') %}
<td>
<a href="{{ path('bo_worldmark_category_edit', {'id': worldmarkCategory.id}) }}">edit</a>
</td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ is_granted('ROLE_ADMIN') ? '4' : '3' }}">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends '_dashboard/base.html.twig' %}
{% block page_content %}
{{ include('_dashboard/worldmark_category/_form.html.twig') }}
{% endblock %}

75
templates/_menu.html.twig Normal file
View File

@ -0,0 +1,75 @@
<nav class="ul_nav__wrapper sp_header__nav">
<ul class="ul_nav">
<li class="ul_nav__head">
<div class="sp_icon__container sp_header__page-icon">
<img src="{{ asset(assets.img.ui ~ 'traveler.png') }}" alt="Traveler">
</div>
</li>
{% for _region in regions %}
{% if is_granted('ROLE_CONTRIBUTOR') %}
{% set href = _region.version > gameVersion
? path('fo_region_show', {'slug': _region.slug, 'v': _region.version})
: path('fo_region_show', {'slug': _region.slug}) %}
{% elseif _region.isActive and _region.version <= gameVersion %}
{% set href = path('fo_region_show', {'slug': _region.slug}) %}
{% else %}
{% set href = null %}
{% endif %}
{% if href %}
{% set class = null %}
{% if route == 'fo_region_show' and region is defined
and (region.id == _region.id or (region.parentRegion and region.parentRegion.id == _region.id)) %}
{% set class = 'ul_nav__link-active' %}
{% endif %}
<li class="ul_nav__item">
<a href="{{ href }}" class="{{ class }}">
<span class="ul_nav__underline"></span>
<span class="ul_nav__item-title">{{ _region.name }}</span>
</a>
{% set subRegions = [] %}
{% for _subRegion in _region.subRegions %}
{% if is_granted('ROLE_SENIOR') %}
{% set href = _subRegion.version > gameVersion
? path('fo_region_show', {'slug': _subRegion.slug, 'v': _subRegion.version})
: path('fo_region_show', {'slug': _subRegion.slug}) %}
{% elseif _subRegion.isActive and _subRegion.version <= gameVersion %}
{% set href = path('fo_region_show', {'slug': _subRegion.slug}) %}
{% else %}
{% set href = null %}
{% endif %}
{% if href %}
{% set class = null %}
{% if route == 'fo_region_show' and region is defined and regionSlug == _subRegion.slug %}
{% set class = 'ul_nav__link-active' %}
{% endif %}
{% set subRegions = subRegions|merge([{'name': _subRegion.name, 'href': href, 'class': class}]) %}
{% endif %}
{% endfor %}
{% if subRegions|length %}
<ul class="ul_nav__sub-nav">
{% for _subRegion in subRegions %}
<li class="ul_nav__item">
<a href="{{ _subRegion.href }}" class="{{ _subRegion.class }}">
<span class="ul_nav__underline"></span>
<span class="ul_nav__item-title">{{ _subRegion.name }}</span>
</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endif %}
{% endfor %}
<li class="ul_nav__tail">
<a class="sp_icon__container" href='https://discord.gg/DdDZSy8kWh' target="_blank">
<img src="{{ asset(assets.img.ui ~ 'discord.png') }}" alt="Discord">
</a>
</li>
</ul>
</nav>

136
templates/base.html.twig Normal file
View File

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html lang="{{ locale }}">
<head>
<meta charset="UTF-8">
{# {% if app.environment == 'dev' or#}
{# route|start_with('sandbox')#}
{# or route|start_with('security_')#}
{# or route|start_with('bo_') %}#}
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
{# {% endif %}#}
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>{{ title is defined ? title : 'Genshin Impact interactive map - Genshin World' }}</title>
{% block meta %}{% endblock %}
<link rel="icon" href="https://genshin-world.com/favicon.ico" type="image/x-icon">
{{ encore_entry_link_tags('app') }}
{% for script in encore_entry_js_files('app') %}
<script src="{{ script }}" type="text/javascript" defer></script>
{% endfor %}
{% if app.environment == 'prod'
and not route|start_with('security_')
and not route|start_with('bo_') %}
<script async src="https://www.googletagmanager.com/gtag/js?id=G-TN3HMR3G0K"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-TN3HMR3G0K');
</script>
<!--suppress ES6ConvertVarToLetConst -->
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
_paq.push(['enableHeartBeatTimer', 60]);
(function() {
var u = "//matomo.sphere.gdn/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d = document, g = d.createElement("script"), s = d.getElementsByTagName("script")[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
{% endif %}
</head>
<body>
{% if is_granted('ROLE_CONTRIBUTOR') %}
<canvas id="transform-canvas" height="720" width="1280"></canvas>
{% endif %}
<div id="page-background"></div>
<div id="page-container" class="{% if isTouchDevice.isMobile or isTouchDevice.isTablet %}sp_app__is-touch-device{% endif %}" data-device="{{ isTouchDevice.isMobile ? 'mobile' : (isTouchDevice.isTablet ? 'tablet' : 'desktop') }}">
<header id="header-container">
{% if isTouchDevice.isMobile or isTouchDevice.isTablet %}
<div id="nav-menu-btn" class="sp_menu-btn">
<div class="sp_menu-btn__bars"></div>
</div>
{% endif %}
{% include '_menu.html.twig' %}
{% if user %}
<div class="sp_header__extra">
{% if is_granted('ROLE_CONTRIBUTOR') %}
<a class="sp_icon__container" href="{{ path('bo_dashboard') }}" title="dashboard">
<img src="{{ asset(assets.img.ui~'settings.png') }}" alt>
</a>
{% endif %}
<a class="sp_icon__container" href="{{ path('security_logout') }}" title="logout">
<img src="{{ asset(assets.img.ui~'logout.png') }}" alt>
</a>
</div>
{% endif %}
</header>
<main id="main-container">
<section id="modal-container">
<div class="sp_modal__background"></div>
<div class="sp_modal__container"></div>
</section>
<div id="blob-loader">
<div class="sp_loader__wrapper">
<div class="sp_slime__wrapper">
<div class="sp_slime__outline"></div>
<div class="sp_slime__outline_ends">
<div class="sp_slime__outline_end"></div>
<div class="sp_slime__outline_end"></div>
</div>
<div class="sp_slime__eyes">
<div class="sp_slime__eye"></div>
<div class="sp_slime__eye"></div>
</div>
</div>
<div class="sp_ground_line__wrapper">
<div class="sp_ground_line"></div>
<div class="sp_ground_line__ends">
<div class="sp_ground_line__end"></div>
<div class="sp_ground_line__end"></div>
</div>
</div>
<div class="sp_element__wrapper">
<div class="sp_elements">
{% set elements = ['anemo', 'cryo', 'dendro', 'electro', 'geo', 'hydro', 'pyro']|shuffle_array %}
{% for idx in 1..2 %}
{% for _element in elements %}
<div class="sp_element">
<div class="sp_element__icon">
<img src="{{ asset(assets.img.ui ~ 'element_'~ _element ~'.png') }}" alt="{{ _element }}">
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
<div class="sp_loader__text">
<div class="sp_loader__warn-text"></div>
</div>
</div>
<div id="toasts-container"></div>
<div id="main-left-container" class="sp_panel__container">
{% block leftPanel %}{% endblock %}
</div>
<div id="main-center-container" class="{% if region is defined %}{{ 'sp_region__background-' ~ region.mapBackground }}{% endif %}">
{% block body %}{% endblock %}
</div>
<div id="main-right-container" class="sp_panel__container">
{% block rightPanel %}{% endblock %}
</div>
</main>
<footer id="footer-container"></footer>
</div>
</body>
</html>

View File

@ -0,0 +1,37 @@
{% extends 'base.html.twig' %}
{% block body %}
<form method="post" style="color: white;">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% if app.user %}
<div class="mb-3">
You are logged in as {{ app.user.username }}, <a href="{{ path('security_logout') }}">Logout</a>
</div>
{% else %}
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputUsername">Username</label>
<input type="text" value="{{ last_username }}" name="username" id="inputUsername" class="form-control" required autofocus>
<label for="inputPassword">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" required>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
</div>
#}
<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
{% endif %}
</form>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block body %}
{% for flashError in app.flashes('verify_email_error') %}
<div class="alert alert-danger" role="alert">{{ flashError }}</div>
{% endfor %}
<div style="color: white;">
<h1>Register</h1>
{{ form_start(form) }}
{{ form_row(form.username) }}
{{ form_row(form.plainPassword, {
label: 'Password'
}) }}
{{ form_row(form.agreeTerms) }}
<button type="submit" class="btn">Register</button>
{{ form_end(form) }}
</div>
{% endblock %}

View File

@ -0,0 +1,130 @@
{#<div class="sp_panel__header"></div>#}
<div class="sp_panel__switch">
<img class="sp_panel__open" src="{{ asset(assets.img.ui~'arrow_open.png') }}" alt="-">
<img class="sp_panel__close" src="{{ asset(assets.img.ui~'arrow_close.png') }}" alt="-">
</div>
<div class="sp_panel__content-switch-container">
<div class="sp_panel__content-switch sp_panel__switch-active" data-target="worldmap-filters">
<img src="{{ asset(assets.img.ui~'content-pins.png') }}" alt="-">
</div>
<div class="sp_panel__content-switch" data-target="worlmap-settings">
<img src="{{ asset(assets.img.ui~'content-settings.png') }}" alt="-">
</div>
</div>
<div id="primogem-counter-container">
<div class="sp_primogem__main-container">
<div>
<div>At least</div>
<div id="primogem-counter">0</div>
<div class="sp_icon__container sp_header__page-icon">
<img src="{{ asset(assets.img.ui ~'primogem.png') }}" alt="Primogem">
</div>
</div>
<div><h2>primogems</h2>&nbsp;left to collect</div>
</div>
</div>
<div class="sp_panel__content sp_slider">
{% set leftIndex = worldmarksData|length %}
<div id="worldmap-filters" class="sp_slider__slide sp_slider__slide-open">
<section class="sp_panel__section sp_filter__section" style="color:#c31414;font-weight:bold;background-color:rgba(0,0,0,0.1);">
<span>This website is used as portfolio and is no longer maintained. While the data it provide is still accurate, it will not be updated anymore.</span>
<span style="padding-top: 8px">Credits to HoYoVerse for the icons and images.</span>
</section>
{% for _worldmarkCategory in worldmarksData %}
<section class="sp_panel__section sp_filter__section">
<div class="sp_panel__section-title">
<h2 data-section-title="{{ _worldmarkCategory._data.name }}">{{ _worldmarkCategory._data.name }}<span>▼</span></h2>
<button class="sp_section-filter__switch" type="button" value="show_all">Show all</button>
<button class="sp_section-filter__switch" type="button" value="hide_all">Hide all</button>
</div>
<div class="sp_form-row__radio {{ is_granted('ROLE_CONTRIBUTOR') ? 'sp_radio__layout-grid-c' : 'sp_radio__layout-grid-b' }} sp_radio__style-icon">
<div class="sp_worldmap-filter__section sp_radio__container">
{% set rightIndex = _worldmarkCategory._worldmarks|length %}
{% for _worldmark in _worldmarkCategory._worldmarks %}
<label class="sp_radio__input-wrapper" title="{{ _worldmark.name }}">
<span class="sp_radio__input-icon">
<span class="sp_node__item">
<span class="sp_node__background">
<img {% if _worldmark.icon %}data-src="{{ asset(assets.worldmark.upload_path ~ _worldmark.icon) }}"{% endif%} src="{{ asset(assets.img._blank_xs) }}" alt="{{ _worldmark.name }}">
</span>
</span>
</span>
{#<span class="sp_radio__input-mark"></span>#}
<span class="sp_radio__input-label">{{ _worldmark.name }}</span>
<span class="nodes_count"></span>
<input class="sp_worldmap__filter" data-index="{{ (leftIndex * 100) + rightIndex }}" data-can-be-hidden="{{ _worldmark.canBeHidden }}" type="checkbox" value="{{ _worldmark.slug }}">
</label>
{% if is_granted('ROLE_CONTRIBUTOR') %}
<button class="sp_button sp_worldmark__init-new-node" data-uri="{{ path('bo_node_new', {'gridId': '%gridId%', 'worldmarkId': _worldmark.id}) }}">
<span>+</span>
</button>
{% endif %}
{% set rightIndex = rightIndex - 1 %}
{% endfor %}
</div>
</div>
</section>
{% set leftIndex = leftIndex - 1 %}
{% endfor %}
</div>
<div id="worlmap-settings" class="sp_slider__slide">
<section class="sp_panel__section">
<div class="sp_panel__section-title">
<label>Worldmap settings</label>
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-a sp_radio__style-text">
<label class="sp_radio__main-label">Profile</label>
<div id="profiles__profiles-container" class="sp_radio__container">
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Profile A</span>
<input name="_profile" type="radio" value="profile-a">
</label>
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Profile B</span>
<input name="_profile" type="radio" value="profile-b">
</label>
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Profile C</span>
<input name="_profile" type="radio" value="profile-c">
</label>
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Profile D</span>
<input name="_profile" type="radio" value="profile-d">
</label>
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Profile E</span>
<input name="_profile" type="radio" value="profile-e">
</label>
</div>
</div>
<div class="sp_form-row__radio sp_radio__layout-grid-a sp_radio__style-text">
<label class="sp_radio__main-label">Profile's server</label>
<div id="profiles__servers-container" class="sp_radio__container">
<label class="sp_radio__input-wrapper" title="America">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">America</span>
<input name="_profile__server" type="radio" value="na">
</label>
<label class="sp_radio__input-wrapper" title="Europe">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Europe</span>
<input name="_profile__server" type="radio" value="eu">
</label>
<label class="sp_radio__input-wrapper" title="Asia">
<span class="sp_radio__input-mark"></span>
<span class="sp_radio__input-label">Asia</span>
<input name="_profile__server" type="radio" value="cn">
</label>
</div>
</div>
</section>
</div>
</div>

View File

@ -0,0 +1,31 @@
{% set screenshots = [] %}
{% set screenshots = screenshots|merge(node.screenshotA ? [asset(assets.screenshot.thumbnail_path ~ node.screenshotA)]: []) %}
{% set screenshots = screenshots|merge(node.screenshotB ? [asset(assets.screenshot.thumbnail_path ~ node.screenshotB)]: []) %}
{% set screenshots = screenshots|merge(node.screenshotC ? [asset(assets.screenshot.thumbnail_path ~ node.screenshotC)]: []) %}
{% set screenshots = screenshots|merge(node.screenshotD ? [asset(assets.screenshot.thumbnail_path ~ node.screenshotD)]: []) %}
{% set screenshots = screenshots|merge(node.screenshotE ? [asset(assets.screenshot.thumbnail_path ~ node.screenshotE)]: []) %}
<label id="{{ 'node-' ~ node.id }}" class="sp_node__item {% if is_granted('ROLE_ADMIN') and node.isDeleted %}sp_node__deleted{% endif %}"
data-coordinate="{{ node.coordinate|json_encode }}"
data-filter="{{ node.worldmark.slug }}"
data-can-be-hidden="{{ node.worldmark.canBeHidden }}"
{% if is_granted('ROLE_CONTRIBUTOR') %}data-edit-url="{{ path('bo_node_edit', {'gridId': node.grid.id, 'worldmarkId': node.worldmark.id, 'id': node.id}) }}"{% endif %}
{% if is_granted('ROLE_CONTRIBUTOR') %}data-delete-url="{{ path('bo_node_delete', {'gridId': node.grid.id, 'worldmarkId': node.worldmark.id, 'id': node.id}) }}"{% endif %}
data-description="{{ node.description }}"
{% if node.screenshotA %}data-screenshots="{{ screenshots|json_encode }}"{% endif %}
data-quantity="{{ node.quantity }}"
data-primogem="{{ node.primogem }}"
hidden>
<span class="sp_node__background">
{% if directRender is defined %}
<img src="{{ asset(node.worldmark.icon ? assets.worldmark.upload_path ~ node.worldmark.icon : assets.img._blank_xs) }}" alt="{{ node.worldmark.name }}">
{% else %}
<img {% if node.worldmark.icon %}data-src="{{ asset(assets.worldmark.upload_path ~ node.worldmark.icon) }}"{% endif %} src="{{ asset(assets.img._blank_xs) }}" alt="{{ node.worldmark.name }}">
{% endif %}
</span>
{% if node.quantity > 1 %}
<span class="sp_node__quantity">
<span>{{ node.quantity }}</span>
</span>
{% endif %}
</label>

View File

@ -0,0 +1,115 @@
{% extends 'base.html.twig' %}
{% set metaRegionName = region.name %}
{% for _region in region.subRegions|filter(_region => _region.isAlias and _region.parentRegion.id == region.id) %}
{% set metaRegionName = metaRegionName ~ ' and ' ~ _region.name %}
{% endfor %}
{% set metaTitle = title is defined ? title : 'Genshin Impact interactive map - Genshin World' %}
{#{% set metaDesc = 'Genshin Impact interactive map of ' ~ metaRegionName ~ '. Find every interest points, events, chests, monsters and materials of Teyvat. Up to date with latest patch.' %}#}
{% set metaDesc = 'Genshin Impact interactive map of ' ~ metaRegionName ~ '. Find every interest points, events, chests, monsters and materials of Teyvat.' %}
{% block meta %}
<meta name="title" content="{{ metaTitle }}">
<meta name="description" content="{{ metaDesc }}">
{% if not region.isActive %}
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
{% endif %}
<meta property="og:type" content="website">
<meta property="og:url" content="{{ url('fo_region_show', { 'slug': regionSlug }) }}">
<meta property="og:title" content="{{ metaTitle }}">
<meta property="og:description" content="{{ metaDesc }}">
<meta property="og:image" content="https://genshin-world.com/og.jpg">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="{{ url('fo_region_show', { 'slug': regionSlug }) }}">
<meta property="twitter:title" content="{{ metaTitle }}">
<meta property="twitter:description" content="{{ metaDesc }}">
<meta property="twitter:image" content="https://genshin-world.com/og.jpg">
<link rel="canonical" href="{{ url('fo_region_show', { 'slug': region.slug }) }}">
{% endblock %}
{% block leftPanel %}
{% include 'woldmap/_leftPannel.html.twig' %}
{% endblock %}
{% block body %}
<h1 id="map-title">{{ metaTitle }}</h1>
<div id="worldmap-container" class="sp_grid__container" data-region-id="{{ region.slug }}" data-region-name="{{ region.name }}" data-region-width="{{ region.gridWidth }}" data-region-height="{{ region.gridHeight }}" {% if anchor %}data-anchor="{{ anchor }}"{% endif %}>
{% for row in 1..region.gridHeight %}
{% for col in 1..region.gridWidth %}
<div id="grid-{{ grid[row][col]['id'] }}" class="sp_grid__cell">
{% set idHash = 'map_g' ~ grid[row][col]['id'] ~ '_v' ~ version %}
<img id="{{ idHash }}" class="sp_grid__map" {% if grid[row][col]['map_data']['map'].id is not null %}data-src="{{ asset(assets.map.upload_path ~ grid[row][col]['map_data']['map'].file) }}"{% endif %} src="{{ asset(assets.map[region.mapBackground]) }}" alt="{{ region.name }}" draggable="false">
<div class="sp_grid__node-container">
{% if nodes['grid_' ~ grid[row][col]['id']] is defined %}
{% for _node in nodes['grid_' ~ grid[row][col]['id']] %}
{% include 'woldmap/_node.html.twig' with {'node': _node} %}
{% endfor %}
{% endif %}
</div>
</div>
{% endfor %}
{% endfor %}
</div>
<div id="grid-zoom-container">
<span>+</span>
<input id="grid-zoom-controller" type="range" min="0" step="2">
<span>-</span>
</div>
<template id="template_tooltip">
<div class="sp_tooltip__wrapper" hidden>
{% if is_granted('ROLE_CONTRIBUTOR') %}
<div class="sp_tooltip__action-left-wrapper">
<form action="" class="sp_tooltip__action sp_node__edit-form sp_form__xhr" method="post">
<button class="sp_button" type="submit">
<span>Edit node</span>
</button>
</form>
<form action="" class="sp_tooltip__action sp_node_delete-form sp_form__xhr" method="post">
<button class="sp_button sp_icon__container" data-type="cancel" type="submit">
<img src="{{ asset(assets.img.delete) }}" alt="delete node">
</button>
</form>
{% if is_granted('ROLE_ADMIN') %}
<button class="sp_button sp_icon__container sp_node__calc-anchor">
<img src="{{ asset(assets.img.ui ~ 'location.png') }}" alt="delete node">
</button>
{% endif %}
</div>
{% endif %}
<div class="sp_tooltip__action-right-wrapper">
<button class="sp_button sp_tooltip__action sp_node__set-display" data-node-id="" data-is-hidden="0">
<span>Hide Pin</span>
<span>Show Pin</span>
</button>
</div>
<div class="sp_tooltip">
<h4 class="sp_tooltip__header">
<span></span>
{% if is_granted('ROLE_CONTRIBUTOR') %}<span></span>{% endif %}
</h4>
<div class="sp_tooltip__body"></div>
<div class="sp_tooltip__footer" hidden>
<div>Screenshots :</div>
<div class="sp_tooltip__screenshot-container"></div>
</div>
</div>
<div class="sp_tooltip__cursor"></div>
</div>
</template>
{#<template id="template_radio-input">#}
{# <label class="sp_radio__input-wrapper">#}
{# <span class="sp_radio__input-icon"></span>#}
{# <span class="sp_radio__input-mark"></span>#}
{# <span class="sp_radio__input-label"></span>#}
{# <input name type value>#}
{# </label>#}
{#</template>#}
{% endblock %}

View File

@ -0,0 +1,109 @@
{% extends 'base.html.twig' %}
{% set metaRegionName = region.name %}
{% for _region in region.subRegions|filter(_region => _region.isAlias and _region.parentRegion.id == region.id) %}
{% set metaRegionName = metaRegionName ~ ' and ' ~ _region.name %}
{% endfor %}
{% set metaTitle = title is defined ? title ~ ' - Genshin World' : 'Genshin World' %}
{#{% set metaDesc = 'Genshin Impact interactive map of ' ~ metaRegionName ~ '. Find every interest points, events, chests, monsters and materials of Teyvat. Up to date with latest patch.' %}#}
{% set metaDesc = 'Genshin Impact interactive map of ' ~ metaRegionName ~ '. Find every interest points, events, chests, monsters and materials of Teyvat.' %}
{% block meta %}
<meta name="title" content="{{ metaTitle }}">
<meta name="description" content="{{ metaDesc }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ url('fo_region_show', { 'slug': regionSlug }) }}">
<meta property="og:title" content="{{ metaTitle }}">
<meta property="og:description" content="{{ metaDesc }}">
<meta property="og:image" content="https://genshin-world.com/og.jpg">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="{{ url('fo_region_show', { 'slug': regionSlug }) }}">
<meta property="twitter:title" content="{{ metaTitle }}">
<meta property="twitter:description" content="{{ metaDesc }}">
<meta property="twitter:image" content="https://genshin-world.com/og.jpg">
<link rel="canonical" href="{{ url('fo_region_show', { 'slug': region.slug }) }}">
{% endblock %}
{% block leftPanel %}
{% include 'woldmap/_leftPannel.html.twig' %}
{% endblock %}
{% block body %}
<h1 id="map-title">{{ metaTitle }}</h1>
<div id="worldmap-container" data-region-id="{{ region.slug }}" data-region-name="{{ region.name }}" {% if anchor %}data-anchor="{{ anchor }}"{% endif %}>
<div class="sp_grid__container">
{% for row in 1..region.gridHeight %}
<div class="sp_grid__row">
{% for col in 1..region.gridWidth %}
<div id="grid-{{ grid[row][col]['id'] }}" class="sp_grid__column">
{% set idHash = 'map_g' ~ grid[row][col]['id'] ~ '_v' ~ version %}
<img id="{{ idHash }}" class="sp_grid__map" {% if grid[row][col]['map_data']['map'].id is not null %}data-src="{{ asset(assets.map.upload_path ~ grid[row][col]['map_data']['map'].file) }}"{% endif %} src="{{ asset(assets.map[region.mapBackground]) }}" alt="{{ region.name }}" draggable="false">
<div class="sp_grid__node-container">
{% if nodes['grid_' ~ grid[row][col]['id']] is defined %}
{% for _node in nodes['grid_' ~ grid[row][col]['id']] %}
{% include 'woldmap/_node.html.twig' with {'node': _node} %}
{% endfor %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
<template id="template_tooltip">
<div class="sp_tooltip__wrapper" hidden>
{% if is_granted('ROLE_CONTRIBUTOR') %}
<div class="sp_tooltip__action-left-wrapper">
<form action="" class="sp_tooltip__action sp_node__edit-form sp_form__xhr" method="post">
<button class="sp_button" type="submit">
<span>Edit node</span>
</button>
</form>
<form action="" class="sp_tooltip__action sp_node_delete-form sp_form__xhr" method="post">
<button class="sp_button sp_icon__container" data-type="cancel" type="submit">
<img src="{{ asset(assets.img.delete) }}" alt="delete node">
</button>
</form>
{% if is_granted('ROLE_ADMIN') %}
<button class="sp_button sp_icon__container sp_node__calc-anchor">
<img src="{{ asset(assets.img.ui ~ 'location.png') }}" alt="delete node">
</button>
{% endif %}
</div>
{% endif %}
<div class="sp_tooltip__action-right-wrapper">
<button class="sp_button sp_tooltip__action sp_node__set-display" data-node-id="" data-is-hidden="0">
<span>Hide Pin</span>
<span>Show Pin</span>
</button>
</div>
<div class="sp_tooltip">
<h4 class="sp_tooltip__header">
<span></span>
{% if is_granted('ROLE_CONTRIBUTOR') %}<span></span>{% endif %}
</h4>
<div class="sp_tooltip__body"></div>
<div class="sp_tooltip__footer" hidden>
<div>Screenshots :</div>
<div class="sp_tooltip__screenshot-container"></div>
</div>
</div>
<div class="sp_tooltip__cursor"></div>
</div>
</template>
{#<template id="template_radio-input">#}
{# <label class="sp_radio__input-wrapper">#}
{# <span class="sp_radio__input-icon"></span>#}
{# <span class="sp_radio__input-mark"></span>#}
{# <span class="sp_radio__input-label"></span>#}
{# <input name type value>#}
{# </label>#}
{#</template>#}
{% endblock %}