@@ -244,6 +244,296 @@ Removed redundant status column from members table to maintain consistency with
244244
245245**Result:** Members table now shows: Name → Email → Role → Billable Rate → Edit
246246
247+ ### Remove Pie Chart from Reporting Pages
248+
249+ Completely removed the ReportingPieChart component from the entire application.
250+
251+ **Files modified:**
252+ - ` resources/ js/ Components/ Common/ Reporting/ ReportingOverview .vue `
253+ - ` resources/ js/ Pages/ SharedReport .vue `
254+
255+ **Component removed:** ` ReportingPieChart` (equivalent to the ` ProjectsChartCard` removed from dashboard)
256+
257+ **Removed imports:**
258+ ` ` ` js
259+ - import ReportingPieChart from ' @/Components/Common/Reporting/ReportingPieChart.vue' ;
260+ ` ` `
261+
262+ **Removed from templates:**
263+ ` ` ` vue
264+ - < div class = " px-2 lg:px-4" >
265+ - < ReportingPieChart
266+ - : data= " groupedPieChartData" >< / ReportingPieChart>
267+ - < / div>
268+ ` ` `
269+
270+ **Removed computed properties:**
271+ ` ` ` js
272+ - const groupedPieChartData = computed (() => { ... });
273+ ` ` `
274+
275+ **File to delete:** ` resources/ js/ Components/ Common/ Reporting/ ReportingPieChart .vue ` (component file no longer needed)
276+
277+ **Layout changes:**
278+ - Removed sidebar layout (grid-cols-4)
279+ - Table now spans full width
280+ - Bar chart (ReportingChart) remains for data visualization
281+
282+ **Result:** ReportingPieChart component completely removed from the application - no imports, no usage, no data generation.
283+
284+ ### Performance Optimization: Projects Search Filter
285+
286+ Optimized the search filter in Projects.vue to improve performance when searching through projects and their associated clients.
287+
288+ **File modified:** ` resources/ js/ Pages/ Projects .vue `
289+
290+ **Problem:** O(n*m) complexity - the client lookup inside the filter loop was inefficient
291+ - For each project (n), was calling ` clients .value .find ()` (m operations)
292+ - With many projects and clients, this created performance bottlenecks
293+
294+ **Solution:** Create clientsMap before filtering for O(1) lookup
295+
296+ **Before:**
297+ ` ` ` js
298+ // Search in client name
299+ const client = clients .value .find (client => client .id === project .client_id );
300+ const clientNameMatch = client? .name .toLowerCase ().includes (query) || false ;
301+ ` ` `
302+
303+ **After:**
304+ ` ` ` js
305+ // Create clients map for O(1) lookup performance
306+ const clientsMap = new Map (clients .value .map (c => [c .id , c]));
307+
308+ filteredProjects = filteredProjects .filter ((project ) => {
309+ // Search in client name
310+ const client = clientsMap .get (project .client_id );
311+ const clientNameMatch = client? .name .toLowerCase ().includes (query) || false ;
312+ // ...
313+ });
314+ ` ` `
315+
316+ **Performance improvement:** O(n*m) → O(n+m) complexity
317+ - Map creation: O(m) - done once
318+ - Lookups: O(1) per project instead of O(m)
319+ - Significant improvement with large datasets
320+
321+ ### CSS Cleanup: Remove Redundant Tailwind Classes
322+
323+ Fixed duplicate and redundant CSS class declarations across all table components throughout the application.
324+
325+ **Problem:** Many table components had duplicate ` 3xl : pl- 12 ` classes in their Tailwind CSS declarations
326+ - Some had simple duplicates: ` pl- 4 sm: pl- 6 lg: pl- 8 3xl : pl- 12 ` (redundant ` 3xl : pl- 12 ` )
327+ - Some had double duplicates: ` 3xl : pl- 12 ... pl- 4 sm: pl- 6 lg: pl- 8 3xl : pl- 12 ` (appearing twice!)
328+
329+ **Files cleaned up:**
330+ - ` resources/ js/ Components/ Common/ Client/ ClientTableRow .vue `
331+ - ` resources/ js/ Components/ Common/ Client/ ClientTableHeading .vue `
332+ - ` resources/ js/ Components/ Common/ Tag/ TagTableHeading .vue `
333+ - ` resources/ js/ Components/ Common/ Tag/ TagTableRow .vue `
334+ - ` resources/ js/ Components/ Common/ ProjectMember/ ProjectMemberTableHeading .vue `
335+ - ` resources/ js/ Components/ Common/ ProjectMember/ ProjectMemberTableRow .vue `
336+ - ` resources/ js/ Components/ Common/ Invitation/ InvitationTableRow .vue `
337+ - ` resources/ js/ Components/ Common/ Invitation/ InvitationTableHeading .vue `
338+ - ` resources/ js/ Components/ Common/ Report/ ReportTableHeading .vue `
339+ - ` resources/ js/ Components/ Common/ Report/ ReportTableRow .vue `
340+ - ` resources/ js/ Components/ Common/ Member/ MemberTableRow .vue `
341+ - ` resources/ js/ Components/ Common/ Member/ MemberTableHeading .vue `
342+ - ` resources/ js/ Components/ Common/ Project/ ProjectTableRow .vue `
343+ - ` resources/ js/ Components/ Common/ Project/ ProjectTableHeading .vue `
344+ - ` resources/ js/ Components/ Common/ Task/ TaskTableHeading .vue `
345+ - ` resources/ js/ Components/ Common/ Task/ TaskTableRow .vue `
346+
347+ **Changes made:**
348+ ` ` ` css
349+ /* Before - redundant classes */
350+ class = " ... pl-4 sm:pl-6 lg:pl-8 3xl:pl-12"
351+ class = " ... 3xl:pl-12 ... pl-4 sm:pl-6 lg:pl-8 3xl:pl-12"
352+
353+ /* After - clean responsive padding */
354+ class = " ... pl-4 sm:pl-6 lg:pl-8"
355+ ` ` `
356+
357+ **Benefits:**
358+ - Cleaner, more maintainable CSS
359+ - Eliminates potential conflicts from duplicate declarations
360+ - Consistent responsive padding across all table components
361+ - Smaller CSS bundle size
362+
363+ ### Fix Client Table Column Positioning
364+
365+ Fixed layout issue where Projects column had excessive spacing from Name column.
366+
367+ **File:** ` resources/ js/ Components/ Common/ Client/ ClientTableRow .vue `
368+
369+ **Problem:** Projects column had excessive padding pushing it away from Name column.
370+
371+ **Fixed styling:**
372+ ` ` ` vue
373+ - class = " whitespace-nowrap flex items-center space-x-5 3xl:pl-12 py-4 pr-3 text-sm font-medium text-text-primary pl-4 sm:pl-6 lg:pl-8 3xl:pl-12"
374+ + class = " whitespace-nowrap py-4 pr-3 text-sm font-medium text-text-primary pl-4 sm:pl-6 lg:pl-8 3xl:pl-12"
375+
376+ - class = " whitespace-nowrap flex items-center space-x-5 3xl:pl-12 py-4 pr-3 text-sm font-medium text-text-primary pl-4 sm:pl-6 lg:pl-8 3xl:pl-12"
377+ + class = " whitespace-nowrap px-3 py-4 text-sm text-text-secondary"
378+ ` ` `
379+
380+ **Result:** Projects column now appears directly next to Name column with proper spacing.
381+
382+ ### Restore Weekly Project Overview API Query
383+
384+ Fixed issue where removing ProjectsChartCard accidentally broke other dashboard functionality.
385+
386+ **File:** ` resources/ js/ Components/ Dashboard/ ThisWeekOverview .vue `
387+
388+ **Problem:** When removing the ProjectsChartCard component, the ` weeklyProjectOverview` API query was also removed, which might be used by other parts of the dashboard.
389+
390+ **Fixed by restoring API query:**
391+ ` ` ` js
392+ // Set up the queries
393+ const { data: weeklyProjectOverview } = useQuery ({
394+ queryKey: [' weeklyProjectOverview' , organizationId],
395+ queryFn : () => {
396+ return api .weeklyProjectOverview ({
397+ params: {
398+ organization: organizationId .value ! ,
399+ },
400+ });
401+ },
402+ enabled: computed (() => !! organizationId .value ),
403+ });
404+ ` ` `
405+
406+ **Result:** Dashboard data should now load properly without the ProjectsChartCard component being displayed.
407+
408+ ### Add Search/Filter Functionality to Projects and Clients Pages
409+
410+ Added real-time search functionality with wildcard matching to improve user experience.
411+
412+ #### Projects Page Search
413+
414+ **File:** ` resources/ js/ Pages/ Projects .vue `
415+
416+ **Added imports:**
417+ ` ` ` js
418+ import { MagnifyingGlassIcon } from ' @heroicons/vue/20/solid' ;
419+ ` ` `
420+
421+ **Added search state:**
422+ ` ` ` js
423+ const searchQuery = ref (' ' );
424+ ` ` `
425+
426+ **Updated filtering logic:**
427+ ` ` ` js
428+ const shownProjects = computed (() => {
429+ let filteredProjects = projects .value .filter ((project ) => {
430+ if (activeTab .value === ' active' ) {
431+ return ! project .is_archived ;
432+ }
433+ return project .is_archived ;
434+ });
435+
436+ // Apply search filter
437+ if (searchQuery .value .trim ()) {
438+ const query = searchQuery .value .toLowerCase ().trim ();
439+ filteredProjects = filteredProjects .filter ((project ) => {
440+ // Search in project name
441+ const projectNameMatch = project .name .toLowerCase ().includes (query);
442+
443+ // Search in client name
444+ const client = clients .value .find (client => client .id === project .client_id );
445+ const clientNameMatch = client? .name .toLowerCase ().includes (query) || false ;
446+
447+ return projectNameMatch || clientNameMatch;
448+ });
449+ }
450+
451+ return filteredProjects;
452+ });
453+ ` ` `
454+
455+ **Added search input UI:**
456+ ` ` ` vue
457+ < div class = " flex items-center space-x-3" >
458+ < div class = " relative" >
459+ < div class = " absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" >
460+ < MagnifyingGlassIcon class = " h-5 w-5 text-text-secondary" / >
461+ < / div>
462+ < input
463+ v- model= " searchQuery"
464+ type= " text"
465+ placeholder= " Search projects or clients..."
466+ class = " block w-64 pl-10 pr-3 py-2 border border-input-border rounded-md leading-5 bg-input-background text-text-primary placeholder-text-secondary focus:outline-none focus:ring-1 focus:ring-accent-500 focus:border-accent-500 sm:text-sm"
467+ / >
468+ < / div>
469+ < SecondaryButton> Create Project< / SecondaryButton>
470+ < / div>
471+ ` ` `
472+
473+ #### Clients Page Search
474+
475+ **File:** ` resources/ js/ Pages/ Clients .vue `
476+
477+ **Added imports:**
478+ ` ` ` js
479+ import { MagnifyingGlassIcon } from ' @heroicons/vue/20/solid' ;
480+ ` ` `
481+
482+ **Added search state:**
483+ ` ` ` js
484+ const searchQuery = ref (' ' );
485+ ` ` `
486+
487+ **Updated filtering logic:**
488+ ` ` ` js
489+ const shownClients = computed (() => {
490+ let filteredClients = clients .value .filter ((client ) => {
491+ if (activeTab .value === ' active' ) {
492+ return ! client .is_archived ;
493+ }
494+ return client .is_archived ;
495+ });
496+
497+ // Apply search filter
498+ if (searchQuery .value .trim ()) {
499+ const query = searchQuery .value .toLowerCase ().trim ();
500+ filteredClients = filteredClients .filter ((client ) => {
501+ return client .name .toLowerCase ().includes (query);
502+ });
503+ }
504+
505+ return filteredClients;
506+ });
507+ ` ` `
508+
509+ **Added search input UI:**
510+ ` ` ` vue
511+ < div class = " flex items-center space-x-3" >
512+ < div class = " relative" >
513+ < div class = " absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" >
514+ < MagnifyingGlassIcon class = " h-5 w-5 text-text-secondary" / >
515+ < / div>
516+ < input
517+ v- model= " searchQuery"
518+ type= " text"
519+ placeholder= " Search clients..."
520+ class = " block w-64 pl-10 pr-3 py-2 border border-input-border rounded-md leading-5 bg-input-background text-text-primary placeholder-text-secondary focus:outline-none focus:ring-1 focus:ring-accent-500 focus:border-accent-500 sm:text-sm"
521+ / >
522+ < / div>
523+ < SecondaryButton> Create Client< / SecondaryButton>
524+ < / div>
525+ ` ` `
526+
527+ #### Features
528+
529+ - **Real-time filtering:** Results update as you type
530+ - **Wildcard search:** Substring/partial matching
531+ - **Projects page:** Searches both project names AND client names
532+ - **Clients page:** Searches client names
533+ - **Case-insensitive:** Search works regardless of capitalization
534+ - **Works with tabs:** Search applies to both Active and Archived tabs
535+ - **Clean UI:** Search input with magnifying glass icon, positioned next to action buttons
536+
247537### Remove Pull Request Template
248538
249539**File:** ` .github / PULL_REQUEST_TEMPLATE .md `
0 commit comments