Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@
<router-outlet />
</div>
<!-- Footer Component -->
<lfx-footer class="py-8 px-5 md:px-8 mt-auto"></lfx-footer>
<lfx-footer class="md:ml-8 p-8 mt-auto"></lfx-footer>
</main>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,23 @@ <h1>{{ committeeLabelPlural }}</h1>
<div class="min-h-[400px]">
@if (committees().length === 0 && project()?.uid) {
<!-- Empty state: No committees exist -->
<div class="text-center py-12">
<div class="bg-muted/50 rounded-lg p-8">
<i class="fa-light fa-people-group text-5xl text-muted-foreground mb-4"></i>
<h3 class="text-muted-foreground">No {{ committeeLabelPlural.toLowerCase() }} found</h3>
<div class="flex items-center justify-center p-16 bg-white border border-dashed border-slate-300 rounded-lg">
<div class="text-center max-w-md">
<div class="text-slate-400 mb-4">
<i class="fa-light fa-eyes text-[2rem] mb-4"></i>
<h3 class="text-slate-600 mt-2">Your project has no {{ committeeLabelPlural.toLowerCase() }}, yet.</h3>
</div>
</div>
</div>
} @else if (filteredCommittees().length === 0) {
<!-- Empty state: Committees exist but filters returned no results -->
<div class="text-center py-12">
<div class="bg-muted/50 rounded-lg p-8">
<i class="fa-light fa-filter text-5xl text-muted-foreground mb-4"></i>
<h3 class="text-muted-foreground">No {{ committeeLabelPlural.toLowerCase() }} match your filters</h3>
<p class="text-sm text-muted-foreground mt-2">Try adjusting your search or filter criteria</p>
<div class="flex items-center justify-center p-16 bg-white border border-dashed border-slate-300 rounded-lg">
<div class="text-center max-w-md">
<div class="text-slate-400 mb-4">
<i class="fa-light fa-eyes text-[2rem] mb-4"></i>
</div>
<h3 class="text-xl font-semibold text-slate-900 mt-4">No {{ committeeLabelPlural.toLowerCase() }} Found</h3>
<p class="text-slate-600 mt-2">Try adjusting your search or filter criteria</p>
</div>
</div>
} @else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { InputTextComponent } from '@components/input-text/input-text.component'
import { SelectComponent } from '@components/select/select.component';
import { TextareaComponent } from '@components/textarea/textarea.component';
import { ToggleComponent } from '@components/toggle/toggle.component';
import { COMMITTEE_CATEGORIES, COMMITTEE_LABEL } from '@lfx-one/shared/constants';
import { COMMITTEE_LABEL, FILTERED_COMMITTEE_CATEGORIES } from '@lfx-one/shared/constants';
import { Committee } from '@lfx-one/shared/interfaces';
import { CommitteeService } from '@services/committee.service';
import { ProjectContextService } from '@services/project-context.service';
Expand Down Expand Up @@ -38,8 +38,8 @@ export class CommitteeFormComponent {
public readonly formSubmit = output<void>();
public readonly formCancel = output<void>();

// Category options from constants
public readonly categoryOptions = COMMITTEE_CATEGORIES;
// Category options from constants (using filtered list)
public readonly categoryOptions = FILTERED_COMMITTEE_CATEGORIES;

// Load parent committee options
public parentCommitteeOptions: Signal<{ label: string; value: string | null }[]> = this.initializeParentCommitteeOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
@if (selectedFoundation()) {
<div class="mb-6 flex justify-between items-center gap-4" data-testid="foundation-project">
<h1>{{ selectedFoundation()?.name }} Overview</h1>
<!-- Data Copilot Button -->
<lfx-data-copilot></lfx-data-copilot>
</div>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import { Component, computed, inject, Signal } from '@angular/core';
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { DataCopilotComponent } from '@app/shared/components/data-copilot/data-copilot.component';
import { SelectComponent } from '@components/select/select.component';
import { Account, PendingActionItem } from '@lfx-one/shared/interfaces';
import { AccountContextService } from '@services/account-context.service';
Expand All @@ -20,15 +19,7 @@ import { PendingActionsComponent } from '../components/pending-actions/pending-a

@Component({
selector: 'lfx-board-member-dashboard',
imports: [
OrganizationInvolvementComponent,
PendingActionsComponent,
MyMeetingsComponent,
FoundationHealthComponent,
SelectComponent,
ReactiveFormsModule,
DataCopilotComponent,
],
imports: [OrganizationInvolvementComponent, PendingActionsComponent, MyMeetingsComponent, FoundationHealthComponent, SelectComponent, ReactiveFormsModule],
templateUrl: './board-member-dashboard.component.html',
styleUrl: './board-member-dashboard.component.scss',
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@
<!-- SPDX-License-Identifier: MIT -->

<!-- Card wrapper with border and shadow -->
<div
class="bg-white rounded-xl border-t border-r border-b border-gray-200 shadow-sm hover:shadow-md transition-shadow relative"
data-testid="dashboard-meeting-card">
<!-- Colored left border overlay -->
<div
aria-hidden="true"
class="absolute border-0 border-l-4 border-t border-b border-r border-solid inset-0 pointer-events-none rounded-xl"
[ngClass]="borderColorClass()"></div>
<div class="bg-white rounded-xl border shadow-md" data-testid="dashboard-meeting-card">
<div class="p-4 space-y-3">
<!-- Header with meeting type and project badges -->
<div class="flex items-center gap-2 flex-wrap">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,6 @@ export class DashboardMeetingCardComponent {
return occurrence?.title || meeting.title;
});

public readonly borderColorClass: Signal<string> = computed(() => {
const type = this.meeting().meeting_type?.toLowerCase();
const config = type ? (MEETING_TYPE_CONFIGS[type] ?? DEFAULT_MEETING_TYPE_CONFIG) : DEFAULT_MEETING_TYPE_CONFIG;
return config.borderColor;
});

public readonly canJoinMeeting: Signal<boolean> = computed(() => {
return canJoinMeeting(this.meeting(), this.occurrence());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ <h5 class="text-sm font-medium">{{ card.title }}</h5>
<div class="text-xl font-medium">{{ card.value }}</div>
}
@if (card.subtitle) {
<div class="text-xs text-muted-foreground">{{ card.subtitle }}</div>
<div class="text-xs text-gray-500">{{ card.subtitle }}</div>
}
</div>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h2>{{ accountName() }}'s Involvement</h2>
<!-- Membership Tier Card (Special) -->
@if (metric.isMembershipTier) {
<div
class="p-4 bg-white rounded-lg border border-slate-200 hover:border-[#0094FF] transition-colors cursor-pointer flex-shrink-0 w-80"
class="p-4 bg-white rounded-lg border border-slate-200 transition-colors cursor-pointer flex-shrink-0 w-80"
[attr.data-testid]="'dashboard-involvement-metric-' + metric.title">
<div class="space-y-3">
<div class="flex items-center gap-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ <h2 class="py-1">Pending Actions</h2>
<div class="flex flex-col gap-3" data-testid="dashboard-pending-actions-list">
@for (item of pendingActions(); track $index) {
<div
class="p-4 border rounded-lg"
class="p-4 border-0 rounded-lg shadow-md"
[ngClass]="{
'bg-amber-50 border-amber-200': item.color === 'amber',
'bg-blue-50 border-blue-200': item.color === 'blue',
'bg-green-50 border-green-200': item.color === 'green',
'bg-purple-50 border-purple-200': item.color === 'purple',
'bg-amber-50': item.color === 'amber',
'bg-blue-50': item.color === 'blue',
'bg-green-50': item.color === 'green',
'bg-purple-50': item.color === 'purple',
}"
[attr.data-testid]="'dashboard-pending-actions-item-' + item.type">
<!-- Header with Type and Badge -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<!-- Project Logo -->
@if (project()?.logo_url) {
<div class="flex items-center justify-center mb-6">
<img [src]="project()?.logo_url" [alt]="project()?.name" class="w-auto h-10 md:h-20" />
<img [src]="project()?.logo_url" [alt]="project()?.name" class="w-auto h-10 md:h-14" />
</div>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class MeetingManageComponent {

// Validation signals for template
public readonly canProceed = signal<boolean>(false);
public readonly project = computed(() => this.projectContextService.selectedProject() || this.projectContextService.selectedFoundation());
public readonly canGoNext = computed(() => this.currentStep() + 1 < this.totalSteps && this.canNavigateToStep(this.currentStep() + 1));
public readonly canGoPrevious = computed(() => this.currentStep() > 1);
public readonly isFirstStep = computed(() => this.currentStep() === 1);
Expand Down Expand Up @@ -388,7 +389,7 @@ export class MeetingManageComponent {
}

return {
project_uid: formValue.selectedProjectUid || this.projectContextService.getProjectUid(),
project_uid: formValue.selectedProjectUid || this.project()?.uid,
title: formValue.title,
description: formValue.description || '',
start_time: startDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,20 @@ <h1>Meetings</h1>
</div>
}
</div>
} @else if (upcomingMeetings().length === 0 && timeFilter() === 'upcoming') {
<div class="flex items-center justify-center p-16 bg-white border border-dashed border-slate-300 rounded-lg">
<div class="text-center max-w-md">
<div class="text-slate-400 mb-4">
<i class="fa-light fa-eyes text-[2rem] mb-4"></i>
<h3 class="text-slate-600 mt-2">Your project has no meetings, yet.</h3>
</div>
</div>
</div>
} @else if (filteredMeetings().length === 0 && project()?.uid) {
<div class="flex items-center justify-center p-16 bg-white border border-dashed border-slate-300 rounded-lg">
<div class="text-center max-w-md">
<div class="text-slate-400 mb-4">
<i class="fa-light fa-calendar-xmark text-6xl"></i>
<i class="fa-light fa-eyes text-[2rem] mb-4"></i>
</div>
<h3 class="text-xl font-semibold text-slate-900 mt-4">No Meetings Found</h3>
<p class="text-slate-600 mt-2">Try adjusting your search or filter criteria</p>
Expand Down
3 changes: 3 additions & 0 deletions apps/lfx-one/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export default {
theme: {
extend: {
colors: lfxColors,
boxShadow: {
md: '0px 1px 2px -1px rgba(0, 0, 0, 0.10), 0px 1px 3px 0px rgba(0, 0, 0, 0.10)',
},
keyframes: {
'fade-in-up': {
'0%': {
Expand Down
20 changes: 18 additions & 2 deletions packages/shared/src/constants/committees.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,22 @@ export const COMMITTEE_CATEGORIES = [
{ label: 'Marketing Oversight Committee/Marketing Advisory Committee', value: 'Marketing Oversight Committee/Marketing Advisory Committee' },
{ label: 'Product Security', value: 'Product Security' },
{ label: 'Special Interest Group', value: 'Special Interest Group' },
{ label: 'Technical Advisory Committee', value: 'Technical Advisory Committee' },
{ label: 'Technical Mailing List', value: 'Technical Mailing List' },
{ label: 'Technical Oversight Committee/Technical Advisory Committee', value: 'Technical Oversight Committee/Technical Advisory Committee' },
{ label: 'Technical Oversight Committee', value: 'Technical Oversight Committee' },
{ label: 'Technical Steering Committee', value: 'Technical Steering Committee' },
{ label: 'Working Group', value: 'Working Group' },
{ label: 'Other', value: 'Other' },
];

/**
* Filtered committee categories for specific UI contexts
* @description Subset of categories for restricted selection (e.g., forms, dashboards)
*/
export const FILTERED_COMMITTEE_CATEGORIES = [
{ label: 'Special Interest Group', value: 'Special Interest Group' },
{ label: 'Technical Advisory Committee', value: 'Technical Advisory Committee' },
{ label: 'Technical Oversight Committee', value: 'Technical Oversight Committee' },
{ label: 'Technical Steering Committee', value: 'Technical Steering Committee' },
{ label: 'Working Group', value: 'Working Group' },
{ label: 'Other', value: 'Other' },
Expand Down Expand Up @@ -110,7 +124,8 @@ const COMMITTEE_TYPE_COLORS = {

// Technical committees
'Technical Steering Committee': 'bg-positive-100 text-positive-800',
'Technical Oversight Committee/Technical Advisory Committee': 'bg-brand-100 text-brand-700',
'Technical Advisory Committee': 'bg-brand-100 text-brand-700',
'Technical Oversight Committee': 'bg-brand-100 text-brand-700',
'Technical Mailing List': 'bg-brand-100 text-brand-700',

// Technical roles
Expand Down Expand Up @@ -171,6 +186,7 @@ export function getCommitteeTypeColor(category: string | undefined): string {

// Technical committees
if (lowerCategory.includes('technical steering')) return 'bg-positive-100 text-positive-800';
if (lowerCategory.includes('technical advisory')) return 'bg-brand-100 text-brand-700';
if (lowerCategory.includes('technical oversight')) return 'bg-brand-100 text-brand-700';
if (lowerCategory.includes('technical mailing')) return 'bg-brand-100 text-brand-700';

Expand Down