yoco updated to use webhook

This commit is contained in:
twotalesanimation
2025-12-29 14:43:24 +02:00
parent 6de01c13c5
commit 00b8ff77b2
123 changed files with 6959 additions and 12669 deletions
@@ -0,0 +1,431 @@
@extends('layouts.app')
@section('title', 'Order #' . $customOrder->order_number . ' - Custom Order Details')
@section('styles')
<style>
/* Page-specific typography overrides */
h1 {
font-family: 'Abril Fatface', cursive;
font-size: 2.5rem;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
h2 {
font-family: 'Abril Fatface', cursive;
font-size: 1.6rem;
color: var(--text-primary);
margin-bottom: var(--spacing-md);
}
h3 {
font-family: var(--font-sans);
font-size: 1.1rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
.page-intro {
margin-bottom: var(--spacing-lg);
}
.page-intro p {
color: var(--text-secondary);
font-size: 1rem;
}
/* Timeline-specific styles */
.card {
padding: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
}
.card:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.timeline-container {
background: white;
padding: var(--spacing-lg);
border-radius: 20px;
margin-bottom: var(--spacing-lg);
transition: var(--transition);
}
.timeline-container:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.timeline-title {
font-family: var(--font-serif);
font-size: 1.3rem;
color: var(--text-primary);
margin-bottom: var(--spacing-lg);
text-align: center;
}
.timeline {
display: flex;
align-items: center;
gap: 0;
position: relative;
overflow-x: auto;
padding: var(--spacing-md) 0;
}
.timeline::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 2px;
background-color: var(--border-color);
z-index: 1;
transform: translateY(-50%);
}
.timeline-item {
flex: 1;
min-width: 140px;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
z-index: 2;
}
.timeline-circle {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: white;
border: 3px solid var(--border-color);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
font-weight: 900;
font-size: 1.2rem;
color: var(--text-primary);
flex-shrink: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
}
.timeline-item.completed .timeline-circle {
background-color: var(--accent-pink);
border-color: var(--accent-pink);
color: white;
}
.timeline-item.active .timeline-circle {
background-color: var(--accent-light);
border-color: var(--accent-dark);
box-shadow: 0 0 0 4px var(--accent-light);
}
.timeline-label {
text-align: center;
font-size: 0.85rem;
font-weight: 600;
color: var(--text-primary);
line-height: 1.3;
max-width: 120px;
margin-top: 60px;
}
.timeline-item.completed .timeline-label {
color: var(--accent-pink);
}
.timeline-item.active .timeline-label {
color: var(--accent-dark);
font-weight: 700;
}
@media (max-width: 768px) {
.content-grid {
grid-template-columns: 1fr;
}
h1 {
font-size: 1.8rem;
}
.image-gallery {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
}
</style>
@endsection
@section('content')
<div class="container">
<div class="page-intro">
<h1>Custom Order Details</h1>
<p>Order #{{ $customOrder->order_number }}</p>
</div>
@if (session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@if (session('info'))
<div class="alert alert-info">
{{ session('info') }}
</div>
@endif
<!-- Timeline -->
<div class="timeline-container">
<h2 class="timeline-title">Order Progress</h2>
<div class="timeline">
@php
$timelineSteps = [
['status' => 'submitted', 'label' => 'Order\nSubmitted', 'completed' => $customOrder->status !== null],
['status' => 'deposit_paid', 'label' => 'Deposit\nPaid', 'completed' => $customOrder->deposit_status === 'paid'],
['status' => 'proof_sent', 'label' => 'Proofs\nSent', 'completed' => $customOrder->proofs()->exists()],
['status' => 'proof_approved', 'label' => 'Proofs\nApproved', 'completed' => $customOrder->proofs()->where('status', 'approved')->exists()],
['status' => 'processing', 'label' => 'Processing', 'completed' => $customOrder->status === 'processing'],
['status' => 'shipped', 'label' => 'Order\nShipped', 'completed' => $customOrder->status === 'completed'],
];
// Determine current step
$currentStep = 0;
if ($customOrder->status === 'completed') $currentStep = 5;
elseif ($customOrder->status === 'processing') $currentStep = 4;
elseif ($customOrder->proofs()->where('status', 'approved')->exists()) $currentStep = 3;
elseif ($customOrder->proofs()->exists()) $currentStep = 2;
elseif ($customOrder->deposit_status === 'paid') $currentStep = 1;
@endphp
@foreach ($timelineSteps as $index => $step)
<div class="timeline-item @if ($index < $currentStep) completed @elseif ($index === $currentStep) active @endif">
<div class="timeline-circle">
@if ($index < $currentStep)
@else
{{ $index + 1 }}
@endif
</div>
<div class="timeline-label">{{ $step['label'] }}</div>
</div>
@endforeach
</div>
</div>
<div class="content-grid">
<!-- Main Content -->
<div>
<!-- Order Status -->
<div class="card">
<h2>Order Status</h2>
<div class="card-section">
<span class="status-badge {{ $customOrder->status }}">
{{ str_replace('_', ' ', ucfirst($customOrder->status)) }}
</span>
<p style="margin-top: var(--spacing-sm); color: var(--text-secondary); font-size: 0.9rem;">
Submitted on {{ $customOrder->created_at->format('d M Y \a\t H:i') }}
</p>
</div>
</div>
<!-- Design Requirements -->
<div class="card">
<h2>Design Requirements</h2>
<div class="card-section">
<h3>Order Type</h3>
<p style="color: var(--text-secondary); text-transform: capitalize;">{{ $customOrder->type }}</p>
</div>
<div class="card-section">
<h3>Dimensions</h3>
@if ($customOrder->specifications)
<dl style="color: var(--text-secondary);">
@if ($customOrder->specifications->length)
<div class="spec-group">
<dt>Length:</dt>
<dd>{{ $customOrder->specifications->length }}m</dd>
</div>
@endif
@if ($customOrder->specifications->width)
<div class="spec-group">
<dt>Width:</dt>
<dd>{{ $customOrder->specifications->width }}m</dd>
</div>
@endif
@if ($customOrder->specifications->height)
<div class="spec-group">
<dt>Height:</dt>
<dd>{{ $customOrder->specifications->height }}m</dd>
</div>
@endif
<div class="spec-group">
<dt>Quantity:</dt>
<dd>{{ $customOrder->specifications->quantity }}</dd>
</div>
</dl>
@endif
</div>
<div class="card-section">
<h3>Print Material</h3>
@if ($customOrder->specifications->printStock)
<p style="color: var(--text-secondary);">{{ $customOrder->specifications->printStock->name }}</p>
@endif
</div>
<div class="card-section">
<h3>Design Brief</h3>
<p style="color: var(--text-secondary);">{{ $customOrder->customer_brief }}</p>
</div>
@if ($customOrder->specifications->special_instructions)
<div class="card-section">
<h3>Special Instructions</h3>
<p style="color: var(--text-secondary);">{{ $customOrder->specifications->special_instructions }}</p>
</div>
@endif
</div>
<!-- Reference Images -->
@if ($customOrder->files->count() > 0)
<div class="card">
<h2>Reference Images</h2>
<div class="image-gallery">
@foreach ($customOrder->files as $file)
<a href="{{ Storage::url($file->file_path) }}" target="_blank" title="{{ $file->original_filename }}">
<img src="{{ Storage::url($file->file_path) }}" alt="{{ $file->original_filename }}">
</a>
@endforeach
</div>
</div>
@endif
<!-- Design Proofs -->
@if ($customOrder->proofs->count() > 0)
<div class="card">
<h2>Design Proofs</h2>
@foreach ($customOrder->proofs as $proof)
<div class="proof-item {{ $proof->status === 'approved' ? 'approved' : '' }}">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--spacing-sm);">
<h3>Proof {{ $loop->iteration }}</h3>
<span class="status-badge {{ $proof->status }}">
{{ ucfirst($proof->status) }}
</span>
</div>
@if ($proof->file_path)
<a href="{{ Storage::url($proof->file_path) }}" target="_blank" style="color: var(--accent-dark); text-decoration: underline; font-size: 0.9rem;">
View Proof File
</a>
@endif
@if ($proof->feedback)
<div style="margin-top: var(--spacing-sm); padding: var(--spacing-sm); background: white; border-radius: 4px; border-left: 3px solid var(--accent-dark);">
<strong style="color: var(--text-primary); font-size: 0.9rem;">Feedback:</strong>
<p style="color: var(--text-secondary); font-size: 0.85rem; margin: var(--spacing-xs) 0 0 0;">{{ $proof->feedback }}</p>
</div>
@endif
</div>
@endforeach
</div>
@endif
</div>
<!-- Sidebar -->
<div>
<!-- Cost & Payment Summary -->
<div class="card">
<h2>Order Summary</h2>
<!-- Cost Summary -->
<div class="payment-section">
<div class="payment-row">
<span>Design Fee:</span>
<span>R{{ number_format($customOrder->design_fee, 2) }}</span>
</div>
@if ($customOrder->material_cost > 0)
<div class="payment-row">
<span>Material Cost:</span>
<span>R{{ number_format($customOrder->material_cost, 2) }}</span>
</div>
@endif
<div class="payment-row total">
<span>Total:</span>
<span>R{{ number_format($customOrder->total_cost, 2) }}</span>
</div>
</div>
<!-- Payment Status -->
<h3 style="margin-top: var(--spacing-lg); margin-bottom: var(--spacing-md);">Payment Status</h3>
<div style="padding: var(--spacing-sm); background-color: var(--accent-light); border-radius: 20px; margin-bottom: var(--spacing-md);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--spacing-xs);">
<strong>Deposit (20%)</strong>
<span class="status-badge {{ $customOrder->deposit_status }}">{{ ucfirst($customOrder->deposit_status) }}</span>
</div>
<p style="color: var(--text-secondary); margin: 0; font-size: 0.9rem;">R{{ number_format($customOrder->deposit_amount, 2) }}</p>
</div>
<div style="padding: var(--spacing-sm); background-color: var(--accent-light); border-radius: 20px; margin-bottom: var(--spacing-lg);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--spacing-xs);">
<strong>Balance (80%)</strong>
<span class="status-badge {{ $customOrder->balance_status }}">{{ ucfirst($customOrder->balance_status) }}</span>
</div>
<p style="color: var(--text-secondary); margin: 0; font-size: 0.9rem;">R{{ number_format($customOrder->balance_amount, 2) }}</p>
</div>
<!-- Payment Buttons -->
@if ($customOrder->deposit_status !== 'paid')
<form method="POST" action="{{ route('yoco-custom-deposit') }}">
@csrf
<input type="hidden" name="custom_order_id" value="{{ $customOrder->id }}">
<button type="submit" class="btn">Pay Deposit (R{{ number_format($customOrder->deposit_amount, 2) }})</button>
</form>
@elseif ($customOrder->deposit_status === 'paid' && $customOrder->proofs->where('status', 'approved')->count() > 0 && $customOrder->balance_status !== 'paid')
<button class="btn" onclick="alert('Balance payment coming soon')">Pay Balance (R{{ number_format($customOrder->balance_amount, 2) }})</button>
@endif
</div>
<!-- Terms -->
<div class="terms-box">
<h3 style="color: var(--text-primary); margin-top: 0;">Payment Terms</h3>
<ul>
<li>The 20% deposit is non-refundable</li>
<li>Balance of 80% must be paid before printing begins</li>
@if ($customOrder->library_discount_applied)
<li>Design may be added to our library</li>
@else
<li>Bespoke, exclusive design</li>
@endif
</ul>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const paymentForm = document.querySelector('form[action*="payment"]');
if (paymentForm) {
console.log('Payment form found:', paymentForm);
console.log('Form action:', paymentForm.action);
paymentForm.addEventListener('submit', function(e) {
console.log('Payment form submitted!');
console.log('Form data:', new FormData(this));
});
} else {
console.log('Payment form NOT found');
console.log('All forms on page:', document.querySelectorAll('form'));
}
});
</script>
@endsection