Dodanie nowej strony admina co pozwala dodawać pane kontaktowe
This commit is contained in:
262
admin/templates/contacts-maps/element-edit.php
Normal file
262
admin/templates/contacts-maps/element-edit.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
|
||||
<script type="text/javascript" src="/libraries/jquery/sortable/sortable.js"></script>
|
||||
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
/** @var array|null $item */
|
||||
/** @var array $products */
|
||||
/** @var array $provinces */
|
||||
|
||||
$item = $this -> item ?? [];
|
||||
$products = $this -> products ?? [];
|
||||
$provinces = $this -> provinces ?? [];
|
||||
|
||||
/** Województwa */
|
||||
$province_values = [ 0 => '--- wybierz województwo ---' ];
|
||||
if (is_array($provinces)) {
|
||||
foreach ($provinces as $p) {
|
||||
$province_values[(int)$p['id']] = $p['name'];
|
||||
}
|
||||
}
|
||||
|
||||
/** Typ salonu */
|
||||
$salon_type_values = [
|
||||
'sales' => 'SALON SPRZEDAŻY',
|
||||
'partner' => 'SALON PARTNERSKI',
|
||||
];
|
||||
|
||||
/** Produkty */
|
||||
$selected_products = $item['products'] ?? [];
|
||||
if (!is_array($selected_products)) $selected_products = [];
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div id="settings-tabs">
|
||||
<ul class="resp-tabs-list settings-tabs">
|
||||
<li><i class="fa fa-map-marker"></i>Dane salonu</li>
|
||||
<li><i class="fa fa-phone"></i>Kontakt</li>
|
||||
<li><i class="fa fa-cubes"></i>Produkty</li>
|
||||
<li><i class="fa fa-wrench"></i>Ustawienia</li>
|
||||
</ul>
|
||||
|
||||
<div class="resp-tabs-container settings-tabs">
|
||||
|
||||
<!-- TAB 1: Dane salonu -->
|
||||
<div>
|
||||
<?= \Html::select([
|
||||
'label' => 'Województwo',
|
||||
'name' => 'province_id',
|
||||
'id' => 'province_id',
|
||||
'values' => $province_values,
|
||||
'value' => (int)($item['province_id'] ?? 0),
|
||||
]);?>
|
||||
|
||||
<?= \Html::select([
|
||||
'label' => 'Typ salonu',
|
||||
'name' => 'salon_type',
|
||||
'id' => 'salon_type',
|
||||
'values' => $salon_type_values,
|
||||
'value' => ($item['salon_type'] ?? 'sales'),
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Nazwa salonu',
|
||||
'name' => 'salon_name',
|
||||
'id' => 'salon_name',
|
||||
'value' => ($item['salon_name'] ?? ''),
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Miasto',
|
||||
'name' => 'city',
|
||||
'id' => 'city',
|
||||
'value' => ($item['city'] ?? ''),
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::textarea([
|
||||
'label' => 'Adres',
|
||||
'name' => 'address',
|
||||
'id' => 'address',
|
||||
'value' => ($item['address'] ?? ''),
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Koordynaty (lat, lng)',
|
||||
'name' => 'coords',
|
||||
'id' => 'coords',
|
||||
'value' => ($item['coords'] ?? ''),
|
||||
'inline' => true,
|
||||
'desc' => 'Np. 50.07576365941408, 21.973886126521034'
|
||||
]);?>
|
||||
|
||||
<?= \Html::textarea([
|
||||
'label' => 'Godziny otwarcia',
|
||||
'name' => 'opening_hours',
|
||||
'id' => 'opening_hours',
|
||||
'value' => ($item['opening_hours'] ?? ''),
|
||||
'inline' => true,
|
||||
'desc' => 'Np. Pn-Pt: 8-17 | Sob: 9-13 | Nd: nieczynne'
|
||||
]);?>
|
||||
|
||||
<?= \Html::input_icon([
|
||||
'label' => 'Baner (obrazek salonu)',
|
||||
'name' => 'banner_image',
|
||||
'id' => 'banner_image',
|
||||
'value' => ($item['banner_image'] ?? ''),
|
||||
'icon_content' => 'przeglądaj',
|
||||
'inline' => true,
|
||||
'icon_js' => "window.open('/libraries/filemanager-9.14.1/dialog.php?type=1&popup=1&field_id=banner_image&akey=c3cb2537d25c0efc9e573d059d79c3b8','mywindow','location=1,status=1,scrollbars=1,width=1100,height=700');"
|
||||
]);?>
|
||||
</div>
|
||||
|
||||
<!-- TAB 2: Kontakt -->
|
||||
<div>
|
||||
<?php
|
||||
$phones_txt = '';
|
||||
if (!empty($item['phones']) && is_array($item['phones'])) $phones_txt = implode("\n", $item['phones']);
|
||||
|
||||
$emails_txt = '';
|
||||
if (!empty($item['emails']) && is_array($item['emails'])) $emails_txt = implode("\n", $item['emails']);
|
||||
?>
|
||||
|
||||
<?= \Html::textarea([
|
||||
'label' => 'Telefony (1 numer = 1 linia)',
|
||||
'name' => 'phones',
|
||||
'id' => 'phones',
|
||||
'value' => $phones_txt,
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::textarea([
|
||||
'label' => 'E-maile (1 email = 1 linia)',
|
||||
'name' => 'emails',
|
||||
'id' => 'emails',
|
||||
'value' => $emails_txt,
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Tekst przycisku',
|
||||
'name' => 'button_label',
|
||||
'id' => 'button_label',
|
||||
'value' => ($item['button_label'] ?? 'SKONTAKTUJ SIĘ Z NAMI'),
|
||||
'inline' => true
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Link przycisku (URL)',
|
||||
'name' => 'button_url',
|
||||
'id' => 'button_url',
|
||||
'value' => ($item['button_url'] ?? ''),
|
||||
'inline' => true,
|
||||
'desc' => 'Np. https://twojadomena.pl/kontakt'
|
||||
]);?>
|
||||
</div>
|
||||
|
||||
<!-- TAB 3: Produkty -->
|
||||
<div>
|
||||
<div class="title">Dostępne produkty</div>
|
||||
|
||||
<?php if (is_array($products) && count($products)): ?>
|
||||
<div style="display:flex; flex-wrap:wrap; gap:14px;">
|
||||
<?php foreach ($products as $p): ?>
|
||||
<?php
|
||||
$pid = (int)$p['id'];
|
||||
$checked = in_array($pid, $selected_products) ? 'checked' : '';
|
||||
?>
|
||||
<label style="display:flex; align-items:center; gap:20px; padding:10px 12px; border:1px solid #ddd; border-radius:6px; cursor:pointer;">
|
||||
<input type="checkbox" name="products[]" value="<?= $pid; ?>" <?= $checked; ?> />
|
||||
<div style="display:flex; flex-direction:column; align-items:center; gap:10px;">
|
||||
<span style="text-align: center;"><?= $p['name']; ?></span>
|
||||
<img src="/<?= ltrim($p['icon'], '/'); ?>" alt="" style="width:36px; height:36px; object-fit:contain;" />
|
||||
</div>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">Brak produktów w pp_contacts_maps_products.</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- TAB 4: Ustawienia -->
|
||||
<div>
|
||||
<?= \Html::input_switch([
|
||||
'label' => 'Aktywny',
|
||||
'name' => 'is_active',
|
||||
'checked' => (!isset($item['is_active']) || (int)$item['is_active'] === 1) ? true : false
|
||||
]);?>
|
||||
|
||||
<?= \Html::input([
|
||||
'label' => 'Sortowanie',
|
||||
'name' => 'sort',
|
||||
'id' => 'sort',
|
||||
'value' => (int)($item['sort'] ?? 0),
|
||||
]);?>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$( function() {
|
||||
$( '#address, #opening_hours' ).ckeditor( {
|
||||
toolbar : 'MyTool',
|
||||
height:'200',
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$out = ob_get_clean();
|
||||
|
||||
$grid = new \gridEdit;
|
||||
$grid -> id = 'contacts-maps-edit';
|
||||
$grid -> gdb_opt = $gdb;
|
||||
$grid -> include_plugins = true;
|
||||
$grid -> title = 'Edycja autora';
|
||||
$grid -> title = $id ? 'Edycja salonu' : 'Dodaj salon';
|
||||
|
||||
$grid->fields = [
|
||||
[
|
||||
'db' => 'id',
|
||||
'type' => 'hidden',
|
||||
'value' => $this->item['id']
|
||||
]
|
||||
];
|
||||
|
||||
$grid -> external_code = $out;
|
||||
$grid -> actions = [
|
||||
'save' => [ 'url' => '/admin/contacts_maps/save/', 'back_url' => '/admin/contacts_maps/view_list/' ],
|
||||
'cancel' => [ 'url' => '/admin/contacts_maps/view_list/' ]
|
||||
];
|
||||
|
||||
$grid -> persist_edit = true;
|
||||
$grid -> id_param = 'id';
|
||||
echo $grid -> draw();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(function ()
|
||||
{
|
||||
disable_menu();
|
||||
|
||||
$( '#settings-tabs' ).easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'settings-tabs',
|
||||
type: 'vertical'
|
||||
});
|
||||
|
||||
$('#languages-main').easyResponsiveTabs({
|
||||
width: 'auto',
|
||||
fit: true,
|
||||
tabidentify: 'languages-main'
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
|
||||
45
admin/templates/contacts-maps/view-list.php
Normal file
45
admin/templates/contacts-maps/view-list.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
global $gdb;
|
||||
|
||||
$grid = new \grid('pp_contacts_maps');
|
||||
$grid->gdb_opt = $gdb;
|
||||
|
||||
$grid->columns_view = [
|
||||
[
|
||||
'name' => 'Lp.',
|
||||
'autoincrement' => true
|
||||
],
|
||||
[
|
||||
'name' => 'Salon',
|
||||
'db' => 'salon_name',
|
||||
'php' => 'echo "<a href=\"/admin/contacts_maps/edit/id=[id]\">[salon_name]</a>";'
|
||||
],
|
||||
[
|
||||
'name' => 'Miasto',
|
||||
'db' => 'city'
|
||||
],
|
||||
[
|
||||
'name' => 'Typ',
|
||||
'db' => 'salon_type',
|
||||
'php' => 'echo ([salon_type] === "sales" ? "SALON SPRZEDAŻY" : ([salon_type] === "partner" ? "SALON PARTNERSKI" : ""));'
|
||||
],
|
||||
[
|
||||
'name' => 'Aktywny',
|
||||
'db' => 'is_active',
|
||||
'php' => 'echo ([is_active] ? "TAK" : "NIE");'
|
||||
],
|
||||
[
|
||||
'name' => 'Usuń',
|
||||
'action' => [ 'type' => 'delete', 'url' => '/admin/contacts_maps/delete/id=[id]' ]
|
||||
]
|
||||
];
|
||||
|
||||
$grid->buttons = [
|
||||
[
|
||||
'label' => 'Dodaj salon',
|
||||
'url' => '/admin/contacts_maps/edit/',
|
||||
'class' => 'btn-success'
|
||||
]
|
||||
];
|
||||
|
||||
echo $grid->draw();
|
||||
@@ -88,6 +88,11 @@
|
||||
<a href="/admin/scontainers/view_list/"><img src="/admin/css/icons/container-solid.svg">Zawartość statyczna</a>
|
||||
<? }?>
|
||||
</li>
|
||||
<? if ( \admin\factory\Users::check_privileges( 'scontainers_administration', $user[ 'id' ] ) ): ?>
|
||||
<li>
|
||||
<a href="/admin/contacts_maps/view_list/"><img src="/admin/css/icons/list-settings-line.svg">Kontakt - lista salonów</a>
|
||||
</li>
|
||||
<? endif; ?>
|
||||
</ul>
|
||||
<?
|
||||
if ( \admin\factory\Users::check_privileges( 'fileManager_administration', $user[ 'id' ] ) || \admin\factory\Users::check_privileges( 'baners_administration', $user[ 'id' ] ) || \admin\factory\Users::check_privileges( 'emails_administration', $user[ 'id' ] ) )
|
||||
|
||||
30
api/contact_map.php
Normal file
30
api/contact_map.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
error_reporting( E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED );
|
||||
function __autoload_my_classes( $classname )
|
||||
{
|
||||
$q = explode( '\\' , $classname );
|
||||
$c = array_pop( $q );
|
||||
$f = '../autoload/' . implode( '/' , $q ) . '/class.' . $c . '.php';
|
||||
|
||||
if ( file_exists( $f ) )
|
||||
require_once( $f );
|
||||
}
|
||||
spl_autoload_register( '__autoload_my_classes' );
|
||||
date_default_timezone_set( 'Europe/Warsaw' );
|
||||
|
||||
require_once '../config.php';
|
||||
require_once '../libraries/medoo/medoo.php';
|
||||
|
||||
session_start();
|
||||
|
||||
$mdb = new medoo( [
|
||||
'database_type' => 'mysql',
|
||||
'database_name' => $database['name'],
|
||||
'server' => $database['host'],
|
||||
'username' => $database['user'],
|
||||
'password' => $database['password'],
|
||||
'charset' => 'utf8'
|
||||
] );
|
||||
|
||||
\front\controls\ContactsMapsApi::index();
|
||||
?>
|
||||
58
autoload/admin/controls/class.ContactsMaps.php
Normal file
58
autoload/admin/controls/class.ContactsMaps.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?
|
||||
namespace admin\controls;
|
||||
class ContactsMaps
|
||||
{
|
||||
static public function view_list()
|
||||
{
|
||||
global $user;
|
||||
|
||||
if ( !\admin\factory\Users::check_privileges( 'scontainers_administration', $user['id'] ) )
|
||||
return \S::alert( 'Nie masz uprawnień' );
|
||||
|
||||
return \Tpl::view( 'contacts-maps/view-list' );
|
||||
}
|
||||
|
||||
static public function edit()
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (!\admin\factory\Users::check_privileges('scontainers_administration', $user['id']))
|
||||
return \S::alert('Nie masz uprawnień');
|
||||
|
||||
return \Tpl::view('contacts-maps/element-edit', [
|
||||
'item' => \admin\factory\ContactsMaps::get(\S::get('id')),
|
||||
'products' => \admin\factory\ContactsMaps::products(),
|
||||
'provinces' => \admin\factory\ContactsMaps::provinces(),
|
||||
]);
|
||||
}
|
||||
|
||||
static public function save()
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (!\admin\factory\Users::check_privileges('scontainers_administration', $user['id']))
|
||||
return;
|
||||
|
||||
$values = \S::json_to_array(\S::get('values'));
|
||||
|
||||
$id = \admin\factory\ContactsMaps::save($values);
|
||||
|
||||
echo json_encode([
|
||||
'status' => $id ? 'ok' : 'error',
|
||||
'id' => $id
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
static public function delete()
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (!\admin\factory\Users::check_privileges('scontainers_administration', $user['id']))
|
||||
return;
|
||||
|
||||
\admin\factory\ContactsMaps::delete(\S::get('id'));
|
||||
header('Location: /admin/contacts_maps/view_list/');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
137
autoload/admin/factory/class.ContactsMaps.php
Normal file
137
autoload/admin/factory/class.ContactsMaps.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?
|
||||
namespace admin\factory;
|
||||
|
||||
class ContactsMaps
|
||||
{
|
||||
static public function products()
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
return $mdb->select(
|
||||
'pp_contacts_maps_products',
|
||||
[ 'id', 'code', 'name', 'icon' ],
|
||||
[
|
||||
'is_active' => 1,
|
||||
'ORDER' => [
|
||||
'sort' => 'ASC'
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
static public function provinces()
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
return $mdb->select(
|
||||
'pp_contacts_maps_provinces',
|
||||
[ 'id', 'code', 'name'],
|
||||
[
|
||||
'ORDER' => [
|
||||
'id' => 'ASC'
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
static public function get($id)
|
||||
{
|
||||
global $mdb;
|
||||
$id = (int)$id;
|
||||
if (!$id) return null;
|
||||
|
||||
|
||||
$row = $mdb->get(
|
||||
'pp_contacts_maps',
|
||||
'*',
|
||||
[ 'id' => $id ]
|
||||
);
|
||||
|
||||
if (!$row) return null;
|
||||
|
||||
$row['phones'] = json_decode($row['phones_json'], true) ?: [];
|
||||
$row['emails'] = json_decode($row['emails_json'], true) ?: [];
|
||||
$row['products'] = json_decode($row['products_json'], true) ?: [];
|
||||
|
||||
$row['coords'] = '';
|
||||
if (!empty($row['lat']) && !empty($row['lng'])) {
|
||||
$row['coords'] = $row['lat'] . ', ' . $row['lng'];
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
static public function save($v)
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
$id = (int)($v['id'] ?? 0);
|
||||
|
||||
// coords: "lat, lng"
|
||||
$coords = trim($v['coords'] ?? '');
|
||||
$lat = 0; $lng = 0;
|
||||
if ($coords) {
|
||||
$parts = array_map('trim', explode(',', $coords));
|
||||
if (count($parts) >= 2) {
|
||||
$lat = (float)str_replace(' ', '', $parts[0]);
|
||||
$lng = (float)str_replace(' ', '', $parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$phones = array_filter(array_map('trim', explode("\n", $v['phones'] ?? '')));
|
||||
$emails = array_filter(array_map('trim', explode("\n", $v['emails'] ?? '')));
|
||||
|
||||
$products = [];
|
||||
if (isset($v['products']) && is_array($v['products'])) {
|
||||
$products = $v['products'];
|
||||
}
|
||||
elseif (isset($v['products[]']) && is_array($v['products[]'])) {
|
||||
$products = $v['products[]'];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'province_id' => (int)($v['province_id'] ?? 0),
|
||||
'city' => trim($v['city'] ?? ''),
|
||||
'salon_type' => $v['salon_type'] ?? 'sales',
|
||||
'salon_name' => trim($v['salon_name'] ?? ''),
|
||||
'address' => trim($v['address'] ?? ''),
|
||||
|
||||
'lat' => $lat,
|
||||
'lng' => $lng,
|
||||
|
||||
'opening_hours' => trim($v['opening_hours'] ?? ''),
|
||||
'phones_json' => json_encode($phones, JSON_UNESCAPED_UNICODE),
|
||||
'emails_json' => json_encode($emails, JSON_UNESCAPED_UNICODE),
|
||||
'products_json' => json_encode(array_map('intval', $products)),
|
||||
|
||||
'button_label' => trim($v['button_label'] ?? 'SKONTAKTUJ SIĘ Z NAMI'),
|
||||
'button_url' => trim($v['button_url'] ?? ''),
|
||||
|
||||
'banner_image' => trim($v['banner_image'] ?? ''),
|
||||
'is_active' => !empty($v['is_active']) ? 1 : 0,
|
||||
'sort' => (int)($v['sort'] ?? 0),
|
||||
];
|
||||
|
||||
if ($id) {
|
||||
$mdb->update('pp_contacts_maps', $data, [ 'id' => $id ]);
|
||||
return $id;
|
||||
}
|
||||
|
||||
$mdb->insert('pp_contacts_maps', $data);
|
||||
return (int)$mdb->id();
|
||||
}
|
||||
|
||||
|
||||
static public function delete($id)
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
$id = (int)$id;
|
||||
if (!$id) return false;
|
||||
|
||||
return $mdb->delete(
|
||||
'pp_contacts_maps',
|
||||
[ 'id' => $id ]
|
||||
);
|
||||
}
|
||||
}
|
||||
24
autoload/front/controls/class.ContactsMapsApi.php
Normal file
24
autoload/front/controls/class.ContactsMapsApi.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?
|
||||
namespace front\controls;
|
||||
|
||||
class ContactsMapsApi
|
||||
{
|
||||
static public function index()
|
||||
{
|
||||
// JSON header
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
$only_active = true;
|
||||
if (\S::get('all') == 1) $only_active = false; // przykład ?all=1
|
||||
|
||||
$data = \front\factory\ContactsMaps::api_list($only_active);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'ok',
|
||||
'count' => count($data),
|
||||
'data' => $data,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
115
autoload/front/factory/class.ContactsMaps.php
Normal file
115
autoload/front/factory/class.ContactsMaps.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?
|
||||
namespace front\factory;
|
||||
|
||||
class ContactsMaps
|
||||
{
|
||||
static public function api_list($only_active = true)
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
// 1) забираємо довідники і індексуємо по id
|
||||
$provinces = $mdb->select(
|
||||
'pp_contacts_maps_provinces',
|
||||
[ 'id', 'code', 'name' ],
|
||||
[ 'ORDER' => [ 'id' => 'ASC' ] ]
|
||||
);
|
||||
|
||||
$provinces_by_id = [];
|
||||
foreach ($provinces as $p) {
|
||||
$provinces_by_id[(int)$p['id']] = $p;
|
||||
}
|
||||
|
||||
$products = $mdb->select(
|
||||
'pp_contacts_maps_products',
|
||||
[ 'id', 'code', 'name', 'icon' ],
|
||||
[
|
||||
'is_active' => 1,
|
||||
'ORDER' => [ 'sort' => 'ASC' ]
|
||||
]
|
||||
);
|
||||
|
||||
$products_by_id = [];
|
||||
foreach ($products as $pr) {
|
||||
$products_by_id[(int)$pr['id']] = $pr;
|
||||
}
|
||||
|
||||
// 2) забираємо салони
|
||||
$where = [
|
||||
'ORDER' => [ 'sort' => 'ASC' ]
|
||||
];
|
||||
if ($only_active) $where['is_active'] = 1;
|
||||
|
||||
$rows = $mdb->select('pp_contacts_maps', '*', $where);
|
||||
|
||||
// 3) збираємо API формат
|
||||
$out = [];
|
||||
foreach ($rows as $r)
|
||||
{
|
||||
$phones = json_decode($r['phones_json'] ?? '[]', true);
|
||||
if (!is_array($phones)) $phones = [];
|
||||
|
||||
$emails = json_decode($r['emails_json'] ?? '[]', true);
|
||||
if (!is_array($emails)) $emails = [];
|
||||
|
||||
$prod_ids = json_decode($r['products_json'] ?? '[]', true);
|
||||
if (!is_array($prod_ids)) $prod_ids = [];
|
||||
|
||||
$prod_out = [];
|
||||
foreach ($prod_ids as $pid) {
|
||||
$pid = (int)$pid;
|
||||
if (isset($products_by_id[$pid])) {
|
||||
$prod_out[] = [
|
||||
'id' => (int)$products_by_id[$pid]['id'],
|
||||
'code' => $products_by_id[$pid]['code'],
|
||||
'name' => $products_by_id[$pid]['name'],
|
||||
'icon' => $products_by_id[$pid]['icon'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$prov = $provinces_by_id[(int)$r['province_id']] ?? null;
|
||||
|
||||
$out[] = [
|
||||
'id' => (int)$r['id'],
|
||||
|
||||
'province' => $prov ? [
|
||||
'id' => (int)$prov['id'],
|
||||
'code' => $prov['code'],
|
||||
'name' => $prov['name'],
|
||||
] : null,
|
||||
|
||||
'city' => $r['city'],
|
||||
'salon_type' => $r['salon_type'],
|
||||
'salon_name' => $r['salon_name'],
|
||||
'address' => $r['address'],
|
||||
|
||||
'position' => [
|
||||
'lat' => (float)$r['lat'],
|
||||
'lng' => (float)$r['lng'],
|
||||
],
|
||||
|
||||
'opening_hours' => $r['opening_hours'] ?? '',
|
||||
|
||||
'contact' => [
|
||||
'phones' => array_values($phones),
|
||||
'emails' => array_values($emails),
|
||||
],
|
||||
|
||||
'products' => $prod_out,
|
||||
|
||||
'button' => [
|
||||
'label' => $r['button_label'] ?? '',
|
||||
'url' => $r['button_url'] ?? '',
|
||||
],
|
||||
|
||||
'banner_image' => $r['banner_image'] ?? '',
|
||||
|
||||
'is_active' => (int)$r['is_active'],
|
||||
'sort' => (int)$r['sort'],
|
||||
'updated_at' => $r['updated_at'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
5
images/products/icon_product_1.svg
Normal file
5
images/products/icon_product_1.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="34" height="29" viewBox="0 0 34 29" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.21484 26.3117L16.6101 26.3326L16.6279 16.2073L16.2782 16.0043C15.8811 15.7744 15.4841 15.1264 15.487 14.1948C15.487 13.4005 15.813 12.66 16.2812 12.3913L16.6338 12.1882L16.6427 2.05996L2.25633 2.03906L2.21484 26.3087V26.3117ZM3.64903 3.44842L15.247 3.46634L15.2411 11.4179C14.5329 12.018 14.0914 13.0572 14.0914 14.1948C14.0884 15.3294 14.524 16.3715 15.2322 16.9777L15.2174 24.9292L3.61348 24.9113L3.652 3.45439L3.64903 3.44842Z" fill="#1E2832"/>
|
||||
<path d="M17.1204 12.1848L17.4701 12.3879C17.9383 12.6596 18.2642 13.4031 18.2613 14.1973C18.2613 15.123 17.8494 15.7829 17.4671 16.0008L17.1175 16.2039L17.0938 26.3292L31.489 26.356L31.5216 2.0834L17.1323 2.0625L17.1145 12.1848H17.1204ZM18.5131 16.9742C19.2184 16.3741 19.6569 15.332 19.6569 14.2003C19.6599 13.0627 19.2243 12.0206 18.5161 11.4174L18.5309 3.47186L30.1289 3.48978L30.0992 24.9467L18.4953 24.9258L18.5131 16.9742Z" fill="#1E2832"/>
|
||||
<path d="M0 28.3425L33.7124 28.3932L33.7509 0.0507609L0.0444481 0L0 28.3425ZM1.44012 1.40936L32.3523 1.45714L32.3197 26.9869L1.39863 26.9391L1.44012 1.40936Z" fill="#1E2832"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
4
images/products/icon_product_2.svg
Normal file
4
images/products/icon_product_2.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="31" height="38" viewBox="0 0 31 38" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M26.9423 34.3686L26.9887 0.0306937L2.91691 0L2.87052 34.3686H0V37.2594H30.1955V34.3686H26.9423ZM5.96429 34.3686V26.1204L6.01069 3.10286V2.97729L23.9529 3.00241L23.9094 26.1483V34.3714H5.96429V34.3686ZM4.27968 1.31704L25.6201 1.34494L25.5766 34.3686H25.275V26.1483L25.3185 3.34562L25.3243 1.69095L4.64502 1.66304L4.59863 26.1204V34.3379H4.23329L4.27678 1.31704H4.27968Z" fill="#1E2832"/>
|
||||
<path d="M20.2605 16.3594C19.7299 16.3594 19.3008 16.7723 19.3008 17.283C19.3008 17.7936 19.7299 18.2066 20.2605 18.2066C20.7911 18.2066 21.2203 17.7936 21.2203 17.283C21.2203 16.7723 20.7911 16.3594 20.2605 16.3594Z" fill="#1E2832"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 734 B |
7
images/products/icon_product_3.svg
Normal file
7
images/products/icon_product_3.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg width="34" height="31" viewBox="0 0 34 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32.0376 0.0464607L1.80016 0L1.75668 26.108H0.00579762L0 30.1153L33.7421 30.1675L33.7479 26.1603H31.997L32.0347 0.0493645L32.0376 0.0464607ZM32.3826 27.5222V28.7969L2.435 28.7476H1.36824V27.4757L3.12202 27.4786L3.1655 1.37059L30.6723 1.41125L30.6346 27.5193H32.3855L32.3826 27.5222Z" fill="#1E2832"/>
|
||||
<path d="M29.0056 3.46875H4.77734V4.87128H29.0056V3.46875Z" fill="#1E2832"/>
|
||||
<path d="M29.0056 13.9609H4.77734V15.3635H29.0056V13.9609Z" fill="#1E2832"/>
|
||||
<path d="M29.0056 8.71094H4.77734V10.1135H29.0056V8.71094Z" fill="#1E2832"/>
|
||||
<path d="M4.09375 26.4581H29.6873V17.7118L4.09375 17.7031V26.4552V26.4581ZM5.45909 19.0737L28.322 19.0795V25.0904H5.45909V19.0737Z" fill="#1E2832"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 793 B |
Reference in New Issue
Block a user