feat: add Weekly Check-in feature with models, UI components, and session management for enhanced team collaboration
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 6m24s

This commit is contained in:
Julien Froidefond
2026-01-14 10:23:58 +01:00
parent 67d685d346
commit 53ee344ae7
23 changed files with 2753 additions and 24 deletions

16
src/lib/okr-utils.ts Normal file
View File

@@ -0,0 +1,16 @@
/**
* Get the current quarter period string (e.g., "Q1 2025") from a date
*/
export function getCurrentQuarterPeriod(date: Date = new Date()): string {
const year = date.getFullYear();
const month = date.getMonth() + 1; // 1-12
const quarter = Math.ceil(month / 3);
return `Q${quarter} ${year}`;
}
/**
* Check if a period string matches the current quarter
*/
export function isCurrentQuarterPeriod(period: string, date: Date = new Date()): boolean {
return period === getCurrentQuarterPeriod(date);
}

View File

@@ -571,3 +571,219 @@ function generatePeriodSuggestions(): string[] {
}
export const PERIOD_SUGGESTIONS = generatePeriodSuggestions();
// ============================================
// Weekly Check-in - Type Definitions
// ============================================
export type WeeklyCheckInCategory =
| 'WENT_WELL' // Ce qui s'est bien passé
| 'WENT_WRONG' // Ce qui s'est mal passé
| 'CURRENT_FOCUS' // Les enjeux du moment (je me concentre sur ...)
| 'NEXT_FOCUS'; // Les prochains enjeux
export type Emotion =
| 'PRIDE' // Fierté
| 'JOY' // Joie
| 'SATISFACTION' // Satisfaction
| 'GRATITUDE' // Gratitude
| 'CONFIDENCE' // Confiance
| 'FRUSTRATION' // Frustration
| 'WORRY' // Inquiétude
| 'DISAPPOINTMENT' // Déception
| 'EXCITEMENT' // Excitement
| 'ANTICIPATION' // Anticipation
| 'DETERMINATION' // Détermination
| 'NONE'; // Aucune émotion
export interface WeeklyCheckInItem {
id: string;
content: string;
category: WeeklyCheckInCategory;
emotion: Emotion;
order: number;
sessionId: string;
createdAt: Date;
updatedAt: Date;
}
export interface WeeklyCheckInSession {
id: string;
title: string;
participant: string;
date: Date;
userId: string;
items: WeeklyCheckInItem[];
createdAt: Date;
updatedAt: Date;
}
export interface CreateWeeklyCheckInSessionInput {
title: string;
participant: string;
date?: Date;
}
export interface UpdateWeeklyCheckInSessionInput {
title?: string;
participant?: string;
date?: Date;
}
export interface CreateWeeklyCheckInItemInput {
content: string;
category: WeeklyCheckInCategory;
emotion?: Emotion;
order?: number;
}
export interface UpdateWeeklyCheckInItemInput {
content?: string;
category?: WeeklyCheckInCategory;
emotion?: Emotion;
order?: number;
}
// ============================================
// Weekly Check-in - UI Config
// ============================================
export interface WeeklyCheckInSectionConfig {
category: WeeklyCheckInCategory;
title: string;
icon: string;
description: string;
color: string;
}
export const WEEKLY_CHECK_IN_SECTIONS: WeeklyCheckInSectionConfig[] = [
{
category: 'WENT_WELL',
title: 'Ce qui s\'est bien passé',
icon: '✅',
description: 'Les réussites et points positifs de la semaine',
color: '#22c55e', // green
},
{
category: 'WENT_WRONG',
title: 'Ce qui s\'est mal passé',
icon: '⚠️',
description: 'Les difficultés et points d\'amélioration',
color: '#ef4444', // red
},
{
category: 'CURRENT_FOCUS',
title: 'Enjeux du moment',
icon: '🎯',
description: 'Sur quoi je me concentre actuellement',
color: '#3b82f6', // blue
},
{
category: 'NEXT_FOCUS',
title: 'Prochains enjeux',
icon: '🚀',
description: 'Ce sur quoi je vais me concentrer prochainement',
color: '#8b5cf6', // purple
},
];
export const WEEKLY_CHECK_IN_BY_CATEGORY: Record<
WeeklyCheckInCategory,
WeeklyCheckInSectionConfig
> = WEEKLY_CHECK_IN_SECTIONS.reduce(
(acc, config) => {
acc[config.category] = config;
return acc;
},
{} as Record<WeeklyCheckInCategory, WeeklyCheckInSectionConfig>
);
export interface EmotionConfig {
emotion: Emotion;
label: string;
icon: string;
color: string;
}
export const EMOTIONS_CONFIG: EmotionConfig[] = [
{
emotion: 'PRIDE',
label: 'Fierté',
icon: '🦁',
color: '#f59e0b', // amber
},
{
emotion: 'JOY',
label: 'Joie',
icon: '😊',
color: '#eab308', // yellow
},
{
emotion: 'SATISFACTION',
label: 'Satisfaction',
icon: '😌',
color: '#22c55e', // green
},
{
emotion: 'GRATITUDE',
label: 'Gratitude',
icon: '🙏',
color: '#14b8a6', // teal
},
{
emotion: 'CONFIDENCE',
label: 'Confiance',
icon: '💪',
color: '#3b82f6', // blue
},
{
emotion: 'FRUSTRATION',
label: 'Frustration',
icon: '😤',
color: '#f97316', // orange
},
{
emotion: 'WORRY',
label: 'Inquiétude',
icon: '😟',
color: '#eab308', // yellow
},
{
emotion: 'DISAPPOINTMENT',
label: 'Déception',
icon: '😞',
color: '#ef4444', // red
},
{
emotion: 'EXCITEMENT',
label: 'Excitement',
icon: '🤩',
color: '#ec4899', // pink
},
{
emotion: 'ANTICIPATION',
label: 'Anticipation',
icon: '⏳',
color: '#8b5cf6', // purple
},
{
emotion: 'DETERMINATION',
label: 'Détermination',
icon: '🔥',
color: '#dc2626', // red
},
{
emotion: 'NONE',
label: 'Aucune',
icon: '—',
color: '#6b7280', // gray
},
];
export const EMOTION_BY_TYPE: Record<Emotion, EmotionConfig> = EMOTIONS_CONFIG.reduce(
(acc, config) => {
acc[config.emotion] = config;
return acc;
},
{} as Record<Emotion, EmotionConfig>
);