# Refactor the layout component
Now that we have our components, it's time to refactor the layout
# Footer component
- Let's refactor the footer component and add some extra information, but only for local development:
- Show the current breakpoint from Tailwind
- Add some quick links for PhpMyAdmin, MailHog (a local mailserver for development) and links to the TALL stack websites
- Create a new folder resources/views/components/layout/footer
- Move the file resources/views/components/layout/footer.blade.php to the folder footer and rename the file to index.blade.php
- Create a new icon component inside the component's folder: resources/views/components/layout/footer/icon.blade.php
WARNING
- If the footer is not rendered correctly, you have to clear the cached files in the storage/framework/views/ folder
- Execute the following command in the terminal:
php artisan view:clear
- Reload the page
- Lines 3 and 45: show the content between this directive only if the constant
APP_ENV
, inside the .env file, is set tolocal
(More details about the .env file and the configuration files can be found in a separate chapter) - Line 7 - 14: show the current breakpoint from Tailwind (opens new window)
- Line 20: the icons disappear when you click outside the div that contains them
- Line 22 - 42: the quick links are added to the footer
<footer class="container mx-auto p-4 text-sm border-t flex justify-between items-center">
<div>The Vinyl Shop - © {{ date('Y') }}</div>
@env('local')
<div class="p-2"
x-data="{showIcons: false}"
@click="showIcons = true">
<div class="text-gray-400 text-xs text-center cursor-pointer ">
<span class="sm:hidden">< 640</span>
<span class="hidden sm:block md:hidden">SM | 640 - 768</span>
<span class="hidden md:block lg:hidden">MD | 768 - 1024</span>
<span class="hidden lg:block xl:hidden">LG | 1024 - 1280</span>
<span class="hidden xl:block 2xl:hidden">XL | 1280 - 1536</span>
<span class="hidden 2xl:block">2XL | > 1536</span>
</div>
<div class="fixed left-0 right-0 bottom-12 p-2 mx-2 sm:mx-8
rounded-md border shadow-lg bg-amber-200/25 backdrop-blur-sm
flex justify-center space-x-4"
x-show="showIcons"
x-transition.duration.300ms
@click.outside="showIcons = false">
<x-layout.footer.icon target="_myadmin"
href="http://phpmyadmin.test"
icon="si-phpmyadmin"/>
<x-layout.footer.icon target="_mail"
href="http://localhost:8025"
icon="si-maildotru"/>
<x-layout.footer.icon target="_icons"
href="https://blade-ui-kit.com/blade-icons"
icon="fas-icons"/>
<x-layout.footer.icon target="_tall"
href="https://tailwindcss.com/docs"
icon="si-tailwindcss"/>
<x-layout.footer.icon target="_tall"
href="https://alpinejs.dev/"
icon="si-alpinedotjs"/>
<x-layout.footer.icon target="_tall"
href="https://laravel.com/docs/9.x/"
icon="si-laravel"/>
<x-layout.footer.icon target="_tall"
href="https://laravel-livewire.com/docs/2.x/"
icon="si-livewire"/>
</div>
</div>
@endenv
<div>Build with Laravel {{ app()->version() }}</div>
</footer>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
- This component has only one
icon
property href
andtarget
are default attributes for an anchor tag and by adding them to the attributes array, they can be overridden at index.blade.php
@props([
'icon' => 'heroicon-s-question-mark-circle',
])
<a {{ $attributes->merge([
'href' => '#!',
'target' => '_self',
'class' => "text-cyan-600 hover:text-gray-500 hover:scale-150 transition duration-150"
]) }}>
<x-icon class="w-4 h-4" name="{{ $icon }}"/>
</a>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# x-cloak
- Every time a page is loaded, the debug icons are visible for a split second
- Alpine's
x-cloak
(opens new window) directive can be used to hide the icons until the page is fully loaded - For
x-cloak
to work however, we must add extra styling to ourresources/css/app.css
file
<footer class="container mx-auto p-4 text-sm border-t flex justify-between items-center">
<div>The Vinyl Shop - © {{ date('Y') }}</div>
@env('local')
<div class="p-2bg-gray-200 rounded-md"
x-data="{showIcons: false}"
@click="showIcons = true">
<div class="text-gray-400 text-xs text-center cursor-pointer ">...</div>
<div class="fixed left-0 right-0 bottom-12 p-2 mx-2 sm:mx-8
rounded-md border shadow-lg bg-amber-200/25 backdrop-blur-sm
flex justify-center space-x-4"
x-show="showIcons"
x-cloak
x-transition.duration.300ms
@click.outside="showIcons = false">
...
</div>
</div>
@endenv
<div>Build with Laravel {{ app()->version() }}</div>
</footer>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@layer base {
h2 {
@apply text-2xl my-2;
}
h3 {
@apply text-xl italic my-2;
}
[x-cloak] {
display: none !important;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Navbar component
- Let's refactor the navbar component and use some off the Jetstream components and our newly created logo component
- Open resources/views/components/layout/nav.blade.php and replace it with the following code:
- The left side of the navbar, starts with our logo, followed by some Jetstream
<x-jet-nav-link />
component- the
href
attribute is set to theroute
attribute of thenav-link
component - the active route (
request()->routeIs('xxxx.*')
(opens new window)) determines if the:active
property is set totrue
orfalse
true
the link to the current route is underlined
false
the link to the current route is not underlined
- the
- The right side of the navbar, ends with a
<x-jet-dropdown />
component- the
$trigger
slot contains an avatar image from the UI Avatars API (opens new window)
when clicking on the avatar, the dropdown menu will be displayed - the default slot contains all the links, build with the Jetstream
<x-jet-dropdown-link />
component
- the
<nav class="container mx-auto p-4 flex justify-between">
{{-- left navigation--}}
<div class="flex items-center space-x-2">
{{-- Logo --}}
<a href="{{ route('home') }}">
<x-tmk.logo class="w-8 h-8"/>
</a>
<a class="hidden sm:block font-medium text-lg" href="{{ route('home') }}">
The Vinyl Shop
</a>
<x-jet-nav-link href="{{ route('home') }}" :active="request()->routeIs('shop')">
Shop
</x-jet-nav-link>
<x-jet-nav-link href="{{ route('contact') }}" :active="request()->routeIs('contact')">
Contact
</x-jet-nav-link>
</div>
{{-- right navigation --}}
<div class="relative flex items-center space-x-2">
<x-jet-nav-link href="{{ route('login') }}" :active="request()->routeIs('login')">
Login
</x-jet-nav-link>
<x-jet-nav-link href="{{ route('register') }}" :active="request()->routeIs('register')">
Register
</x-jet-nav-link>
<x-jet-nav-link href="{{ route('home') }}" :active="request()->routeIs('basket')">
<x-fas-shopping-basket class="w-4 h-4"/>
</x-jet-nav-link>
{{-- dropdown navigation--}}
<x-jet-dropdown align="right" width="48">
{{-- avatar --}}
<x-slot name="trigger">
<img class="rounded-full h-8 w-8 cursor-pointer"
src="https://ui-avatars.com/api/?name=Vinyl+Shop"
alt="Vinyl Shop">
</x-slot>
<x-slot name="content">
{{-- all users --}}
<div class="block px-4 py-2 text-xs text-gray-400">My Name</div>
<x-jet-dropdown-link href="{{ route('home') }}">Dashboard</x-jet-dropdown-link>
<x-jet-dropdown-link href="{{ route('home') }}">Update Profile</x-jet-dropdown-link>
<div class="border-t border-gray-100"></div>
<x-jet-dropdown-link href="{{ route('home') }}">Logout</x-jet-dropdown-link>
<div class="border-t border-gray-100"></div>
{{-- admins only --}}
<div class="block px-4 py-2 text-xs text-gray-400">Admin</div>
<x-jet-dropdown-link href="{{ route('home') }}">Genres</x-jet-dropdown-link>
<x-jet-dropdown-link href="{{ route('admin.records.index') }}">Records</x-jet-dropdown-link>
<x-jet-dropdown-link href="{{ route('home') }}">Covers</x-jet-dropdown-link>
<x-jet-dropdown-link href="{{ route('home') }}">Users</x-jet-dropdown-link>
<x-jet-dropdown-link href="{{ route('home') }}">Orders</x-jet-dropdown-link>
</x-slot>
</x-jet-dropdown>
</div>
</nav>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
- Open resources/views/vendor/jetstream/components/nav-link.blade.php to see the full implementation of the component
@props(['active'])
@php
$classes = ($active ?? false)
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition'
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition';
@endphp
<a {{ $attributes->merge(['class' => $classes]) }}>
{{ $slot }}
</a>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- Open resources/views/vendor/jetstream/components/dropdown.blade.php to see the full implementation of the component
@props([
'align' => 'right',
'width' => '48',
'contentClasses' => 'py-1 bg-white',
'dropdownClasses' => ''
])
@php
switch ($align) {
case 'left':
$alignmentClasses = 'origin-top-left left-0';
break;
case 'top':
$alignmentClasses = 'origin-top';
break;
case 'none':
case 'false':
$alignmentClasses = '';
break;
case 'right':
default:
$alignmentClasses = 'origin-top-right right-0';
break;
}
switch ($width) {
case '48':
$width = 'w-48';
break;
}
@endphp
<div class="relative" x-data="{ open: false }" @click.away="open = false" @close.stop="open = false">
<div @click="open = ! open">
{{ $trigger }}
</div>
<div x-show="open"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute z-50 mt-2 {{ $width }} rounded-md shadow-lg {{ $alignmentClasses }} {{ $dropdownClasses }}"
style="display: none;"
@click="open = false">
<div class="rounded-md ring-1 ring-black ring-opacity-5 {{ $contentClasses }}">
{{ $content }}
</div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
- Open resources/views/vendor/jetstream/components/dropdown-link.blade.php to see the full implementation of the component
<a {{ $attributes->merge(['class' => 'block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition']) }}>
{{ $slot }}
</a>
1
2
3
4
2
3
4
REMARKS
- Because we don't have all the pages yet, most of the links in our navbar refer to the home page
route('home')
instead of the actual page