$this->data['title'] = $page->title;
$this->data['page'] = $page->withFakes()->getDecodedAttributes();
+ $this->data['model'] = $page; // So we can access model functions like ->getMedia()
return view('pages.' . $page->template, $this->data);
}
class Page extends CMSPage
{
+ function getImages($collectionName) {
+ return $this->getMedia($collectionName);
+ }
+
+ function getImage($collectionName) {
+ return $this->getImages($collectionName)->first();
+ }
+
+ function getImageURL($collectionName) {
+ return $this->getImage($collectionName)->getUrl();
+ }
}
'label' => __('Adresse'),
'translatable' => false,
'tab' => 'Informations de contact']);
+
+ //=== Social Networks
+ $this->addField([
+ 'name' => 'social',
+ 'type' => 'BunchOfFields',
+ 'bunch' => 'App\SubForms\SocialNetworks',
+ 'label' => __('Réseaux Sociaux'),
+ 'tab' => __('Réseaux Sociaux'),
+ ]);
}
}
try {
// BladeX Component Aliases
// Ref: https://docs.spatie.be/laravel-blade-x/v2/introduction
+ BladeX::component('components.column'); // <column> ... </column>
+ BladeX::component('components.columns'); // <columns> ... </columns>
+ BladeX::component('components.content'); // <content> ... </content>
BladeX::component('components.flexible-image'); // <flexible-image />
BladeX::component('components.full-width'); // <full-width> ... </full-width>
- BladeX::component('components.content'); // <content> ... </content>
- BladeX::component('components.columns'); // <columns> ... </columns>
- BladeX::component('components.column'); // <column> ... </column>
BladeX::component('components.grid'); // <grid cols="3" gap="md"> ... </grid>
- BladeX::component('components.text-block'); // <text-block> ... </text-block>
+ BladeX::component('components.intro-block'); // <intro-block title="..." image="..."> ... </intro-block>
BladeX::component('components.link-button'); // <link-button> ... </link-button>
- BladeX::component('components.phone-link'); // <phone-link number="012345"> ... </phone-link>
BladeX::component('components.map-link'); // <map-link address="..."> ... </map-link>
+ BladeX::component('components.phone-link'); // <phone-link number="012345"> ... </phone-link>
+ BladeX::component('components.text-block'); // <text-block> ... </text-block>
} catch (\Exception $e) {
}
--- /dev/null
+<?php
+
+
+namespace App\SubForms;
+
+
+use Cubist\Backpack\app\Magic\SubForm;
+
+class SocialNetworks extends SubForm
+{
+ public function init()
+ {
+ parent::init();
+
+ $this->addField(['name' => 'twitter',
+ 'type' => 'Text',
+ 'label' => __('Twitter'),
+ 'translatable' => false]);
+
+ $this->addField(['name' => 'linkedin',
+ 'type' => 'Text',
+ 'label' => __('LinkedIn'),
+ 'translatable' => false]);
+ }
+}
<template>
- <div class="tabs" :class="`mode-${currentMode}`">
+ <div class="tabs" :class="`mode-${currentMode}`" v-show="tabs.length > 0">
<ul role="tablist" class="tabs-list">
<li v-for="(tab, i) in tabs"
:key="i"
+++ /dev/null
-$(function () {
- $(document).on('click', '#product-tabs .section-title', function () {
- let that = $(this);
-
- $('.content-item').each(function () {
- if ($(this).data('content') === that.data('nav')) {
- $(this).addClass('active-content').siblings().removeClass('active-content').addClass('hidden');
- that.addClass('active-nav').parent().siblings().find(".section-title").removeClass('active-nav');
- }
- });
-
- if ($(window).width() < 940) {
- $('.responsive-content').each(function () {
- if ($(this).data('content') === that.data('nav')) {
- that.find('.product-nav-arrow').toggleClass('rotate');
- }
- })
- }
- })
-
- $(".section-title").click(function () {
- $(this)
- .toggleClass('active-content')
- .siblings(".responsive-content")
- .slideToggle()
- });
-
-});
grid-auto-columns: unset
grid-auto-flow: unset
- // When columns are stacked, add margins between them
- .column
- constrain(margin-bottom, $vertical-gutter)
+.column
+ // When columns are stacked, add margins between them
+ +below($breakpoint-columns)
+ constrain(margin-bottom, $vertical-gutter)
y: vertical, // special case for both top & bottom padding
}
-// Generate classes
-for counter, vwAmount in $vw-spacing
+// Generate classes with responsive variations
+@responsive
+ for counter, vwAmount in $vw-spacing
- // First, generate classes for all sides + grid gaps...
+ // First, generate classes for all sides + grid gaps...
- // Padding (p-1v, p-2v etc)
- .p-{counter}v
- constrain(padding, vwAmount)
+ // Padding (p-1v, p-2v etc)
+ .p-{counter}v
+ constrain(padding, vwAmount)
- // Margins (m-1v, m-2v etc)
- .m-{counter}v
- constrain(margin, vwAmount)
+ // Margins (m-1v, m-2v etc)
+ .m-{counter}v
+ constrain(margin, vwAmount)
- // Negative margins (-m-1v, -m-2v etc)
- .-m-{counter}v
- constrain(margin, - vwAmount)
+ // Negative margins (-m-1v, -m-2v etc)
+ .-m-{counter}v
+ constrain(margin, - vwAmount)
- // Next, generate classes for individual sides
- for sideAbbreviation, side in $sides
+ // Next, generate classes for individual sides
+ for sideAbbreviation, side in $sides
- // Padding utilities (pt, pr, pb, pl, px, py)
- .p{sideAbbreviation}-{counter}v
- $property = s('padding-%s', side)
+ // Padding utilities (pt, pr, pb, pl, px, py)
+ .p{sideAbbreviation}-{counter}v
+ $property = s('padding-%s', side)
- if (side is 'horizontal')
- horizontal-spacing(vwAmount)
- else if (side is 'vertical')
- vertical-spacing(vwAmount)
- else
- constrain($property, vwAmount)
+ if (side is 'horizontal')
+ horizontal-spacing(vwAmount)
+ else if (side is 'vertical')
+ vertical-spacing(vwAmount)
+ else
+ constrain($property, vwAmount)
- // Margin utilities (mt, mr, mb, ml, mx, my)
- .m{sideAbbreviation}-{counter}v
- $property = s('margin-%s', side)
+ // Margin utilities (mt, mr, mb, ml, mx, my)
+ .m{sideAbbreviation}-{counter}v
+ $property = s('margin-%s', side)
- if (side is 'horizontal')
- horizontal-spacing(vwAmount, 'margin')
- else if (side is 'vertical')
- vertical-spacing(vwAmount, 'margin')
- else
- constrain($property, vwAmount)
+ if (side is 'horizontal')
+ horizontal-spacing(vwAmount, 'margin')
+ else if (side is 'vertical')
+ vertical-spacing(vwAmount, 'margin')
+ else
+ constrain($property, vwAmount)
- // Negative margin utilities (-mt, -mr, -mb, -ml, -mx, -my)
- .-m{sideAbbreviation}-{counter}v
- $property = s('margin-%s', side)
+ // Negative margin utilities (-mt, -mr, -mb, -ml, -mx, -my)
+ .-m{sideAbbreviation}-{counter}v
+ $property = s('margin-%s', side)
- if (side is 'horizontal')
- horizontal-spacing( - vwAmount, 'margin')
- else if (side is 'vertical')
- vertical-spacing( - vwAmount, 'margin')
- else
- constrain($property, - vwAmount)
+ if (side is 'horizontal')
+ horizontal-spacing( - vwAmount, 'margin')
+ else if (side is 'vertical')
+ vertical-spacing( - vwAmount, 'margin')
+ else
+ constrain($property, - vwAmount)
--- /dev/null
+// Contact details
+.contact-details
+ // The link
+ &-block
+ @apply flex text-inherit mb-6
+
+ &:hover
+ @apply text-blue
+
+ .contact-details-icon
+ transform: scale(1.1)
+
+ &-icon
+ @apply mr-4
+ transform: scale(1)
+ transition: transform 0.1s ease-out
+
+ &-title
+ @apply font-display
+
+// Contact page overrides
+.contact-page
+ .contact-details
+ &-icon
+ @apply text-navy
+ &-title
+ @apply font-bold font-body text-navy
+
@apply fixed text-white
top: 215px
left: 100% // Container needs to be right off the screen, otherwise it might block elements below it
- transform: translateX(- $contact-tab-width)
a
@apply text-inherit
&-tab
white-space: nowrap
- transform: none
+ transform: translateX(- $contact-tab-width)
transition: transform 0.5s ease
&:hover
- transform: s('translateX(calc(-100% + %s))', $contact-tab-width)
+ transform: translateX(-100%)
.contact-shortcut-detail
transform: none
transition-delay: 0s
max-width: 42em
- // Contact details
- &-contact
- // The link
- &-block
- @apply flex text-white mb-6
-
- &:hover
- @apply text-blue
-
- .footer-contact-icon
- transform: scale(1.1)
-
- &-icon
- @apply mr-4
- transform: scale(1)
- transition: transform 0.1s ease-out
-
- &-title
- @apply font-display
-
-
// Sub-footer
&-end
$ratio = $meta[1] / $meta[0] * 100 .'%'; // Height / Width
@endphp
- <div class="bg-image h-full bg-cover bg-no-repeat" style="background-image: url({{ asset($src) }}); background-position: {{ $bg_position ?? 'center' }}">
- <div class="bg-image-sizer" style="padding-bottom: {{ $ratio }}"></div>
+ <div class="bg-image h-full bg-cover" style="background-image: url({{ asset($src) }}); background-position: {{ $bgPosition ?? 'center' }}">
+
+ {{-- Proportional padding only comes into effect when columns stack (small screens) --}}
+ {{-- This makes the image more flexible when in columns... --}}
+ <div class="bg-image-sizer hidden sm:block" style="padding-bottom: {{ $ratio }}"></div>
+
</div>
@endif
--- /dev/null
+{{-- Introduction block with image and overlapping title text --}}
+@php
+ $title = $title ?? '';
+ $image = $image ?? false;
+ $class = $class ?? '';
+ $padding = $padding ?? null; // Pass null so it doesn't override default padding
+@endphp
+
+<full-width :padding="$padding" :class="$class">
+ <content>
+ <columns>
+ {{-- Image sticks --}}
+ <column class="md:-ml-2v sm:-mr-2v">
+ @if ($image)
+ <img src="{{ $image }}" alt="{{ $title }}">
+ @endif
+ </column>
+
+ <column>
+ <text-block class="pt-2v" title-class="h1 overlap-left" :title="$title">
+ {{ $slot }}
+ </text-block>
+ </column>
+ </columns>
+ </content>
+</full-width>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
- <link href="https://fonts.googleapis.com/css?family=Barlow:500,600|Muli&display=swap" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/css?family=Barlow:500,600|Muli:400,700&display=swap" rel="stylesheet">
</head>
<body class="font-body text-grey-dark">
@include('cubist::body.begin')
--- /dev/null
+@extends('layouts/app')
+
+@section('content')
+
+ <div class="contact-page">
+
+ <intro-block padding="pb-2v" :title="$page->intro->title ?? ''" :image="$model->getImageURL($page->intro->image)">
+ <p>{!! nl2br($page->intro->text) !!}</p>
+ <p><a href="#">{{ $page->intro->button->label }}</a></p>
+ </intro-block>
+
+ <full-width padding="pb-4v">
+ <content>
+ <columns>
+ <column>
+ <text-block>
+
+ <h2 class="h2">{{ __('Coordonnées') }}</h2>
+ @include('partials.contact-details')
+
+ <h2 class="h2 mt-10">{{ __('Suivez-nous') }}</h2>
+
+ {{-- Social Networks --}}
+ {{-- Todo: consider refactoring social data structure so image, label and URL can be set from admin --}}
+ <a class="flex items-center mb-4 font-bold text-navy hover:text-blue" href="{{ $global->social->twitter }}" target="_blank" rel="noopener">
+ @svg('icon-twitter', 'mr-3')
+ {{ __('Twitter') }}
+ </a>
+
+ <a class="flex items-center mb-4 font-bold text-navy hover:text-blue" href="{{ $global->social->linkedin }}" target="_blank" rel="noopener">
+ @svg('icon-linkedin', 'mr-3')
+ {{ __('LinkedIn') }}
+ </a>
+
+ </text-block>
+
+ </column>
+ <column class="bg-grey-200 p-10 text-center">
+ (contact form)
+ </column>
+ </columns>
+ </content>
+ </full-width>
+
+ </div>
+@endsection
<link-button href="#test123">Découvrir</link-button>
</p>
- <div class="pb-2v"></div>
</text-block>
</column>
- <column class="overlap-bottom">
+ <column class="overlap-bottom md:-mr-2v sm:-ml-2v sm:mb-0">
<flexible-image src="storage/uploads/images/home-car.jpg" />
</column>
</full-width>
{{-- Intro text --}}
- <full-width padding="pt-5v pb-4v">
- <content>
- <columns>
- <column>
- <img src="{{ asset('storage/uploads/images/home-wing.jpg') }}" alt="">
- </column>
-
- <column>
- <text-block class="pt-2v" title_class="h1 overlap-left" :title="$page->intro->title">
- {{-- Todo: make a better function for converting plain text into paragraphs and breaks --}}
- <p>{!! nl2br($page->intro->text) !!}</p>
+ <intro-block padding="pt-5v pb-4v" :title="$page->intro->title" :image="asset('storage/uploads/images/home-wing.jpg')">
+ {{-- Todo: make a better function for converting plain text into paragraphs and breaks --}}
+ <p>{!! nl2br($page->intro->text) !!}</p>
- {{-- Todo: make a component for handling CMS links when passing an object like $page->intro->button --}}
- <p><a href="#">{{ $page->intro->button->label }}</a></p>
- </text-block>
-
- </column>
- </columns>
- </content>
- </full-width>
+ {{-- Todo: make a component for handling CMS links when passing an object like $page->intro->button --}}
+ <p><a href="#">{{ $page->intro->button->label }}</a></p>
+ </intro-block>
{{-- Our products --}}
</full-width>
{{-- Services & Support --}}
- <full-width class="bg-grey-100">
- <content>
- <columns>
- <column>
- <img src="{{ asset('storage/uploads/images/home-services.jpg') }}" alt="">
- </column>
-
- <column>
- <text-block class="pt-2v" title-class="h1 overlap-left" title="Services & Support">
- <p>PM instrumentation distribue depuis 1986 des Capteurs et Systèmes de haute technicité. Issue de la société Schaevitz, PM Instrumentation a su développer une gamme de capteurs et systèmes d’excellente qualité provenant principalement des Etats-Unis.</p>
+ <intro-block class="bg-grey-100" :title="__('Services & Support')" :image="asset('storage/uploads/images/home-services.jpg')">
+ <p>PM instrumentation distribue depuis 1986 des Capteurs et Systèmes de haute technicité. Issue de la société Schaevitz, PM Instrumentation a su développer une gamme de capteurs et systèmes d’excellente qualité provenant principalement des Etats-Unis.</p>
- <p>Principalement dédiés aux mesures physiques, nous saurons vous conseiller dans le choix de produits adaptés à votre environnement.</p>
+ <p>Principalement dédiés aux mesures physiques, nous saurons vous conseiller dans le choix de produits adaptés à votre environnement.</p>
- <p><a href="#">En savoir plus</a></p>
- </text-block>
- </column>
- </columns>
- </content>
- </full-width>
+ <p><a href="#">En savoir plus</a></p>
+ </intro-block>
{{-- News --}}
<full-width>
{{-- Product details --}}
<div class="flex mb-2v sm:block">
@if($product->hasProductImage())
- {{-- Product images --}}
- <div class="product-detail-images-wrapper flex-grow" style="max-width: 348px">
- <div
- class="product-detail-images-main border-gray-100 border-4 pb-100p w-full bg-center bg-contain bg-no-repeat mb-3"
- style="background-image: url({{ $product->getMediaInField($product->images)->first()->getUrl() }});">
- </div>
+ {{-- Product images --}}
+ <div class="product-detail-images-wrapper flex-grow" style="max-width: 348px">
+ <div
+ class="product-detail-images-main border-gray-100 border-4 pb-100p w-full bg-center bg-cover mb-3"
+ style="background-image: url({{ $product->getMediaInField($product->images)->first()->getUrl() }});">
+ </div>
- <grid cols="3" gap="sm">
- @foreach ($product->getMediaInField($product->images) as $image)
- <div
- class="product-detail-images-main border-gray-100 border-4 pb-100p w-full bg-center bg-contain bg-no-repeat"
- style="background-image: url({{ $image->getUrl() }});">
- </div>
- @endforeach
- </grid>
- </div>
+ <grid cols="3" gap="sm">
+ @foreach ($product->getMediaInField($product->images) as $image)
+ <div
+ class="product-detail-images-main border-gray-100 border-4 pb-100p w-full bg-center bg-cover"
+ style="background-image: url({{ $image->getUrl() }});">
+ </div>
+ @endforeach
+ </grid>
+ </div>
@endif
{{-- Product text --}}
{!! Markdown::parse($product->highlights) !!}
@if(count($product->getMediaInField($product->technical_sheet)))
- <p class="mt-4"><a href="{{$product->getMediaInField($product->technical_sheet)->first()->getUrl()}}">Télécharger
- la fiche produit</a></p>
+ <p class="mt-4">
+ <a href="{{$product->getMediaInField($product->technical_sheet)->first()->getUrl()}}">
+ {{ __('Télécharger la fiche produit') }}
+ </a>
+ </p>
@endif
<link-button href="#" class="align-middle">Ajouter à ma sélection</link-button>
@section('content')
- <full-width padding="pb-4v">
- <content>
- <columns>
- <column>
- <img src="{{ asset('storage/uploads/images/home-wing.jpg') }}" alt="">
- </column>
-
- <column>
- <text-block class="pt-2v" title_class="h1 overlap-left capitalize" :title="$page->intro->title ?? ''">
-
- <p>{!! nl2br($page->intro->text) !!}</p>
-
- <p><a href="#">{{ $page->intro->button->label }}</a></p>
- </text-block>
-
- </column>
- </columns>
- </content>
-
- </full-width>
+ <intro-block padding="pb-4v" :title="$page->intro->title ?? ''" :image="asset('storage/uploads/images/home-wing.jpg')">
+ <p>{!! nl2br($page->intro->text) !!}</p>
+ <p><a href="#">{{ $page->intro->button->label }}</a></p>
+ </intro-block>
@endsection
--- /dev/null
+<map-link class="contact-details-block" :address="$global->address">
+ @svg('icon-address', 'contact-details-icon')
+ <div class="contact-details-text">
+ <div class="contact-details-title">{{ __('Adresse') }}</div>
+ {!! nl2br($global->address) !!}
+ </div>
+</map-link>
+
+<a class="contact-details-block" href="mailto:{{ $global->email }}">
+ @svg('icon-email', 'contact-details-icon')
+ <div class="contact-details-text">
+ <div class="contact-details-title">{{ __('Email') }}</div>
+ {{ $global->email }}
+ </div>
+</a>
+
+<phone-link class="contact-details-block" :number="$global->phone" country-code="33">
+ @svg('icon-phone', 'contact-details-icon')
+ <div class="contact-details-text">
+ <div class="contact-details-title">{{ __('Téléphone') }}</div>
+ {{ $global->phone }}
+ </div>
+</phone-link>
-<div class="contact-shortcut flex flex-col xs:hidden">
+<div class="contact-shortcut flex flex-col z-30 xs:hidden">
- <phone-link :number="$global->phone" class="contact-shortcut-tab mb-px inline-flex self-start bg-blue p-3 inline-block">
+ <phone-link :number="$global->phone" class="contact-shortcut-tab mb-px inline-flex self-start bg-blue p-3">
<img class="contact-shortcut-icon" src="{{ asset('images/icon-phone.svg') }}" alt="{{ __('Téléphone') }}">
{{ $global->phone }}
</phone-link>
<div class="contact-shortcut-tab">
- <a href="mailto:{{ $global->email }}" class="bg-blue p-3 bg-blue flex">
- <img class="contact-shortcut-icon" src="{{ asset('images/icon-email.svg') }}" alt="{{ __('E-mail') }}">
- {{ $global->email }}
+ <a href="/contact" class="bg-blue p-3 bg-blue flex items-center pr-10">
+ <img class="contact-shortcut-icon" src="{{ asset('images/icon-email.svg') }}" alt="{{ __('Contact') }}">
+ {!! __('Formulaire de contact</a>') !!}
</a>
-
+ {{--
<div class="contact-shortcut-detail bg-blue">
{!! sprintf(__('Utilisez notre <a href="%s">formulaire de contact</a>'), '/contact') !!}
</div>
+ --}}
</div>
</div>
<p>Issue de la société Schaevitz, PM Instrumentation a su développer une gamme de capteurs et systèmes d’excellente qualité provenant principalement des Etats-Unis.</p>
</div>
<div class="footer-social flex">
- <a class="text-white hover:text-blue mr-6" href="https://www.twitter.com/" target="_blank" rel="noopener">
+ <a class="text-white hover:text-blue mr-6" href="{{ $global->social->twitter }}" target="_blank" rel="noopener">
@svg('icon-twitter')
</a>
- <a class="text-white hover:text-blue" href="https://www.linkedin.com/" target="_blank" rel="noopener">
+ <a class="text-white hover:text-blue" href="{{ $global->social->linkedin }}" target="_blank" rel="noopener">
@svg('icon-linkedin')
</a>
</div>
<div class="footer-col">
<h3 class="footer-col-heading">Nous contacter</h3>
-
- <map-link class="footer-contact-block" :address="$global->address">
- @svg('icon-address', 'footer-contact-icon')
- <div class="footer-contact-text">
- <div class="footer-contact-title">{{ __('Adresse') }}</div>
- {!! nl2br($global->address) !!}
- </div>
- </map-link>
-
- <a class="footer-contact-block" href="mailto:{{ $global->email }}">
- @svg('icon-email', 'footer-contact-icon')
- <div class="footer-contact-text">
- <div class="footer-contact-title">{{ __('Email') }}</div>
- {{ $global->email }}
- </div>
- </a>
-
- <phone-link class="footer-contact-block" :number="$global->phone" country-code="33">
- @svg('icon-phone', 'footer-contact-icon')
- <div class="footer-contact-text">
- <div class="footer-contact-title">{{ __('Téléphone') }}</div>
- {{ $global->phone }}
- </div>
- </phone-link>
-
+ @include('partials.contact-details')
</div>
<div class="footer-col">
});
mix.js('resources/js/app.js', 'public/js')
- .js('resources/js/product-details.js','public/js')
.stylus('resources/styles/app.styl', 'public/css', {
use: [
require('rupture')()