Skip to content

Instantly share code, notes, and snippets.

@timosz
Last active September 24, 2025 15:14
Show Gist options
  • Select an option

  • Save timosz/575c93f12606261a8c94bdabffff608c to your computer and use it in GitHub Desktop.

Select an option

Save timosz/575c93f12606261a8c94bdabffff608c to your computer and use it in GitHub Desktop.
Laravel Blade Components - Production-Quality Structure from Multi-Tenant SaaS Platform. Demonstrates component composition, data flow, conditional rendering, and internationalization in a real invoicing application.
@props([
'customer' => null,
'invoice' => null,
'isVies' => false,
'isUsCustomer' => false,
'company_region' => null,
'invoice_qrurl' => null,
])
<div class="w-full">
{{-- Customer company name --}}
<div class="w-full flex {{ empty($invoice_qrurl) ? 'pt-8' : '-mt-3' }}">
<div class="flex items-start text-xs">
<span class="font-ceral text-rab-gray-title w-20">
{{ $isVies ? 'Company Name:' : 'Επωνυμία:' }}
</span>
<span class="font-ceram">{{ $customer->company_name }}</span>
</div>
</div>
{{-- Main customer details grid --}}
<div class="w-full flex pt-2">
{{-- Left column: Address details --}}
<div class="w-1/2 flex flex-col border-t border-rab-gray-line text-xs pt-2 pr-6">
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-20">
{{ $isVies ? 'Address:' : 'Διεύθυνση:' }}
</span>
<span class="font-ceram">{{ $customer->address }}</span>
</div>
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-20">
{{ $isVies ? 'Postal Code:' : 'Τ.Κ.:' }}
</span>
<span class="font-ceram">{{ $customer->postal_code }}</span>
</div>
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-20">
{{ $isVies ? 'City:' : 'Πόλη:' }}
</span>
<span class="font-ceram">{{ $customer->city }}</span>
</div>
{{-- Country field for international invoices only --}}
@if ($isVies)
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-20">Country:</span>
<span class="font-ceram">
{{ $isVies ? $customer->getEnglishCountryName() : $customer->country }}
({{ $customer->country_code }})
</span>
</div>
@endif
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-20">
{{ $isVies ? 'Profession:' : 'Επάγγελμα:' }}
</span>
<span class="font-ceram">{{ $customer->profession }}</span>
</div>
</div>
{{-- Visual separator --}}
<div class="border-r border-rab-gray-line mt-3"></div>
{{-- Middle column: Tax information --}}
<div class="w-1/4 flex flex-col border-t border-rab-gray-line text-xs pt-2 pl-6 -ml-1">
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-7">
{{ $isVies ? ( $isUsCustomer ? 'US-EIN:' : 'VAT:') : 'ΑΦΜ:' }}
</span>
<span class="font-ceram ml-1">
{{ $isVies ? ( $isUsCustomer ? '' : $customer->country_code) . $customer->vat_number : $customer->vat_number }}
</span>
</div>
{{-- Greek tax office field for domestic invoices --}}
@if(!$isVies)
<div class="flex items-start pb-1">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-7">ΔΟΥ:</span>
<span class="font-ceram ml-1">{{ $customer->doy }}</span>
</div>
@endif
</div>
{{-- Right column: Invoice metadata --}}
<div class="w-1/4 flex flex-col items-end border-t border-rab-gray-line text-xs ml-20 pt-4">
<div class="flex items-center pb-1">
<span class="font-ceral text-rab-gray-title w-7">Νο:</span>
<span class="font-ceram">{{ $invoice->number }}</span>
</div>
<div class="flex flex-col font-cerar font-semibold text-right">
<span class="font-ceram">{{ $company_region }}</span>
<span class="font-ceram mt-1">
{{ Carbon\Carbon::parse($invoice->date)->format('d/m/Y') }}
</span>
</div>
</div>
</div>
{{-- Optional remarks section --}}
@if($invoice->remarks)
<div class="w-full flex">
<div class="w-2/3 mt-2 text-xs border-t border-rab-gray-line flex items-start pb-1 pt-2">
<span class="flex-shrink-0 font-ceral text-rab-gray-title w-24">Παρατηρήσεις:</span>
<span class="font-cerar font-semibold">{{ $invoice->remarks }}</span>
</div>
</div>
@endif
</div>
@props([
'companyLogoUrl' => null,
'companyName' => null,
'companyNameLine2' => null,
'companyProfession' => null,
'isVies' => false,
'qrCode' => null,
'invoiceQrurl' => null,
])
<div class="w-full">
<div class="w-full flex justify-between">
{{-- Company branding section --}}
<x-pdf.header-company-details
:companyLogoUrl="$companyLogoUrl"
:companyName="$companyName"
:companyNameLine2="$companyNameLine2"
:companyProfession="$companyProfession"
/>
{{-- Invoice title and QR code section --}}
<div class="flex flex-col items-end">
<div class="flex flex-col">
{{-- Multi-language invoice title --}}
<div class="font-ceram text-4xl tracking-widest">
<p class="text-right">{{ $isVies ? 'INVOICE' : 'ΤΙΜΟΛΟΓΙΟ' }}</p>
</div>
{{-- Invoice type subtitle --}}
<div class="font-ceram tracking-widest {{ $isVies ? 'text-xs' : 'text-base' }}">
<p class="text-right {{ $isVies ? '' : 'mr-1' }}">
{{ $isVies ? 'FOR SERVICES PROVIDED' : 'ΓΙΑ ΠΑΡΟΧΗ ΥΠΗΡΕΣΙΩΝ' }}
</p>
</div>
{{-- Conditional QR code for digital verification --}}
@if($qrCode)
<div class="mt-2 mr-1 flex justify-end">
<img src="{{ $qrCode }}"
alt="QR Code"
style="width: 100px; height: 100px; object-fit: contain;">
</div>
@endif
</div>
</div>
</div>
</div>
@extends('layouts.pdf')
@section('content')
<!-- Top section with absolute positioning for PDF layout -->
<div class="absolute top-0 w-full">
<!-- Reusable header component with company branding -->
<x-pdf.service-invoice-header
:company-logo-url="$company_logo_url"
:company-name="$company_name"
:company-name-line-2="$company_name_line_2"
:company-profession="$company_profession"
:is-vies="$invoice->is_vies"
:qr-code="$qr_code ?? null"
/>
<!-- Customer information component -->
<x-pdf.invoice-customer-details
:customer="$customer"
:invoice="$invoice"
:company_region="$company_region"
:is-vies="$invoice->is_vies"
:is-us-customer="$customer->country_code == 'US'"
/>
<!-- Invoice line items component -->
<x-pdf.invoice-items :items="$items" :is-vies="$invoice->is_vies" />
</div>
<!-- Bottom section with payment and totals -->
<div class="absolute bottom-0 w-full">
<div class="w-full flex">
<!-- Payment options component -->
<x-pdf.invoice-payment-options :invoice="$invoice" :is-vies="$invoice->is_vies" />
<!-- Invoice totals component -->
<x-pdf.invoice-totals :invoice="$invoice" :is-vies="$invoice->is_vies" :totals="$totals" />
</div>
<!-- Localized thank you message -->
<div class="w-full my-6 flex justify-center">
<span class="font-ceram text-lg text-rab-gray-thankyou tracking-wide">
{{ $invoice->is_vies ? 'Thank you for your business!' : 'Ευχαριστούμε για τη συνεργασία!' }}
</span>
</div>
<!-- Divider -->
<div class="w-full h-1 border-t border-rab-gray-line"></div>
<!-- Company footer details -->
<x-pdf.invoice-company-details
:company_name="$company_name"
:company_name_line_2="$company_name_line_2"
:company_profession="$company_profession"
:company_vat_number="$company_vat_number"
:company_address="$company_address"
:company_postal_code="$company_postal_code"
:company_region="$company_region"
:company_city="$company_city"
:company_phone="$company_phone"
:company_mobile_phone="$company_mobile_phone"
:company_website_url="$company_website_url"
:company_bank_details="$company_bank_details"
:is-vies="$invoice->is_vies"
/>
</div>
@endsection

Comments are disabled for this gist.