affiliations
This commit is contained in:
1 parent
4f3f9c9aad
commit
0b5b3dd3ee
177 files changed
+9660
-8531
No files matched your search
@@ -0,0 +1,121 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Activities</h2>
|
||||
<p class="text-muted mb-0">Manage club activities and classes</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addActivityModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Activity
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(isset($activities) && count($activities) > 0)
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>Activity</th>
|
||||
<th>Duration</th>
|
||||
<th>Instructor</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($activities as $activity)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="rounded bg-primary bg-opacity-10 p-2">
|
||||
<i class="bi bi-activity text-primary"></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="fw-semibold mb-0">{{ $activity->name }}</p>
|
||||
<p class="text-muted small mb-0">{{ Str::limit($activity->description, 50) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $activity->duration ?? 'N/A' }} min</td>
|
||||
<td>{{ $activity->instructor->name ?? 'Not assigned' }}</td>
|
||||
<td>
|
||||
@if($activity->is_active ?? true)
|
||||
<span class="badge bg-success">Active</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">Inactive</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex gap-1">
|
||||
<button class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-activity text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No activities yet</h5>
|
||||
<p class="text-muted mb-3">Add activities and classes for your members</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addActivityModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Activity
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Add Activity Modal -->
|
||||
<div class="modal fade" id="addActivityModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Activity</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.activities.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Activity Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<textarea name="description" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Duration (minutes)</label>
|
||||
<input type="number" name="duration" class="form-control" value="60">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Instructor</label>
|
||||
<select name="instructor_id" class="form-select">
|
||||
<option value="">Select instructor</option>
|
||||
@foreach($instructors ?? [] as $instructor)
|
||||
<option value="{{ $instructor->id }}">{{ $instructor->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 mt-3">Add Activity</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,207 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Analytics</h2>
|
||||
<p class="text-muted mb-0">Track your club's performance</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<select class="form-select" style="width: auto;">
|
||||
<option value="7">Last 7 days</option>
|
||||
<option value="30" selected>Last 30 days</option>
|
||||
<option value="90">Last 90 days</option>
|
||||
<option value="365">Last year</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-primary">
|
||||
<i class="bi bi-download me-2"></i>Export
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Key Metrics -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">New Members</p>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h4 class="fw-bold mb-0">{{ $analytics['new_members'] ?? 0 }}</h4>
|
||||
<span class="badge bg-success-subtle text-success">
|
||||
<i class="bi bi-arrow-up"></i> {{ $analytics['new_members_change'] ?? 0 }}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Retention Rate</p>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h4 class="fw-bold mb-0">{{ $analytics['retention_rate'] ?? 0 }}%</h4>
|
||||
<span class="badge bg-success-subtle text-success">
|
||||
<i class="bi bi-arrow-up"></i> {{ $analytics['retention_change'] ?? 0 }}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Avg. Revenue/Member</p>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h4 class="fw-bold mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($analytics['avg_revenue'] ?? 0, 2) }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Check-ins</p>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h4 class="fw-bold mb-0">{{ $analytics['total_checkins'] ?? 0 }}</h4>
|
||||
<span class="badge bg-info-subtle text-info">
|
||||
<i class="bi bi-arrow-up"></i> {{ $analytics['checkins_change'] ?? 0 }}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<!-- Membership Growth Chart -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Membership Growth</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="membershipChart" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Popular Packages -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Popular Packages</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if(isset($popularPackages) && count($popularPackages) > 0)
|
||||
@foreach($popularPackages as $package)
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div>
|
||||
<p class="fw-semibold mb-0">{{ $package->name }}</p>
|
||||
<p class="text-muted small mb-0">{{ $package->subscriptions_count }} subscriptions</p>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<p class="fw-bold text-primary mb-0">{{ $package->percentage ?? 0 }}%</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress mb-3" style="height: 6px;">
|
||||
<div class="progress-bar bg-primary" style="width: {{ $package->percentage ?? 0 }}%"></div>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
<div class="text-center py-4">
|
||||
<p class="text-muted mb-0">No package data available</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activity Breakdown -->
|
||||
<div class="col-lg-6">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Activity Breakdown</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="activityChart" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Peak Hours -->
|
||||
<div class="col-lg-6">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Peak Hours</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="peakHoursChart" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Membership Growth Chart
|
||||
new Chart(document.getElementById('membershipChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
datasets: [{
|
||||
label: 'Members',
|
||||
data: @json($analytics['monthly_members'] ?? [0,0,0,0,0,0,0,0,0,0,0,0]),
|
||||
borderColor: 'hsl(355, 84%, 44%)',
|
||||
backgroundColor: 'hsla(355, 84%, 44%, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: { legend: { display: false } }
|
||||
}
|
||||
});
|
||||
|
||||
// Activity Chart
|
||||
new Chart(document.getElementById('activityChart'), {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: @json($analytics['activity_labels'] ?? ['No data']),
|
||||
datasets: [{
|
||||
data: @json($analytics['activity_data'] ?? [100]),
|
||||
backgroundColor: ['#CE1126', '#3b82f6', '#22c55e', '#f59e0b', '#8b5cf6']
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
}
|
||||
});
|
||||
|
||||
// Peak Hours Chart
|
||||
new Chart(document.getElementById('peakHoursChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['6am', '8am', '10am', '12pm', '2pm', '4pm', '6pm', '8pm', '10pm'],
|
||||
datasets: [{
|
||||
label: 'Check-ins',
|
||||
data: @json($analytics['hourly_checkins'] ?? [0,0,0,0,0,0,0,0,0]),
|
||||
backgroundColor: 'hsl(355, 84%, 44%)'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: { legend: { display: false } }
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
@@ -0,0 +1,215 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div class="space-y-6">
|
||||
<!-- Header -->
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-2">Dashboard Overview</h2>
|
||||
<p class="text-muted">Welcome to {{ $club->club_name }} management</p>
|
||||
</div>
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div class="row g-3">
|
||||
<!-- Active Members -->
|
||||
<div class="col-6 col-md-4 col-lg">
|
||||
<div class="card h-100 border-0 shadow-sm" style="cursor: pointer;" onclick="window.location='{{ route('admin.club.members', $club->id) }}'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-muted small">Active Members</span>
|
||||
<div class="rounded p-2" style="background-color: hsl(var(--primary) / 0.1);">
|
||||
<i class="bi bi-people text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="fw-bold text-primary mb-1">{{ $stats['members'] ?? 0 }}</h3>
|
||||
<p class="text-muted small mb-0">Members with valid packages</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Activities -->
|
||||
<div class="col-6 col-md-4 col-lg">
|
||||
<div class="card h-100 border-0 shadow-sm" style="cursor: pointer;" onclick="window.location='{{ route('admin.club.activities', $club->id) }}'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-muted small">Activities</span>
|
||||
<div class="rounded p-2" style="background-color: hsl(var(--warning) / 0.1);">
|
||||
<i class="bi bi-activity text-warning"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="fw-bold text-warning mb-1">{{ $stats['activities'] ?? 0 }}</h3>
|
||||
<p class="text-muted small mb-0">Available activities</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Packages -->
|
||||
<div class="col-6 col-md-4 col-lg">
|
||||
<div class="card h-100 border-0 shadow-sm" style="cursor: pointer;" onclick="window.location='{{ route('admin.club.packages', $club->id) }}'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-muted small">Packages</span>
|
||||
<div class="rounded p-2" style="background-color: hsl(var(--success) / 0.1);">
|
||||
<i class="bi bi-box text-success"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="fw-bold text-success mb-1">{{ $stats['packages'] ?? 0 }}</h3>
|
||||
<p class="text-muted small mb-0">Available packages</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trainers -->
|
||||
<div class="col-6 col-md-4 col-lg">
|
||||
<div class="card h-100 border-0 shadow-sm" style="cursor: pointer;" onclick="window.location='{{ route('admin.club.instructors', $club->id) }}'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-muted small">Trainers</span>
|
||||
<div class="rounded p-2" style="background-color: hsl(var(--info) / 0.1);">
|
||||
<i class="bi bi-person-badge text-info"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="fw-bold text-info mb-1">{{ $stats['instructors'] ?? 0 }}</h3>
|
||||
<p class="text-muted small mb-0">Available trainers</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rating -->
|
||||
<div class="col-6 col-md-4 col-lg">
|
||||
<div class="card h-100 border-0 shadow-sm" style="cursor: pointer;" onclick="window.location='{{ route('admin.club.details', $club->id) }}'">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="text-muted small">Member Rating</span>
|
||||
<div class="rounded p-2" style="background-color: hsl(35 90% 55% / 0.1);">
|
||||
<i class="bi bi-star-fill" style="color: hsl(35, 90%, 55%);"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3 class="fw-bold mb-1" style="color: hsl(35, 90%, 55%);">{{ number_format($stats['rating'] ?? 0, 1) }}</h3>
|
||||
<i class="bi bi-star-fill" style="color: hsl(35, 90%, 55%);"></i>
|
||||
</div>
|
||||
<p class="text-muted small mb-0">Average from reviews</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Financial Overview Chart -->
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0 pb-0">
|
||||
<h5 class="fw-bold mb-1">Financial Overview (Last 12 Months)</h5>
|
||||
<p class="text-muted small">Monthly income, expenses, and profit trends</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="financialChart" height="300"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Expiring Subscriptions -->
|
||||
@if(isset($expiringSubscriptions) && count($expiringSubscriptions) > 0)
|
||||
<div class="card border-0 shadow-sm border-start border-warning border-4">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-bold mb-0">
|
||||
<i class="bi bi-exclamation-triangle text-warning me-2"></i>
|
||||
Expiring Subscriptions
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Member</th>
|
||||
<th>Package</th>
|
||||
<th>Expires</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($expiringSubscriptions as $subscription)
|
||||
<tr>
|
||||
<td>{{ $subscription->user->full_name ?? 'N/A' }}</td>
|
||||
<td>{{ $subscription->package->name ?? 'N/A' }}</td>
|
||||
<td>{{ $subscription->end_date ? $subscription->end_date->format('M d, Y') : 'N/A' }}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline-primary">Renew</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const ctx = document.getElementById('financialChart').getContext('2d');
|
||||
|
||||
// Sample data - replace with actual data from controller
|
||||
const monthlyData = @json($monthlyFinancials ?? []);
|
||||
|
||||
const labels = monthlyData.map(d => d.month) || ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
const incomeData = monthlyData.map(d => d.income) || [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
const expensesData = monthlyData.map(d => d.expenses) || [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
const profitData = monthlyData.map(d => d.profit) || [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Income',
|
||||
data: incomeData,
|
||||
borderColor: '#22c55e',
|
||||
backgroundColor: 'rgba(34, 197, 94, 0.1)',
|
||||
borderWidth: 2,
|
||||
tension: 0.3
|
||||
},
|
||||
{
|
||||
label: 'Expenses',
|
||||
data: expensesData,
|
||||
borderColor: '#ef4444',
|
||||
backgroundColor: 'rgba(239, 68, 68, 0.1)',
|
||||
borderWidth: 2,
|
||||
tension: 0.3
|
||||
},
|
||||
{
|
||||
label: 'Profit',
|
||||
data: profitData,
|
||||
borderColor: '#3b82f6',
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.1)',
|
||||
borderWidth: 2,
|
||||
tension: 0.3
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
callback: function(value) {
|
||||
return '{{ $club->currency ?? "BHD" }} ' + value.toLocaleString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
@@ -0,0 +1,127 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div class="space-y-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Club Details</h2>
|
||||
<p class="text-muted mb-0">Manage your club information</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#editClubModal">
|
||||
<i class="bi bi-pencil me-2"></i>Edit Details
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info Card -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Basic Information</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">Club Name</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->club_name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">Slug</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->slug }}</p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label text-muted small">Description</label>
|
||||
<p class="mb-0">{{ $club->description ?? 'No description provided' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">Email</label>
|
||||
<p class="mb-0">{{ $club->email ?? 'Not set' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">Phone</label>
|
||||
<p class="mb-0">
|
||||
@if($club->phone)
|
||||
{{ is_array($club->phone) ? implode(', ', $club->phone) : $club->phone }}
|
||||
@else
|
||||
Not set
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label text-muted small">Address</label>
|
||||
<p class="mb-0">{{ $club->address ?? 'Not set' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logo & Settings Card -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Club Logo</h5>
|
||||
</div>
|
||||
<div class="card-body text-center">
|
||||
@if($club->logo)
|
||||
<img src="{{ asset('storage/' . $club->logo) }}" alt="{{ $club->club_name }}" class="img-fluid rounded mb-3" style="max-height: 150px;">
|
||||
@else
|
||||
<div class="bg-light rounded d-flex align-items-center justify-content-center mb-3" style="height: 150px;">
|
||||
<i class="bi bi-building text-muted" style="font-size: 3rem;"></i>
|
||||
</div>
|
||||
@endif
|
||||
<button class="btn btn-outline-primary btn-sm">
|
||||
<i class="bi bi-upload me-1"></i>Change Logo
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Settings</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted small">Currency</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->currency ?? 'BHD' }}</p>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted small">Timezone</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->timezone ?? 'Asia/Bahrain' }}</p>
|
||||
</div>
|
||||
<div class="mb-0">
|
||||
<label class="form-label text-muted small">Enrollment Fee</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($club->enrollment_fee ?? 0, 2) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location Card -->
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Location</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">GPS Latitude</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->gps_lat ?? 'Not set' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small">GPS Longitude</label>
|
||||
<p class="fw-semibold mb-0">{{ $club->gps_long ?? 'Not set' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@if($club->gps_lat && $club->gps_long)
|
||||
<div class="mt-3">
|
||||
<div id="clubMap" style="height: 300px; border-radius: 0.5rem;"></div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,108 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Facilities</h2>
|
||||
<p class="text-muted mb-0">Manage your club facilities</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addFacilityModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Facility
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(isset($facilities) && count($facilities) > 0)
|
||||
<div class="row g-4">
|
||||
@foreach($facilities as $facility)
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
@if($facility->image)
|
||||
<img src="{{ asset('storage/' . $facility->image) }}" alt="{{ $facility->name }}" class="card-img-top" style="height: 180px; object-fit: cover;">
|
||||
@else
|
||||
<div class="bg-light d-flex align-items-center justify-content-center" style="height: 180px;">
|
||||
<i class="bi bi-geo-alt text-muted" style="font-size: 3rem;"></i>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card-body">
|
||||
<h5 class="fw-semibold mb-2">{{ $facility->name }}</h5>
|
||||
<p class="text-muted small mb-3">{{ Str::limit($facility->description, 100) }}</p>
|
||||
<div class="d-flex gap-2 flex-wrap">
|
||||
<x-takeone-cropper
|
||||
id="facility_{{ $facility->id }}"
|
||||
:width="400"
|
||||
:height="300"
|
||||
shape="square"
|
||||
folder="clubs/{{ $club->id }}/facilities"
|
||||
filename="facility_{{ $facility->id }}"
|
||||
uploadUrl="{{ route('admin.club.facilities.upload-image', [$club->id, $facility->id]) }}"
|
||||
:currentImage="$facility->image ? asset('storage/' . $facility->image) : ''"
|
||||
buttonText="Change Image"
|
||||
buttonClass="btn btn-sm btn-outline-success flex-grow-1"
|
||||
/>
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-geo-alt text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No facilities yet</h5>
|
||||
<p class="text-muted mb-3">Add facilities to showcase what your club offers</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addFacilityModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Facility
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Add Facility Modal -->
|
||||
<div class="modal fade" id="addFacilityModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Facility</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.facilities.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Facility Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<textarea name="description" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label d-block">Image</label>
|
||||
<x-takeone-cropper
|
||||
id="add_facility_image"
|
||||
mode="form"
|
||||
inputName="image"
|
||||
:width="400"
|
||||
:height="300"
|
||||
:previewWidth="200"
|
||||
:previewHeight="150"
|
||||
shape="square"
|
||||
folder="clubs/{{ $club->id }}/facilities"
|
||||
filename="facility_{{ time() }}"
|
||||
buttonText="Select Image"
|
||||
buttonClass="btn btn-outline-success btn-sm"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Add Facility</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,188 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center gap-3 mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Financials</h2>
|
||||
<p class="text-muted mb-0">Track income, expenses, and transactions</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#addExpenseModal">
|
||||
<i class="bi bi-dash-circle me-2"></i>Add Expense
|
||||
</button>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addIncomeModal">
|
||||
<i class="bi bi-plus-circle me-2"></i>Add Income
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary Cards -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Total Income</p>
|
||||
<h4 class="fw-bold text-success mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($summary['total_income'] ?? 0, 2) }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Total Expenses</p>
|
||||
<h4 class="fw-bold text-danger mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($summary['total_expenses'] ?? 0, 2) }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Net Profit</p>
|
||||
<h4 class="fw-bold text-primary mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($summary['net_profit'] ?? 0, 2) }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<p class="text-muted small mb-1">Pending Payments</p>
|
||||
<h4 class="fw-bold text-warning mb-0">{{ $club->currency ?? 'BHD' }} {{ number_format($summary['pending'] ?? 0, 2) }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Transactions Table -->
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||||
<h5 class="fw-semibold mb-0">Recent Transactions</h5>
|
||||
<div class="d-flex gap-2">
|
||||
<select class="form-select form-select-sm" style="width: auto;">
|
||||
<option value="">All Types</option>
|
||||
<option value="income">Income</option>
|
||||
<option value="expense">Expense</option>
|
||||
<option value="refund">Refund</option>
|
||||
</select>
|
||||
<input type="month" class="form-control form-control-sm" style="width: auto;">
|
||||
</div>
|
||||
</div>
|
||||
@if(isset($transactions) && count($transactions) > 0)
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Description</th>
|
||||
<th>Type</th>
|
||||
<th>Amount</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($transactions as $transaction)
|
||||
<tr>
|
||||
<td>{{ $transaction->transaction_date ? $transaction->transaction_date->format('M d, Y') : 'N/A' }}</td>
|
||||
<td>{{ $transaction->description ?? 'N/A' }}</td>
|
||||
<td>
|
||||
@if($transaction->type === 'income')
|
||||
<span class="badge bg-success">Income</span>
|
||||
@elseif($transaction->type === 'expense')
|
||||
<span class="badge bg-danger">Expense</span>
|
||||
@else
|
||||
<span class="badge bg-warning text-dark">{{ ucfirst($transaction->type) }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="{{ $transaction->type === 'income' ? 'text-success' : 'text-danger' }} fw-semibold">
|
||||
{{ $transaction->type === 'income' ? '+' : '-' }}{{ $club->currency ?? 'BHD' }} {{ number_format($transaction->amount, 2) }}
|
||||
</td>
|
||||
<td>
|
||||
@if($transaction->status === 'paid')
|
||||
<span class="badge bg-success">Paid</span>
|
||||
@elseif($transaction->status === 'pending')
|
||||
<span class="badge bg-warning text-dark">Pending</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">{{ ucfirst($transaction->status) }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-eye"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-currency-dollar text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No transactions yet</h5>
|
||||
<p class="text-muted">Transactions will appear here as they occur</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Income Modal -->
|
||||
<div class="modal fade" id="addIncomeModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Income</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.financials.income', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<input type="text" name="description" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Amount ({{ $club->currency ?? 'BHD' }})</label>
|
||||
<input type="number" name="amount" class="form-control" step="0.01" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Date</label>
|
||||
<input type="date" name="transaction_date" class="form-control" value="{{ date('Y-m-d') }}" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success w-100">Add Income</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Expense Modal -->
|
||||
<div class="modal fade" id="addExpenseModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Expense</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.financials.expense', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<input type="text" name="description" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Amount ({{ $club->currency ?? 'BHD' }})</label>
|
||||
<input type="number" name="amount" class="form-control" step="0.01" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Date</label>
|
||||
<input type="date" name="transaction_date" class="form-control" value="{{ date('Y-m-d') }}" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger w-100">Add Expense</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,76 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Gallery</h2>
|
||||
<p class="text-muted mb-0">Manage your club photos and media</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadImageModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Images
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(isset($images) && count($images) > 0)
|
||||
<div class="row g-3">
|
||||
@foreach($images as $image)
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="position-relative">
|
||||
<img src="{{ asset('storage/' . $image->path) }}" alt="{{ $image->caption ?? 'Gallery image' }}" class="card-img-top" style="height: 200px; object-fit: cover;">
|
||||
<div class="position-absolute top-0 end-0 p-2">
|
||||
<button class="btn btn-sm btn-danger rounded-circle" onclick="deleteImage({{ $image->id }})">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@if($image->caption)
|
||||
<div class="card-body py-2">
|
||||
<p class="small mb-0">{{ $image->caption }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-images text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No images yet</h5>
|
||||
<p class="text-muted mb-3">Upload photos to showcase your club</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadImageModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Images
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Upload Modal -->
|
||||
<div class="modal fade" id="uploadImageModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Upload Images</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.gallery.upload', $club->id) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Images</label>
|
||||
<input type="file" name="images[]" class="form-control" multiple accept="image/*">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Caption (optional)</label>
|
||||
<input type="text" name="caption" class="form-control" placeholder="Enter caption...">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,115 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Instructors</h2>
|
||||
<p class="text-muted mb-0">Manage your club instructors and trainers</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addInstructorModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Instructor
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(isset($instructors) && count($instructors) > 0)
|
||||
<div class="row g-4">
|
||||
@foreach($instructors as $instructor)
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body text-center">
|
||||
@if($instructor->photo)
|
||||
<img src="{{ asset('storage/' . $instructor->photo) }}" alt="{{ $instructor->name }}" class="rounded-circle mb-3" style="width: 100px; height: 100px; object-fit: cover;">
|
||||
@else
|
||||
<div class="rounded-circle bg-primary d-inline-flex align-items-center justify-content-center mb-3" style="width: 100px; height: 100px;">
|
||||
<span class="text-white fw-bold" style="font-size: 2rem;">{{ strtoupper(substr($instructor->name, 0, 1)) }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<h5 class="fw-semibold mb-1">{{ $instructor->name }}</h5>
|
||||
<p class="text-muted small mb-2">{{ $instructor->specialization ?? 'Trainer' }}</p>
|
||||
@if($instructor->bio)
|
||||
<p class="text-muted small mb-3">{{ Str::limit($instructor->bio, 80) }}</p>
|
||||
@endif
|
||||
<div class="d-flex gap-2 justify-content-center flex-wrap">
|
||||
<x-takeone-cropper
|
||||
id="instructor_{{ $instructor->id }}"
|
||||
:width="200"
|
||||
:height="200"
|
||||
shape="circle"
|
||||
folder="clubs/{{ $club->id }}/instructors"
|
||||
filename="instructor_{{ $instructor->id }}"
|
||||
uploadUrl="{{ route('admin.club.instructors.upload-photo', [$club->id, $instructor->id]) }}"
|
||||
:currentImage="$instructor->photo ? asset('storage/' . $instructor->photo) : ''"
|
||||
buttonText="Change Photo"
|
||||
buttonClass="btn btn-sm btn-outline-success"
|
||||
/>
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-people text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No instructors yet</h5>
|
||||
<p class="text-muted mb-3">Add instructors to your club</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addInstructorModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Instructor
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Add Instructor Modal -->
|
||||
<div class="modal fade" id="addInstructorModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Instructor</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.instructors.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Specialization</label>
|
||||
<input type="text" name="specialization" class="form-control" placeholder="e.g., Yoga, CrossFit, Swimming">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Bio</label>
|
||||
<textarea name="bio" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="mb-3 text-center">
|
||||
<label class="form-label d-block">Photo</label>
|
||||
<x-takeone-cropper
|
||||
id="add_instructor_photo"
|
||||
mode="form"
|
||||
inputName="photo"
|
||||
:width="200"
|
||||
:height="200"
|
||||
:previewWidth="120"
|
||||
:previewHeight="120"
|
||||
shape="circle"
|
||||
folder="clubs/{{ $club->id }}/instructors"
|
||||
filename="instructor_{{ time() }}"
|
||||
buttonText="Select Photo"
|
||||
buttonClass="btn btn-outline-success btn-sm"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Add Instructor</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,187 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center gap-3 mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Members</h2>
|
||||
<p class="text-muted mb-0">Manage club members and subscriptions</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#walkInModal">
|
||||
<i class="bi bi-person-walking me-2"></i>Walk-in
|
||||
</button>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addMemberModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Member
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search & Filter -->
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-white border-end-0">
|
||||
<i class="bi bi-search text-muted"></i>
|
||||
</span>
|
||||
<input type="text" class="form-control border-start-0" placeholder="Search members..." id="searchMembers">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select" id="filterStatus">
|
||||
<option value="">All Status</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="expired">Expired</option>
|
||||
<option value="pending">Pending</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select class="form-select" id="filterPackage">
|
||||
<option value="">All Packages</option>
|
||||
@foreach($packages ?? [] as $package)
|
||||
<option value="{{ $package->id }}">{{ $package->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Members Table -->
|
||||
@if(isset($members) && count($members) > 0)
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>Member</th>
|
||||
<th>Package</th>
|
||||
<th>Start Date</th>
|
||||
<th>End Date</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($members as $member)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
@if($member->user->profile_picture)
|
||||
<img src="{{ asset('storage/' . $member->user->profile_picture) }}" alt="" class="rounded-circle" style="width: 40px; height: 40px; object-fit: cover;">
|
||||
@else
|
||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
|
||||
<span class="text-white fw-bold">{{ strtoupper(substr($member->user->full_name ?? 'M', 0, 1)) }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div>
|
||||
<p class="fw-semibold mb-0">{{ $member->user->full_name ?? 'N/A' }}</p>
|
||||
<p class="text-muted small mb-0">{{ $member->user->email ?? '' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $member->subscription->package->name ?? 'No package' }}</td>
|
||||
<td>{{ $member->subscription->start_date ? $member->subscription->start_date->format('M d, Y') : 'N/A' }}</td>
|
||||
<td>{{ $member->subscription->end_date ? $member->subscription->end_date->format('M d, Y') : 'N/A' }}</td>
|
||||
<td>
|
||||
@if($member->status === 'active')
|
||||
<span class="badge bg-success">Active</span>
|
||||
@elseif($member->status === 'expired')
|
||||
<span class="badge bg-danger">Expired</span>
|
||||
@else
|
||||
<span class="badge bg-warning text-dark">{{ ucfirst($member->status) }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">
|
||||
Actions
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="#"><i class="bi bi-eye me-2"></i>View</a></li>
|
||||
<li><a class="dropdown-item" href="#"><i class="bi bi-pencil me-2"></i>Edit</a></li>
|
||||
<li><a class="dropdown-item" href="#"><i class="bi bi-arrow-repeat me-2"></i>Renew</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item text-danger" href="#"><i class="bi bi-trash me-2"></i>Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if($members instanceof \Illuminate\Pagination\LengthAwarePaginator)
|
||||
<div class="card-footer bg-white border-0">
|
||||
{{ $members->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-people text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No members yet</h5>
|
||||
<p class="text-muted mb-3">Start adding members to your club</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addMemberModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Member
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Add Member Modal -->
|
||||
<div class="modal fade" id="addMemberModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add New Member</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.members.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Full Name</label>
|
||||
<input type="text" name="full_name" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Email</label>
|
||||
<input type="email" name="email" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Mobile</label>
|
||||
<input type="text" name="mobile" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Package</label>
|
||||
<select name="package_id" class="form-select" required>
|
||||
<option value="">Select package</option>
|
||||
@foreach($packages ?? [] as $package)
|
||||
<option value="{{ $package->id }}">{{ $package->name }} - {{ $club->currency ?? 'BHD' }} {{ number_format($package->price, 2) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Start Date</label>
|
||||
<input type="date" name="start_date" class="form-control" value="{{ date('Y-m-d') }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Payment Status</label>
|
||||
<select name="payment_status" class="form-select">
|
||||
<option value="paid">Paid</option>
|
||||
<option value="pending">Pending</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 mt-4">Add Member</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,106 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Messages</h2>
|
||||
<p class="text-muted mb-0">Communicate with your members</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#newMessageModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>New Message
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<!-- Conversations List -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-header bg-white border-0">
|
||||
<input type="text" class="form-control" placeholder="Search conversations...">
|
||||
</div>
|
||||
<div class="card-body p-0" style="max-height: 500px; overflow-y: auto;">
|
||||
@if(isset($conversations) && count($conversations) > 0)
|
||||
@foreach($conversations as $conversation)
|
||||
<div class="d-flex align-items-center gap-3 p-3 border-bottom conversation-item {{ $conversation->unread ? 'bg-light' : '' }}" style="cursor: pointer;">
|
||||
@if($conversation->user->profile_picture)
|
||||
<img src="{{ asset('storage/' . $conversation->user->profile_picture) }}" alt="" class="rounded-circle" style="width: 45px; height: 45px; object-fit: cover;">
|
||||
@else
|
||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center" style="width: 45px; height: 45px;">
|
||||
<span class="text-white fw-bold">{{ strtoupper(substr($conversation->user->full_name ?? 'U', 0, 1)) }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex-grow-1 min-width-0">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<p class="fw-semibold mb-0 text-truncate">{{ $conversation->user->full_name ?? 'Unknown' }}</p>
|
||||
<small class="text-muted">{{ $conversation->last_message_at ? $conversation->last_message_at->diffForHumans(null, true) : '' }}</small>
|
||||
</div>
|
||||
<p class="text-muted small mb-0 text-truncate">{{ $conversation->last_message ?? 'No messages yet' }}</p>
|
||||
</div>
|
||||
@if($conversation->unread_count > 0)
|
||||
<span class="badge bg-primary rounded-pill">{{ $conversation->unread_count }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-chat-dots text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-2 mb-0">No conversations yet</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Area -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body d-flex flex-column" style="min-height: 500px;">
|
||||
<div class="text-center my-auto">
|
||||
<i class="bi bi-chat-square-text text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">Select a conversation</h5>
|
||||
<p class="text-muted">Choose a conversation from the list to start messaging</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New Message Modal -->
|
||||
<div class="modal fade" id="newMessageModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">New Message</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.messages.send', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">To</label>
|
||||
<select name="recipient_id" class="form-select" required>
|
||||
<option value="">Select member...</option>
|
||||
@foreach($members ?? [] as $member)
|
||||
<option value="{{ $member->user_id }}">{{ $member->user->full_name ?? 'Unknown' }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Message</label>
|
||||
<textarea name="message" class="form-control" rows="4" required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Send Message</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.conversation-item:hover {
|
||||
background-color: hsl(var(--muted)) !important;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
@@ -0,0 +1,116 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Packages</h2>
|
||||
<p class="text-muted mb-0">Manage membership packages</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPackageModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Package
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(isset($packages) && count($packages) > 0)
|
||||
<div class="row g-4">
|
||||
@foreach($packages as $package)
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||
<div>
|
||||
<h5 class="fw-semibold mb-1">{{ $package->name }}</h5>
|
||||
<span class="badge bg-primary">{{ $package->duration_days ?? 30 }} days</span>
|
||||
</div>
|
||||
@if($package->is_popular ?? false)
|
||||
<span class="badge bg-warning text-dark">Popular</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<p class="text-muted small mb-3">{{ Str::limit($package->description, 100) }}</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<span class="h4 fw-bold text-primary">{{ $club->currency ?? 'BHD' }} {{ number_format($package->price, 2) }}</span>
|
||||
<span class="text-muted">/ {{ $package->duration_days ?? 30 }} days</span>
|
||||
</div>
|
||||
|
||||
@if($package->features)
|
||||
<ul class="list-unstyled small mb-3">
|
||||
@foreach(json_decode($package->features, true) ?? [] as $feature)
|
||||
<li class="mb-1">
|
||||
<i class="bi bi-check-circle text-success me-2"></i>{{ $feature }}
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-sm btn-outline-primary flex-grow-1">
|
||||
<i class="bi bi-pencil me-1"></i>Edit
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-box text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No packages yet</h5>
|
||||
<p class="text-muted mb-3">Create membership packages for your club</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPackageModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Package
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Add Package Modal -->
|
||||
<div class="modal fade" id="addPackageModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Package</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.packages.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Package Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Description</label>
|
||||
<textarea name="description" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Price ({{ $club->currency ?? 'BHD' }})</label>
|
||||
<input type="number" name="price" class="form-control" step="0.01" required>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Duration (days)</label>
|
||||
<input type="number" name="duration_days" class="form-control" value="30" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 mt-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" name="is_popular" class="form-check-input" id="isPopular">
|
||||
<label class="form-check-label" for="isPopular">Mark as Popular</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Add Package</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,152 @@
|
||||
@extends('layouts.admin-club')
|
||||
|
||||
@section('club-admin-content')
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h3 fw-bold mb-1">Roles & Permissions</h2>
|
||||
<p class="text-muted mb-0">Manage club staff roles and access</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addRoleModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Staff
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Staff with Roles -->
|
||||
@if(isset($staffMembers) && count($staffMembers) > 0)
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>Staff Member</th>
|
||||
<th>Role</th>
|
||||
<th>Added</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($staffMembers as $staff)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
@if($staff->user->profile_picture)
|
||||
<img src="{{ asset('storage/' . $staff->user->profile_picture) }}" alt="" class="rounded-circle" style="width: 40px; height: 40px; object-fit: cover;">
|
||||
@else
|
||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
|
||||
<span class="text-white fw-bold">{{ strtoupper(substr($staff->user->full_name ?? 'S', 0, 1)) }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div>
|
||||
<p class="fw-semibold mb-0">{{ $staff->user->full_name ?? 'N/A' }}</p>
|
||||
<p class="text-muted small mb-0">{{ $staff->user->email ?? '' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@if($staff->role === 'admin')
|
||||
<span class="badge bg-danger">Admin</span>
|
||||
@elseif($staff->role === 'instructor')
|
||||
<span class="badge bg-info">Instructor</span>
|
||||
@else
|
||||
<span class="badge bg-secondary">{{ ucfirst($staff->role) }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ $staff->created_at ? $staff->created_at->format('M d, Y') : 'N/A' }}</td>
|
||||
<td>
|
||||
<div class="d-flex gap-1">
|
||||
<button class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="bi bi-shield-check text-muted" style="font-size: 4rem;"></i>
|
||||
<h5 class="mt-3 mb-2">No staff roles assigned</h5>
|
||||
<p class="text-muted mb-3">Add staff members and assign roles</p>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addRoleModal">
|
||||
<i class="bi bi-plus-lg me-2"></i>Add Staff
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Available Roles Info -->
|
||||
<div class="card border-0 shadow-sm mt-4">
|
||||
<div class="card-header bg-white border-0">
|
||||
<h5 class="fw-semibold mb-0">Available Roles</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<div class="border rounded p-3">
|
||||
<div class="d-flex align-items-center gap-2 mb-2">
|
||||
<span class="badge bg-danger">Admin</span>
|
||||
</div>
|
||||
<p class="small text-muted mb-0">Full access to all club settings, members, and financials</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="border rounded p-3">
|
||||
<div class="d-flex align-items-center gap-2 mb-2">
|
||||
<span class="badge bg-info">Instructor</span>
|
||||
</div>
|
||||
<p class="small text-muted mb-0">Can manage activities, view members, and track attendance</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="border rounded p-3">
|
||||
<div class="d-flex align-items-center gap-2 mb-2">
|
||||
<span class="badge bg-secondary">Staff</span>
|
||||
</div>
|
||||
<p class="small text-muted mb-0">Limited access to member check-in and basic operations</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Staff Role Modal -->
|
||||
<div class="modal fade" id="addRoleModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header border-0">
|
||||
<h5 class="modal-title">Add Staff Member</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('admin.club.roles.store', $club->id) }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Search User</label>
|
||||
<input type="text" class="form-control" placeholder="Search by email or name..." id="searchUser">
|
||||
<input type="hidden" name="user_id" id="selectedUserId">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Role</label>
|
||||
<select name="role" class="form-select" required>
|
||||
<option value="">Select role</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="instructor">Instructor</option>
|
||||
<option value="staff">Staff</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Assign Role</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in new issue
Block a user