wip: Mobile-Theme-Testphase und PHP-8.2-Guards (Stand Juni 2026)
This commit is contained in:
@@ -0,0 +1,407 @@
|
||||
/* =================================================================
|
||||
Mobile-Theme — CSS Overrides für geerbte theme2/easyshop_advanced
|
||||
Templates, die auf Mobile sonst zerschossen aussehen.
|
||||
================================================================= */
|
||||
|
||||
/* --- Generic resets für geerbte Tables/Widths --- */
|
||||
.content_box_structure_list table,
|
||||
.content_box_structure_list table td,
|
||||
.widget_content_wrapper table,
|
||||
.widget_content_wrapper table td {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
.content_box_structure_list img,
|
||||
.structure_item img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* --- Strukturlisten (Hauptkategorien auf Home) als Cards/Grid --- */
|
||||
.content_box_structure_list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
padding: 0;
|
||||
margin: 12px 0 24px;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
.content_box_structure_list .header,
|
||||
.content_box_structure_list > .content > .header {
|
||||
grid-column: 1 / -1;
|
||||
background: transparent !important;
|
||||
padding: 0;
|
||||
}
|
||||
.content_box_structure_list .header h1,
|
||||
.content_box_structure_list .header h2 {
|
||||
font-size: 1.05rem !important;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
margin: 8px 0 12px;
|
||||
padding: 0;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
.content_box_structure_list > .content {
|
||||
display: contents;
|
||||
}
|
||||
.structure_item {
|
||||
display: block;
|
||||
background: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.06);
|
||||
transition: transform .1s ease, box-shadow .1s ease;
|
||||
}
|
||||
.structure_item:active {
|
||||
transform: scale(.98);
|
||||
}
|
||||
.structure_item > a {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: stretch !important;
|
||||
padding: 0 !important;
|
||||
background: transparent !important;
|
||||
color: #222 !important;
|
||||
text-decoration: none !important;
|
||||
min-height: 160px;
|
||||
}
|
||||
.structure_item .image_wrapper {
|
||||
order: 1;
|
||||
background: #f9f9f9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 110px;
|
||||
padding: 8px;
|
||||
}
|
||||
.structure_item .image_wrapper img {
|
||||
max-height: 100px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
.structure_item .structure_item_text_sign {
|
||||
display: none !important; /* das » brauchen wir auf Mobile nicht */
|
||||
}
|
||||
.structure_item .structure_item_text {
|
||||
order: 2;
|
||||
display: block !important;
|
||||
padding: 8px 10px !important;
|
||||
background: #fff !important;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
.structure_item .structure_item_text span {
|
||||
font-size: 14px !important;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* --- Content-Boxen (allgemein) --- */
|
||||
.content_box_textbox,
|
||||
.content_box_substructure,
|
||||
.content_box_item_list {
|
||||
background: #fff !important;
|
||||
border: 1px solid #eee !important;
|
||||
border-radius: 8px;
|
||||
padding: 12px !important;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.05);
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.content_box_textbox h1,
|
||||
.content_box_textbox h2 {
|
||||
font-size: 1.1rem !important;
|
||||
color: #c00;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
/* --- Item-Liste (geerbt aus theme2 item_box.tpl) --- */
|
||||
.itemBox,
|
||||
.item_box,
|
||||
.shopItem {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
background: #fff;
|
||||
border: 1px solid #eee !important;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px !important;
|
||||
padding: 12px !important;
|
||||
width: 100% !important;
|
||||
float: none !important;
|
||||
}
|
||||
.itemBox img,
|
||||
.item_box img,
|
||||
.shopItem img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Sortier-Dropdown (JS, Desktop-only) — auf Mobile aus
|
||||
============================================ */
|
||||
.sort_wrapper {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
SEO-Textbaustein NUR auf Item-Listen-Seiten verstecken
|
||||
(CMS-Seiten wie AGB/Datenschutz/Widerruf nutzen denselben
|
||||
.content_box_textbox-Wrapper für Inhalt — den dort zeigen!)
|
||||
Marker: nur wenn body auch eine .content_box_item_list enthält.
|
||||
============================================ */
|
||||
body:has(.content_box_item_list) .content_box_textbox > .content,
|
||||
body:has(.content_box_item_list) .content_box_textbox .text_box_hidden_text,
|
||||
body:has(.content_box_item_list) .content_box_textbox .text_box_link_show_text,
|
||||
body:has(.content_box_item_list) .content_box_textbox .text_box_link_hide_text {
|
||||
display: none !important;
|
||||
}
|
||||
.content_box_textbox > .header {
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
padding: 4px 0 8px !important;
|
||||
}
|
||||
.content_box_textbox > .header h1 {
|
||||
font-size: 1.25rem !important;
|
||||
color: #c00 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Item-Liste (.list_item_box)
|
||||
============================================ */
|
||||
.content_box_item_list {
|
||||
padding: 0 !important;
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.list_item_box {
|
||||
display: grid !important;
|
||||
grid-template-columns: 100px 1fr;
|
||||
gap: 12px;
|
||||
background: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
width: 100% !important;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.04);
|
||||
float: none !important;
|
||||
}
|
||||
.list_item_box .imagebox {
|
||||
grid-row: 1 / span 5;
|
||||
width: 100px !important;
|
||||
height: 100px !important;
|
||||
background-color: #f9f9f9 !important;
|
||||
background-size: contain !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: center !important;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #f0f0f0;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.list_item_box .imagebox span {
|
||||
position: absolute;
|
||||
left: -9999px; /* "Zeige alle Bilder" Text auf Mobile weg */
|
||||
}
|
||||
|
||||
/* Daten-Block rechts neben Bild */
|
||||
.list_item_box .primary_data_box {
|
||||
min-width: 0;
|
||||
}
|
||||
.list_item_box .artname h2 {
|
||||
font-size: 0.95rem !important;
|
||||
line-height: 1.3 !important;
|
||||
margin: 0 0 6px !important;
|
||||
color: #222;
|
||||
}
|
||||
.list_item_box .artname h2 a {
|
||||
color: #222 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.list_item_box .product_no {
|
||||
font-size: 0.78rem !important;
|
||||
color: #666;
|
||||
margin: 0 0 4px !important;
|
||||
}
|
||||
.list_item_box .product_no strong {
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
}
|
||||
.list_item_box .artmanulogo img {
|
||||
max-height: 24px;
|
||||
width: auto !important;
|
||||
}
|
||||
.list_item_box .availability {
|
||||
font-size: 0.82rem;
|
||||
margin: 6px 0;
|
||||
}
|
||||
.list_item_box .availability .notAvailable {
|
||||
display: inline-block;
|
||||
background: #fff4f4;
|
||||
border-left: 3px solid #c00;
|
||||
padding: 6px 8px;
|
||||
font-size: 0.75rem !important;
|
||||
}
|
||||
|
||||
/* Action-Buttons + Preis (gehen unter den Daten in voller Breite) */
|
||||
.list_item_box .variants_box,
|
||||
.list_item_box .link_box,
|
||||
.list_item_box #artinfobox,
|
||||
.list_item_box .linkbox,
|
||||
.list_item_box .pricing_box {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.list_item_box .link_box {
|
||||
font-size: 0.78rem;
|
||||
color: #555;
|
||||
border-top: 1px dashed #eee;
|
||||
padding-top: 8px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.list_item_box .link_box a {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
margin: 2px 4px 2px 0;
|
||||
background: #f4f4f4;
|
||||
border-radius: 4px;
|
||||
text-decoration: none !important;
|
||||
color: #333 !important;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
.list_item_box .button_details,
|
||||
.list_item_box .button_details_no {
|
||||
display: inline-block !important;
|
||||
background: #c00 !important;
|
||||
background-image: none !important;
|
||||
color: #fff !important;
|
||||
padding: 10px 16px !important;
|
||||
border-radius: 6px !important;
|
||||
font-weight: 600;
|
||||
text-decoration: none !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-height: 44px;
|
||||
line-height: 1.4;
|
||||
border: 0 !important;
|
||||
}
|
||||
.list_item_box .button_details_no {
|
||||
background: #6c757d !important;
|
||||
}
|
||||
.list_item_box .pricing_box {
|
||||
font-size: 1.1rem;
|
||||
color: #c00;
|
||||
font-weight: 700;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Pagination — Mobile: nur die untere Variante sichtbar.
|
||||
Carteasy rendert Pagination + 24/48/alle-Switcher doppelt
|
||||
(oben + unten). Auf Mobile macht oben keinen Sinn.
|
||||
============================================ */
|
||||
.list_item_shown_wrapper:first-of-type,
|
||||
.pagination:first-of-type {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.list_item_shown_wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
margin: 16px 0;
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
.pagingButton {
|
||||
display: inline-block;
|
||||
min-width: 38px;
|
||||
min-height: 38px;
|
||||
line-height: 38px;
|
||||
padding: 0 8px;
|
||||
text-align: center;
|
||||
background: #f4f4f4;
|
||||
border-radius: 6px;
|
||||
text-decoration: none !important;
|
||||
color: #333 !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
.pagingButton.activ {
|
||||
background: #c00 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
margin: 12px 0 20px;
|
||||
}
|
||||
.pagination a {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 40px;
|
||||
min-height: 40px;
|
||||
padding: 0 10px;
|
||||
background: #f4f4f4;
|
||||
border-radius: 6px;
|
||||
text-decoration: none !important;
|
||||
color: #333 !important;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.pagination_button.highlight,
|
||||
.pagination a.highlight {
|
||||
background: #c00 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.pagination_back,
|
||||
.pagination_forward {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ddd !important;
|
||||
}
|
||||
.pagination_back::before { content: "‹"; font-size: 1.3rem; line-height: 1; }
|
||||
.pagination_forward::before { content: "›"; font-size: 1.3rem; line-height: 1; }
|
||||
.pagination_back.inactive,
|
||||
.pagination_forward.inactive {
|
||||
opacity: 0.35;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* --- Tabellen die per width in PX gesetzt sind --- */
|
||||
[style*="width:992px"],
|
||||
[style*="width:720px"],
|
||||
[style*="width:600px"],
|
||||
[style*="width:480px"] {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
[style*="float:left"],
|
||||
[style*="float:right"] {
|
||||
float: none !important;
|
||||
}
|
||||
|
||||
/* --- Headings im Content-Bereich kompakter --- */
|
||||
main h1 { font-size: 1.35rem; line-height: 1.3; }
|
||||
main h2 { font-size: 1.15rem; line-height: 1.3; }
|
||||
main h3 { font-size: 1.05rem; line-height: 1.3; }
|
||||
|
||||
/* --- Inputs touch-freundlich (mindestens 44px Tap-Target) --- */
|
||||
main input[type=text],
|
||||
main input[type=number],
|
||||
main input[type=email],
|
||||
main input[type=tel],
|
||||
main select,
|
||||
main button,
|
||||
main .btn {
|
||||
min-height: 44px;
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<!-- mobile:content_item -->
|
||||
|
||||
{* MVP-Mobile-Item-Detail mit Bootstrap 5 Card-Layout.
|
||||
Variablen aus $shopArticle (siehe Desktop-content_item.tpl).
|
||||
POST geht zur selben URL (kein action= nötig). *}
|
||||
|
||||
{assign var=item_image_first value=""}
|
||||
{if isset($shopArticle->files[0]) && $shopArticle->files[0]->file_name}
|
||||
{assign var=item_image_first value=$shopArticle->files[0]->file_name}
|
||||
{/if}
|
||||
|
||||
<form method="post" id="item_buy_form">
|
||||
<input type="hidden" name="buy_quantity" value="{$shopArticle->buy_quantity}">
|
||||
<input type="hidden" name="min_quantity" value="{$shopArticle->min_quantity}">
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="javascript:history.back()" class="text-muted text-decoration-none small">
|
||||
<i class="bi bi-arrow-left"></i> zurück
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{* --- Hauptbild + Bildergalerie --- *}
|
||||
<div class="card shop-item-card mb-3">
|
||||
{if $item_image_first}
|
||||
<div id="itemImageSlider" class="carousel slide" data-bs-ride="false">
|
||||
{if $shopArticle->files|@count > 1}
|
||||
<div class="carousel-indicators">
|
||||
{foreach from=$shopArticle->files item=file name=indi}
|
||||
<button type="button" data-bs-target="#itemImageSlider" data-bs-slide-to="{$smarty.foreach.indi.index}"
|
||||
{if $smarty.foreach.indi.first}class="active"{/if} aria-label="Bild {$smarty.foreach.indi.iteration}"></button>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="carousel-inner bg-white">
|
||||
{foreach from=$shopArticle->files item=file name=slides}
|
||||
<div class="carousel-item {if $smarty.foreach.slides.first}active{/if}">
|
||||
<a href="{$SHOP_DIR}images/article/{$file->file_name}" target="_blank">
|
||||
<img src="{$SHOP_DIR}images/article/details_{$file->file_name}"
|
||||
class="d-block w-100" style="height:280px;object-fit:contain;background:#fff;"
|
||||
alt="{if isset($file->alt)}{$file->alt|escape:'html'}{else}{$shopArticle->name|escape:'html'}{/if}">
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{if $shopArticle->files|@count > 1}
|
||||
<button class="carousel-control-prev" type="button" data-bs-target="#itemImageSlider" data-bs-slide="prev">
|
||||
<span class="carousel-control-prev-icon" aria-hidden="true" style="background-color:rgba(0,0,0,.3);border-radius:50%;"></span>
|
||||
</button>
|
||||
<button class="carousel-control-next" type="button" data-bs-target="#itemImageSlider" data-bs-slide="next">
|
||||
<span class="carousel-control-next-icon" aria-hidden="true" style="background-color:rgba(0,0,0,.3);border-radius:50%;"></span>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{else}
|
||||
<div class="card-body text-center text-muted py-5">
|
||||
<i class="bi bi-image" style="font-size:3rem;"></i><br>
|
||||
<small>Kein Bild verfügbar</small>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{* --- Titel + Hersteller + Artikelnummer --- *}
|
||||
<div class="card shop-item-card mb-3">
|
||||
<div class="card-body">
|
||||
<h1 class="h4 mb-2">
|
||||
{if !$user_lang || $user_lang == $system_configuration.default_system_language || !$shopArticle->name_en}
|
||||
{$shopArticle->name}
|
||||
{else}
|
||||
{$shopArticle->name_en}
|
||||
{/if}
|
||||
</h1>
|
||||
|
||||
{if isset($shopArticle->manufacturer_data->name) && $shopArticle->manufacturer_data->name}
|
||||
<span class="badge bg-secondary mb-2">{$shopArticle->manufacturer_data->name}</span>
|
||||
{/if}
|
||||
|
||||
{if $shopArticle->number}
|
||||
<div class="small text-muted mb-2">
|
||||
{$template_text.item_details.item_number}:
|
||||
<strong>
|
||||
{if $shopArticle->attribute_7 && $shopArticle->number != $shopArticle->attribute_7}
|
||||
{$shopArticle->attribute_7}
|
||||
<span class="text-muted">(alt: {$shopArticle->number})</span>
|
||||
{else}
|
||||
{$shopArticle->number}
|
||||
{/if}
|
||||
</strong>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* Lagerbestand *}
|
||||
{if $shopArticle->inventory > 0}
|
||||
<div class="text-success small">
|
||||
<i class="bi bi-check-circle-fill"></i> Auf Lager — {$shopArticle->inventory} Stück verfügbar
|
||||
</div>
|
||||
{elseif $shopArticle->inventory === 0}
|
||||
<div class="text-danger small">
|
||||
<i class="bi bi-x-circle-fill"></i> Aktuell nicht verfügbar
|
||||
</div>
|
||||
{else}
|
||||
<div class="text-muted small">
|
||||
<i class="bi bi-info-circle"></i> Lieferzeit auf Anfrage
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* --- Preis + Add-to-Cart --- *}
|
||||
<div class="card shop-item-card mb-3" id="priceBox">
|
||||
<div class="card-body">
|
||||
{if $shopArticle->shop_price_1 > 0}
|
||||
<div class="mb-2">
|
||||
<span class="h3 text-danger">
|
||||
{$shopArticle->shop_price_1|number_format:"2":",":"."} €
|
||||
</span>
|
||||
<small class="text-muted">inkl. MwSt.</small>
|
||||
</div>
|
||||
{else}
|
||||
<div class="mb-2 text-muted">
|
||||
Preis auf Anfrage
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<label for="qty" class="visually-hidden">Menge</label>
|
||||
<input type="number" name="quantity" id="qty"
|
||||
class="form-control text-center" style="max-width:90px;"
|
||||
value="{if $shopArticle->min_quantity > 0}{$shopArticle->min_quantity}{else}1{/if}"
|
||||
min="{if $shopArticle->min_quantity > 0}{$shopArticle->min_quantity}{else}1{/if}"
|
||||
step="{if $shopArticle->buy_quantity > 0}{$shopArticle->buy_quantity}{else}1{/if}">
|
||||
|
||||
<button type="submit" name="item_to_cart" value="1" class="btn btn-brand btn-lg flex-grow-1">
|
||||
<i class="bi bi-bag-plus"></i> In den Warenkorb
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* --- Beschreibung + weitere Tabs als Accordion --- *}
|
||||
{if isset($shopArticle->tab_content) && $shopArticle->tab_content}
|
||||
<div class="accordion mb-3" id="itemDetailsAcc">
|
||||
{foreach from=$shopArticle->tab_content item=content key=content_id name=tabs}
|
||||
{assign var=tab_label value=""}
|
||||
{if isset($shopArticle->tab_title[$content_id])}
|
||||
{assign var=tab_label value=$shopArticle->tab_title[$content_id]}
|
||||
{else}
|
||||
{assign var=tab_label value=$template_text.item_details.description}
|
||||
{/if}
|
||||
{if $content}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button {if !$smarty.foreach.tabs.first}collapsed{/if}"
|
||||
type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#tabColl_{$content_id}"
|
||||
aria-expanded="{if $smarty.foreach.tabs.first}true{else}false{/if}">
|
||||
{$tab_label}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="tabColl_{$content_id}" class="accordion-collapse collapse {if $smarty.foreach.tabs.first}show{/if}" data-bs-parent="#itemDetailsAcc">
|
||||
<div class="accordion-body">
|
||||
{$content}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/foreach}
|
||||
|
||||
{* Technische Daten als zusätzlicher Block, falls Attribute vorhanden *}
|
||||
{if isset($shopArticle->schema_data_attributes) && $shopArticle->schema_data_attributes}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#tabColl_attributes" aria-expanded="false">
|
||||
Technische Daten
|
||||
</button>
|
||||
</h2>
|
||||
<div id="tabColl_attributes" class="accordion-collapse collapse" data-bs-parent="#itemDetailsAcc">
|
||||
<div class="accordion-body">
|
||||
<table class="table table-sm table-borderless mb-0">
|
||||
<tbody>
|
||||
{foreach from=$shopArticle->schema_data_attributes item=attribute}
|
||||
{if $attribute.name}
|
||||
<tr>
|
||||
<th scope="row" class="text-muted fw-normal" style="width:45%;">{$attribute.name}</th>
|
||||
<td>{$attribute.value|default:''}{if $attribute.unit} {$attribute.unit}{/if}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</form>
|
||||
|
||||
{* --- Sticky-Bottom-Bar (Quick Add) --- *}
|
||||
<div class="position-fixed bottom-0 start-0 end-0 bg-white shadow-lg p-2 d-md-none" style="z-index:1030;border-top:1px solid #eee;">
|
||||
<div class="d-flex gap-2">
|
||||
<a href="#priceBox" class="btn btn-brand flex-grow-1">
|
||||
<i class="bi bi-bag-plus"></i> Zum Warenkorb hinzufügen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>{if isset($html_meta.title)}{$html_meta.title}{else}{$system_configuration.full_shop_name}{/if}</title>
|
||||
|
||||
{if isset($html_meta.description)}<meta name="description" content="{$html_meta.description}">{/if}
|
||||
{if isset($html_meta.keywords)}<meta name="keywords" content="{$html_meta.keywords}">{/if}
|
||||
|
||||
<link rel="canonical" href="{$serverProtocol}://{$servername}{$currentURI}">
|
||||
<link rel="icon" href="{$SUB_DIR}favicon.ico" type="image/x-icon">
|
||||
|
||||
{* Bootstrap 5.3 *}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
|
||||
|
||||
{* Eigenes Mobile-CSS *}
|
||||
<link rel="stylesheet" href="{$THEME_DIR}/media/css/mobile.css?v=6">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--brand-color: #c00;
|
||||
--brand-color-dark: #a00;
|
||||
}
|
||||
body { padding-top: 56px; padding-bottom: 80px; }
|
||||
.navbar-brand img { max-height: 36px; }
|
||||
.shop-item-card { border: 0; box-shadow: 0 1px 3px rgba(0,0,0,.08); margin-bottom: 12px; }
|
||||
.btn-brand { background: var(--brand-color); color: #fff; border: 0; }
|
||||
.btn-brand:hover { background: var(--brand-color-dark); color: #fff; }
|
||||
.theme-switch-hint {
|
||||
position: fixed; bottom: 8px; right: 8px; z-index: 999;
|
||||
background: rgba(0,0,0,.7); color: #fff; padding: 4px 10px;
|
||||
border-radius: 12px; font-size: 11px; text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{* --- Top-Bar --- *}
|
||||
<nav class="navbar navbar-expand-lg fixed-top bg-white shadow-sm" aria-label="Hauptnavigation">
|
||||
<div class="container-fluid">
|
||||
<button class="navbar-toggler border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#mobileNav" aria-controls="mobileNav" aria-label="Menü öffnen">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<a class="navbar-brand mx-auto" href="{$SUB_DIR}">
|
||||
<strong>{$system_configuration.full_shop_name}</strong>
|
||||
</a>
|
||||
|
||||
<a href="{$SUB_DIR}index.php?website_modul=website_shoppingcart" class="btn btn-link text-dark p-0" aria-label="Warenkorb">
|
||||
<i class="bi bi-bag" style="font-size: 1.5rem;"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{* --- Off-Canvas Nav --- *}
|
||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="mobileNav" aria-labelledby="mobileNavLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="mobileNavLabel">Menü</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Schließen"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<form action="{$SUB_DIR}" method="get" class="mb-3">
|
||||
<div class="input-group">
|
||||
<input type="text" name="search_item[search_item]" class="form-control" placeholder="Suchen…" autocomplete="off">
|
||||
<button class="btn btn-brand" type="submit"><i class="bi bi-search"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}">Startseite</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}Mein-Konto/">Mein Konto</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}Kontakt/">Kontakt</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}Widerrufsrecht/">Widerrufsbelehrung</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}AGB/">AGB</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}Datenschutz/">Datenschutz</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="{$SUB_DIR}Impressum/">Impressum</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* --- Content --- *}
|
||||
<main class="container py-3">
|
||||
{$maincontent}
|
||||
</main>
|
||||
|
||||
{* --- Footer --- *}
|
||||
<footer class="bg-light py-4 mt-4 border-top">
|
||||
<div class="container text-center">
|
||||
<a class="btn btn-brand btn-lg mb-2" href="{$SUB_DIR}widerruf.php">
|
||||
Vertrag widerrufen
|
||||
</a>
|
||||
<p class="small text-muted mb-1">Elektronische Widerrufsfunktion gem. § 356a BGB</p>
|
||||
<hr class="my-3">
|
||||
<p class="small text-muted mb-0">
|
||||
<strong>{$system_configuration.full_shop_name}</strong> ·
|
||||
{$system_configuration.footer_copyright_text}
|
||||
</p>
|
||||
<p class="small mt-2 mb-0">
|
||||
<a href="?theme=theme2" class="text-muted">Zur Desktop-Version</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{* Theme-Switch Hint (nur Test-Phase) *}
|
||||
<a href="?theme=theme2" class="theme-switch-hint">📱 mobile · zurück zur Desktop-Version</a>
|
||||
|
||||
{* Bootstrap 5 JS bundle *}
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user