Updated Google Scholar Integration,Updated Admin and HOD Dashboard, Added Google Auth: Login Controller and Routes
This commit is contained in:
@@ -1,22 +1,223 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('header')
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
Coordinator Dashboard
|
||||
</h2>
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
Coordinator Dashboard
|
||||
</h2>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||
<div class="p-6 text-gray-900">
|
||||
Welcome, Coordinator! Manage department-related tasks here.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('departments.index') }}" class="text-blue-500 underline">View Departments</a><br>
|
||||
<a href="{{ route('users.index') }}" class="text-blue-500 underline">View Faculty</a><br>
|
||||
<a href="{{ route('profile.edit') }}" class="text-blue-500 underline">Edit Profile</a>
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||
<div class="p-6 text-gray-900">
|
||||
Welcome, Coordinator! Manage department-related tasks here.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graphs Section -->
|
||||
<div class="mt-6">
|
||||
<h3 class="text-lg font-semibold">Analytics</h3>
|
||||
<div id="graphs-container" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6 mt-4">
|
||||
<!-- First three graphs -->
|
||||
<div class="bg-white p-4 shadow rounded">
|
||||
<h4 class="text-md font-semibold mb-4">Comparison of All Models by Department</h4>
|
||||
<div class="flex flex-row sm:flex-row sm:items-center sm:justify-between">
|
||||
<select id="departmentSelector" class="mb-4 px-7 border rounded">
|
||||
@foreach($departments as $department)
|
||||
<option value="{{ $department->id }}">{{ $department->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select id="comparisonYearSelector" class="mb-4 px-7 border rounded">
|
||||
<option value="all">All Years</option>
|
||||
@foreach($years as $year)
|
||||
<option value="{{ $year }}">{{ $year }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<canvas id="comparisonChart"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-4 shadow rounded">
|
||||
<h4 class="text-md font-semibold mb-4">Total Contribution by Department</h4>
|
||||
<div class="flex flex-row sm:flex-row sm:items-center sm:justify-between">
|
||||
<select id="modelSelector" class="mb-4 sm:mb-0 p-2 border rounded">
|
||||
<option value="all">All Categories</option>
|
||||
<option value="ActivitiesAttended">Activities Attended</option>
|
||||
<option value="ActivitiesOrganised">Activities Organised</option>
|
||||
<option value="BooksPublished">Books Published</option>
|
||||
<option value="ExternalEngagement">External Engagement</option>
|
||||
<option value="IvOrganised">IV Organised</option>
|
||||
<option value="OnlineCourse">Online Courses</option>
|
||||
<option value="Patent">Patents</option>
|
||||
<option value="Publication">Publications</option>
|
||||
</select>
|
||||
<select id="contributionYearSelector" class="mb-4 sm:ml-4 px-7 border rounded">
|
||||
<option value="all">All Years</option>
|
||||
@foreach($years as $year)
|
||||
<option value="{{ $year }}">{{ $year }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<canvas id="contributionChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const departmentSelector = document.getElementById('departmentSelector');
|
||||
const comparisonYearSelector = document.getElementById('comparisonYearSelector');
|
||||
const modelSelector = document.getElementById('modelSelector');
|
||||
const contributionYearSelector = document.getElementById('contributionYearSelector');
|
||||
|
||||
// Use coordinator route names (must exist in routes/web.php)
|
||||
const comparisonBaseUrl = "{{ route('coordinator.analytics.comparison') }}";
|
||||
const contributionBaseUrl = "{{ route('coordinator.analytics.contribution') }}";
|
||||
|
||||
function fetchComparisonData(departmentId, year) {
|
||||
const yearParam = year === 'all' ? '' : `&year=${year}`;
|
||||
const url = departmentId
|
||||
? `${comparisonBaseUrl}?department_id=${departmentId}${yearParam}`
|
||||
: `${comparisonBaseUrl}?${yearParam}`;
|
||||
|
||||
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('HTTP ' + response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
const ctx = document.getElementById('comparisonChart').getContext('2d');
|
||||
if (window.comparisonChartInstance) window.comparisonChartInstance.destroy();
|
||||
|
||||
const modelPages = [
|
||||
'ActivitiesAttendedResponses',
|
||||
'ActivitiesOrganisedResponses',
|
||||
'BooksPublishedResponses',
|
||||
'ExternalEngagementResponses',
|
||||
'IvOrganisedResponses',
|
||||
'OnlineCoursesResponses',
|
||||
'PatentsResponses',
|
||||
'PublicationsResponses'
|
||||
];
|
||||
|
||||
// Redirect to coordinator pages
|
||||
const barLinks = modelPages.map(page => `/coordinator/${page}`);
|
||||
|
||||
window.comparisonChartInstance = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: data.labels,
|
||||
datasets: [{
|
||||
label: 'Comparison by Department',
|
||||
data: data.values,
|
||||
}]
|
||||
},
|
||||
plugins: [ChartDataLabels],
|
||||
options: {
|
||||
plugins: { legend: { display: false } },
|
||||
responsive: true,
|
||||
scales: { y: { beginAtZero: true } },
|
||||
onClick: function(evt, elements) {
|
||||
if (elements.length > 0) {
|
||||
const idx = elements[0].index;
|
||||
const deptId = departmentSelector ? departmentSelector.value : departmentId;
|
||||
if (idx < barLinks.length) window.location.href = `${barLinks[idx]}?department_id=${deptId}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// show total
|
||||
let comparisonTotal = document.getElementById('comparisonTotal');
|
||||
if (!comparisonTotal) {
|
||||
comparisonTotal = document.createElement('p');
|
||||
comparisonTotal.id = 'comparisonTotal';
|
||||
comparisonTotal.classList.add('text-center', 'font-bold', 'mt-2');
|
||||
document.getElementById('comparisonChart').parentElement.appendChild(comparisonTotal);
|
||||
}
|
||||
comparisonTotal.textContent = `Total: ${data.total}`;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Comparison fetch error:', err);
|
||||
});
|
||||
}
|
||||
|
||||
function fetchContributionData(model, year) {
|
||||
const yearParam = year === 'all' ? '' : `&year=${year}`;
|
||||
const url = `${contributionBaseUrl}?model=${model}${yearParam}`;
|
||||
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('HTTP ' + response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
const ctx = document.getElementById('contributionChart').getContext('2d');
|
||||
if (window.contributionChartInstance) window.contributionChartInstance.destroy();
|
||||
|
||||
// map labels to coordinator pages (adjust if needed)
|
||||
const barLinks = data.labels.map((label, idx) => `/coordinator/contribution/${idx+1}`);
|
||||
|
||||
window.contributionChartInstance = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: data.labels,
|
||||
datasets: [{ label: 'Total Contribution by Department', data: data.values }]
|
||||
},
|
||||
plugins: [ChartDataLabels],
|
||||
options: {
|
||||
plugins: { legend: { display: false } },
|
||||
responsive: true,
|
||||
scales: { y: { beginAtZero: true } },
|
||||
onClick: function(evt, elements) {
|
||||
if (elements.length > 0) {
|
||||
const idx = elements[0].index;
|
||||
window.location.href = barLinks[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let contributionTotal = document.getElementById('contributionTotal');
|
||||
if (!contributionTotal) {
|
||||
contributionTotal = document.createElement('p');
|
||||
contributionTotal.id = 'contributionTotal';
|
||||
contributionTotal.classList.add('text-center', 'font-bold', 'mt-2');
|
||||
document.getElementById('contributionChart').parentElement.appendChild(contributionTotal);
|
||||
}
|
||||
contributionTotal.textContent = `Total: ${data.total}`;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Contribution fetch error:', err);
|
||||
});
|
||||
}
|
||||
|
||||
// INITIAL FETCH: use the selected department (not hardcoded 1)
|
||||
const initialDept = departmentSelector ? departmentSelector.value : null;
|
||||
const initialYear = comparisonYearSelector ? comparisonYearSelector.value : 'all';
|
||||
if (initialDept) {
|
||||
fetchComparisonData(initialDept, initialYear);
|
||||
} else {
|
||||
// fallback: let server infer (coordinator filter), call without department_id
|
||||
fetchComparisonData('', initialYear);
|
||||
}
|
||||
|
||||
// initial contribution
|
||||
const initModel = modelSelector ? modelSelector.value : 'all';
|
||||
const initContribYear = contributionYearSelector ? contributionYearSelector.value : 'all';
|
||||
fetchContributionData(initModel, initContribYear);
|
||||
|
||||
// Event listeners
|
||||
if (departmentSelector) departmentSelector.addEventListener('change', () => fetchComparisonData(departmentSelector.value, comparisonYearSelector.value));
|
||||
if (comparisonYearSelector) comparisonYearSelector.addEventListener('change', () => fetchComparisonData(departmentSelector.value, comparisonYearSelector.value));
|
||||
if (modelSelector) modelSelector.addEventListener('change', () => fetchContributionData(modelSelector.value, contributionYearSelector.value));
|
||||
if (contributionYearSelector) contributionYearSelector.addEventListener('change', () => fetchContributionData(modelSelector.value, contributionYearSelector.value));
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
Reference in New Issue
Block a user