#11 - Add total hours per career, per category and per course.
This commit is contained in:
parent
3fa78d78c8
commit
663b256112
@ -1,6 +1,7 @@
|
|||||||
import directus from './directus';
|
import directus from './directus';
|
||||||
import { readItems, type Query } from '@directus/sdk';
|
import { readItems, type Query } from '@directus/sdk';
|
||||||
import type { CodyopsCareers, Careers } from '../types/codyops-careers';
|
import type { CodyopsCareers, Careers } from '../types/codyops-careers';
|
||||||
|
import { sumTimes } from '../utils/time';
|
||||||
|
|
||||||
export async function getCareers(): Promise<Careers[]> {
|
export async function getCareers(): Promise<Careers[]> {
|
||||||
const careers = await directus.request(
|
const careers = await directus.request(
|
||||||
@ -16,6 +17,11 @@ export async function getCareers(): Promise<Careers[]> {
|
|||||||
'name',
|
'name',
|
||||||
'level',
|
'level',
|
||||||
'category',
|
'category',
|
||||||
|
{
|
||||||
|
modules: [
|
||||||
|
'duration'
|
||||||
|
]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -23,5 +29,41 @@ export async function getCareers(): Promise<Careers[]> {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
return careers;
|
|
||||||
|
const careersWithCalculatedHours = careers.map(career => {
|
||||||
|
let totalCareerMinutes = 0;
|
||||||
|
|
||||||
|
const coursesWithCalculatedHours = career.courses.map(courseItem => {
|
||||||
|
const course = courseItem.codyops_courses_id;
|
||||||
|
if (course && course.modules) {
|
||||||
|
const moduleDurations = course.modules
|
||||||
|
.map(module => module.duration)
|
||||||
|
.filter((duration): duration is string => duration !== undefined && duration !== null); // Filter out undefined/null
|
||||||
|
const { hours, minutes } = sumTimes(moduleDurations);
|
||||||
|
const totalCourseMinutes = (hours * 60) + minutes;
|
||||||
|
totalCareerMinutes += totalCourseMinutes;
|
||||||
|
return {
|
||||||
|
...courseItem,
|
||||||
|
codyops_courses_id: {
|
||||||
|
...course,
|
||||||
|
totalCourseHours: hours + (minutes / 60), // Store as decimal hours
|
||||||
|
totalCourseMinutes: totalCourseMinutes,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return courseItem;
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalCareerHours = Math.floor(totalCareerMinutes / 60);
|
||||||
|
const remainingCareerMinutes = totalCareerMinutes % 60;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...career,
|
||||||
|
courses: coursesWithCalculatedHours,
|
||||||
|
totalCareerHours: totalCareerHours + (remainingCareerMinutes / 60), // Store as decimal hours
|
||||||
|
totalCareerMinutes: totalCareerMinutes,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return careersWithCalculatedHours;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ const FeaturesComponent = (await import(`../../sections/${career.slug}/${career.
|
|||||||
<DescriptionComponent />
|
<DescriptionComponent />
|
||||||
</CareerSection>
|
</CareerSection>
|
||||||
<Cta />
|
<Cta />
|
||||||
<CareerProgram list={career.courses.map(c => c.codyops_courses_id)} />
|
<CareerProgram career={career} />
|
||||||
<Cta />
|
<Cta />
|
||||||
</Main>
|
</Main>
|
||||||
</Root>
|
</Root>
|
||||||
|
@ -1,29 +1,39 @@
|
|||||||
---
|
---
|
||||||
import type { Courses } from '../../../types/codyops-courses';
|
import type { Courses } from '../../../types/codyops-courses';
|
||||||
|
import type { Careers } from '../../../types/codyops-careers';
|
||||||
import { toSnakeCase, fromSnakeCase } from '../../../utils';
|
import { toSnakeCase, fromSnakeCase } from '../../../utils';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
list?: Courses[];
|
career: Careers;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { list }: Props = Astro.props;
|
const { career }: Props = Astro.props;
|
||||||
|
|
||||||
// Group courses by category
|
// Group courses by category
|
||||||
const groupedCourses = list?.reduce((acc, course) => {
|
const groupedCourses = career.courses?.reduce((acc, courseItem) => {
|
||||||
|
const course = courseItem.codyops_courses_id;
|
||||||
|
if (course) {
|
||||||
const category = course.category;
|
const category = course.category;
|
||||||
if (!acc[category]) {
|
if (!acc[category]) {
|
||||||
acc[category] = [];
|
acc[category] = { courses: [], totalCategoryMinutes: 0 };
|
||||||
|
}
|
||||||
|
acc[category].courses.push(course);
|
||||||
|
if (course.totalCourseMinutes) {
|
||||||
|
acc[category].totalCategoryMinutes += course.totalCourseMinutes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
acc[category].push(course);
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, Courses[]>);
|
}, {} as Record<string, { courses: Courses[]; totalCategoryMinutes: number }>);
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="program" class="container content-space-t-3 career__section">
|
<section id="program" class="container content-space-t-3 career__section">
|
||||||
<h2 class="career-subtitle text-white text-center mb-5">Programa de Carrera</h2>
|
<h2 class="career-subtitle text-white text-center mb-5">Programa de Carrera</h2>
|
||||||
|
<div class="text-center text-white mb-4">
|
||||||
|
Total Carrera: {career.totalCareerHours?.toFixed(1)} horas
|
||||||
|
</div>
|
||||||
<div class="accordion accordion-btn-icon-start">
|
<div class="accordion accordion-btn-icon-start">
|
||||||
{groupedCourses && Object.entries(groupedCourses).map(([category, courses]) => (
|
{groupedCourses && Object.entries(groupedCourses).map(([category, { courses, totalCategoryMinutes }]) => (
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<div class="accordion-header" id={`heading-${toSnakeCase(category)}`}>
|
<div class="accordion-header" id={`heading-${toSnakeCase(category)}`}>
|
||||||
<a
|
<a
|
||||||
@ -46,7 +56,7 @@ const groupedCourses = list?.reduce((acc, course) => {
|
|||||||
<!-- End Col -->
|
<!-- End Col -->
|
||||||
|
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
{/* Hours will be calculated and displayed here if needed */}
|
<span class="small text-white">{(totalCategoryMinutes / 60).toFixed(1)} hours</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- End Col -->
|
<!-- End Col -->
|
||||||
</div>
|
</div>
|
||||||
@ -87,7 +97,7 @@ const groupedCourses = list?.reduce((acc, course) => {
|
|||||||
<!-- End Col -->
|
<!-- End Col -->
|
||||||
|
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
{/* Hours will be displayed here if needed */}
|
<span class="small text-white">{course.totalCourseHours?.toFixed(1)} hours</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- End Col -->
|
<!-- End Col -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,6 +15,8 @@ export interface Careers {
|
|||||||
courses: {
|
courses: {
|
||||||
codyops_courses_id: Courses;
|
codyops_courses_id: Courses;
|
||||||
}[];
|
}[];
|
||||||
|
totalCareerHours?: number;
|
||||||
|
totalCareerMinutes?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodyopsCareers {
|
export interface CodyopsCareers {
|
||||||
|
@ -25,6 +25,8 @@ export interface Courses {
|
|||||||
codyops_careers?: {
|
codyops_careers?: {
|
||||||
codyops_careers_id?: Partial<Careers>;
|
codyops_careers_id?: Partial<Careers>;
|
||||||
};
|
};
|
||||||
|
totalCourseHours?: number;
|
||||||
|
totalCourseMinutes?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodyopsCourses {
|
export interface CodyopsCourses {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user