import { WrappedData, Slide } from './types.js';
import { StatsCalculator } from './stats-calculator.js';
export class TeamSlideGenerator {
constructor(private data: WrappedData, private statsCalculator: StatsCalculator) {}
generateTeamSlides(): Slide[] {
const slides: Slide[] = [];
// Welcome slide
slides.push(this.createWelcomeSlide());
// Team summary
slides.push(this.createTeamSummarySlide());
// Most active days
slides.push(this.createMostActiveDaysSlide());
// Busiest months
slides.push(this.createBusiestMonthsSlide());
// Day of week distribution
slides.push(this.createDayOfWeekSlide());
// Pull requests if available
if (this.data.pullRequests && this.data.pullRequests.totalPRs.merged > 0) {
slides.push(this.createPRStatsSlide());
}
// Fun facts
slides.push(this.createFunFactsSlide());
return slides;
}
private createWelcomeSlide(): Slide {
const period = this.data.period;
return {
title: 'Git Wrapped de l\'Équipe',
emoji: '🎉',
subtitle: 'Votre année en code, visualisée',
content: `
Git Wrapped de l'Équipe
${period.start} à ${period.end}
Célébrons les réalisations de votre équipe!
`
};
}
private createTeamSummarySlide(): Slide {
const summary = this.data.teamSummary;
// Calculate actual days in period
const startDate = new Date(this.data.period.start);
const endDate = new Date(this.data.period.end);
const daysDiff = Math.max(1, Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)));
const avgCommitsPerDay = (summary.totalCommits / daysDiff).toFixed(1);
return {
title: 'Réalisations de l\'Équipe',
emoji: '🚀',
subtitle: 'Les grands chiffres de votre équipe',
content: `
${summary.totalCommits.toLocaleString()}
commits totaux
${summary.linesAdded.toLocaleString()}
lignes ajoutées
${summary.linesDeleted.toLocaleString()}
lignes supprimées
${avgCommitsPerDay}
commits par jour
`
};
}
private createBusiestMonthsSlide(): Slide {
const busiestMonths = this.data.busiestMonths
.sort((a, b) => b.commits - a.commits)
.slice(0, 5);
return {
title: 'Mois les Plus Actifs',
emoji: '📅',
subtitle: 'Quand votre équipe était la plus productive',
content: `
${busiestMonths.map(month => {
const date = new Date(month.month + '-01');
const monthName = date.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
return `
${monthName}
${month.commits.toLocaleString()} commits
`;
}).join('')}
`
};
}
private createPRStatsSlide(): Slide {
const prData = this.data.pullRequests!;
return {
title: 'Pull Requests',
emoji: '✅',
subtitle: 'Stats de collaboration de l\'équipe',
content: `
${prData.totalPRs.opened}
PRs ouvertes
${prData.totalPRs.merged}
PRs mergées
Excellente collaboration!
`
};
}
private createMostActiveDaysSlide(): Slide {
const busiestDays = this.data.busiestDays || [];
const topDays = busiestDays.slice(0, 5);
return {
title: 'Jours les Plus Productifs',
emoji: '🔥',
subtitle: 'Jours avec le plus de commits',
content: `
${topDays.map((day, index) => {
const date = new Date(day.date);
const formatted = date.toLocaleDateString('fr-FR', {
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric'
});
return `
${index + 1}.
${formatted}
${day.commits} commits
`;
}).join('')}
`
};
}
private createDayOfWeekSlide(): Slide {
const dayOrder = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const dayData = this.data.commitsByDayOfWeek || {};
const sortedDays = dayOrder
.map(day => ({ day, commits: dayData[day] || 0 }))
.filter(d => d.commits > 0)
.sort((a, b) => b.commits - a.commits);
const total = Object.values(dayData).reduce((sum, count) => sum + count, 0);
const mostPopularDay = sortedDays[0];
const percentage = ((mostPopularDay.commits / total) * 100).toFixed(1);
// French day names
const frenchDays: Record = {
'Monday': 'Lundi',
'Tuesday': 'Mardi',
'Wednesday': 'Mercredi',
'Thursday': 'Jeudi',
'Friday': 'Vendredi',
'Saturday': 'Samedi',
'Sunday': 'Dimanche'
};
return {
title: 'Jour Préféré pour Coder',
emoji: '📅',
subtitle: 'Quel jour de la semaine votre équipe préfère',
content: `
${frenchDays[mostPopularDay.day]}
${percentage}% de tous les commits (${mostPopularDay.commits.toLocaleString()} commits)
${sortedDays.slice(0, 5).map(d => `
${d.commits}
${frenchDays[d.day]}
`).join('')}
`
};
}
private createFunFactsSlide(): Slide {
const totalCommits = this.data.teamSummary.totalCommits;
// Calculate actual days in period
const startDate = new Date(this.data.period.start);
const endDate = new Date(this.data.period.end);
const daysDiff = Math.max(1, Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)));
const avgCommitsPerDay = (totalCommits / daysDiff).toFixed(1);
// Most common day of week
const dayData = this.data.commitsByDayOfWeek || {};
const dayOrder = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const sortedDays = dayOrder
.map(day => ({ day, commits: dayData[day] || 0 }))
.sort((a, b) => b.commits - a.commits);
const frenchDays: Record = {
'Monday': 'Lundi',
'Tuesday': 'Mardi',
'Wednesday': 'Mercredi',
'Thursday': 'Jeudi',
'Friday': 'Vendredi',
'Saturday': 'Samedi',
'Sunday': 'Dimanche'
};
const favoriteDay = sortedDays[0]?.day ? frenchDays[sortedDays[0].day] : 'N/A';
return {
title: 'Faits Amusants',
emoji: '🎯',
subtitle: 'Chiffres intéressants de votre équipe',
content: `
${avgCommitsPerDay}
Commits par jour
${this.data.teamSummary.linesAdded.toLocaleString()}
Lignes ajoutées
${this.data.teamSummary.linesDeleted.toLocaleString()}
Lignes supprimées
${favoriteDay}
Jour de codage préféré
🎉 Ensemble, votre équipe a livré ${totalCommits.toLocaleString()} commits cette année!
`
};
}
}