@hed-hog/contact 0.0.330 → 0.0.332

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,7 @@ import {
41
41
  } from '@/components/ui/sheet';
42
42
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
43
43
  import { zodResolver } from '@hookform/resolvers/zod';
44
- import { ChevronsUpDown, Loader2, Plus, X } from 'lucide-react';
44
+ import { ChevronsUpDown, Loader2, Pencil, Plus, X } from 'lucide-react';
45
45
  import { useTranslations } from 'next-intl';
46
46
  import { useEffect, useMemo, useRef, useState } from 'react';
47
47
  import {
@@ -60,6 +60,10 @@ type PersonOption = {
60
60
  avatar_id?: number | null;
61
61
  };
62
62
 
63
+ type PersonOptionApi = PersonOption & {
64
+ avatar_id?: number | null;
65
+ };
66
+
63
67
  type CreatePersonValues = {
64
68
  name: string;
65
69
  type: 'individual' | 'company';
@@ -563,6 +567,8 @@ export function PersonPicker({
563
567
  entityLabel,
564
568
  value,
565
569
  onChange,
570
+ onEditSelection,
571
+ onCreateNew,
566
572
  selectPlaceholder,
567
573
  personTypeFilter = 'all',
568
574
  createType = 'individual',
@@ -570,11 +576,15 @@ export function PersonPicker({
570
576
  initialSelectedLabel = '',
571
577
  disabled = false,
572
578
  clearable = true,
579
+ showEditButton = false,
580
+ editAriaLabel,
573
581
  }: {
574
582
  label: string;
575
583
  entityLabel: string;
576
584
  value?: string | number | null;
577
585
  onChange: (personId: number | null, personName: string) => void;
586
+ onEditSelection?: (personId: number) => void;
587
+ onCreateNew?: (initialName?: string) => void;
578
588
  selectPlaceholder: string;
579
589
  personTypeFilter?: PersonTypeFilter;
580
590
  createType?: Exclude<PersonTypeFilter, 'all'>;
@@ -582,6 +592,8 @@ export function PersonPicker({
582
592
  initialSelectedLabel?: string;
583
593
  disabled?: boolean;
584
594
  clearable?: boolean;
595
+ showEditButton?: boolean;
596
+ editAriaLabel?: string;
585
597
  }) {
586
598
  const { request } = useApp();
587
599
  const t = usePersonPickerTranslations();
@@ -685,9 +697,11 @@ export function PersonPicker({
685
697
  }
686
698
 
687
699
  if (payload && 'data' in payload && Array.isArray(payload.data)) {
688
- return payload.data.map((p) => ({
700
+ const options = payload.data as PersonOptionApi[];
701
+
702
+ return options.map((p) => ({
689
703
  ...p,
690
- avatarId: (p as any).avatar_id ?? p.avatarId ?? null,
704
+ avatarId: p.avatar_id ?? p.avatarId ?? null,
691
705
  })) as PersonOption[];
692
706
  }
693
707
 
@@ -701,6 +715,9 @@ export function PersonPicker({
701
715
  ? String(value)
702
716
  : '';
703
717
  const hasValue = normalizedValue.length > 0;
718
+ const selectedPersonId = hasValue ? Number(normalizedValue) : Number.NaN;
719
+ const canEditSelection =
720
+ Number.isFinite(selectedPersonId) && selectedPersonId > 0;
704
721
 
705
722
  const selectedPersonFromList = personOptionsData.find(
706
723
  (p) => String(p.id) === normalizedValue
@@ -750,7 +767,7 @@ export function PersonPicker({
750
767
  <div className="grid min-w-0 gap-2">
751
768
  {label ? <Label>{label}</Label> : null}
752
769
 
753
- <div className="grid min-w-0 grid-cols-[minmax(0,1fr)_auto] gap-2 sm:grid-cols-[minmax(0,1fr)_auto_auto]">
770
+ <div className="grid min-w-0 grid-cols-[minmax(0,1fr)_auto] gap-2 sm:grid-cols-[minmax(0,1fr)_auto_auto_auto]">
754
771
  <Popover
755
772
  open={!disabled && personOpen}
756
773
  onOpenChange={(open) => {
@@ -816,10 +833,15 @@ export function PersonPicker({
816
833
  personOptionsData.length === 0
817
834
  ) {
818
835
  e.preventDefault();
819
- openCreateWithPrefill(
820
- e.currentTarget,
821
- personSearch.trim()
822
- );
836
+ if (onCreateNew) {
837
+ setPersonOpen(false);
838
+ onCreateNew(personSearch.trim());
839
+ } else {
840
+ openCreateWithPrefill(
841
+ e.currentTarget,
842
+ personSearch.trim()
843
+ );
844
+ }
823
845
  }
824
846
  }}
825
847
  />
@@ -837,10 +859,15 @@ export function PersonPicker({
837
859
  variant="outline"
838
860
  className="w-full"
839
861
  onClick={(event) => {
840
- openCreateWithPrefill(
841
- event.currentTarget,
842
- personSearch.trim()
843
- );
862
+ if (onCreateNew) {
863
+ setPersonOpen(false);
864
+ onCreateNew(personSearch.trim());
865
+ } else {
866
+ openCreateWithPrefill(
867
+ event.currentTarget,
868
+ personSearch.trim()
869
+ );
870
+ }
844
871
  }}
845
872
  >
846
873
  {t('actions.createNew')}
@@ -914,6 +941,27 @@ export function PersonPicker({
914
941
  </Button>
915
942
  ) : null}
916
943
 
944
+ {showEditButton ? (
945
+ <Button
946
+ type="button"
947
+ variant="outline"
948
+ size="icon"
949
+ className="shrink-0"
950
+ disabled={disabled || !canEditSelection}
951
+ onClick={() => {
952
+ if (!canEditSelection || !onEditSelection) {
953
+ return;
954
+ }
955
+ onEditSelection(selectedPersonId);
956
+ }}
957
+ aria-label={
958
+ editAriaLabel ?? t('actions.createEntityAria', { entityLabel })
959
+ }
960
+ >
961
+ <Pencil className="h-4 w-4" />
962
+ </Button>
963
+ ) : null}
964
+
917
965
  <Button
918
966
  type="button"
919
967
  variant="outline"
@@ -921,9 +969,14 @@ export function PersonPicker({
921
969
  className="shrink-0"
922
970
  disabled={disabled}
923
971
  onClick={(event) => {
924
- captureParentScrollPosition(event.currentTarget);
925
- setPersonOpen(false);
926
- setCreatePersonOpen(true);
972
+ if (onCreateNew) {
973
+ setPersonOpen(false);
974
+ onCreateNew(personSearch.trim());
975
+ } else {
976
+ captureParentScrollPosition(event.currentTarget);
977
+ setPersonOpen(false);
978
+ setCreatePersonOpen(true);
979
+ }
927
980
  }}
928
981
  aria-label={t('actions.createEntityAria', { entityLabel })}
929
982
  >
@@ -801,7 +801,7 @@ export default function AccountsPage() {
801
801
  <Page>
802
802
  <PageHeader
803
803
  breadcrumbs={[
804
- { label: 'Home', href: '/' },
804
+ { label: crmT('breadcrumbs.home'), href: '/' },
805
805
  { label: crmT('breadcrumbs.crm'), href: '/contact/dashboard' },
806
806
  { label: t('title') },
807
807
  ]}
@@ -311,7 +311,7 @@ export default function CrmActivitiesPage() {
311
311
  <Page>
312
312
  <PageHeader
313
313
  breadcrumbs={[
314
- { label: 'Home', href: '/' },
314
+ { label: crmT('breadcrumbs.home'), href: '/' },
315
315
  { label: crmT('breadcrumbs.crm'), href: '/contact/dashboard' },
316
316
  { label: t('title') },
317
317
  ]}
@@ -619,7 +619,7 @@ export default function CrmFollowupsPage() {
619
619
  <Page>
620
620
  <PageHeader
621
621
  breadcrumbs={[
622
- { label: 'Home', href: '/' },
622
+ { label: crmT('breadcrumbs.home'), href: '/' },
623
623
  { label: crmT('breadcrumbs.crm'), href: '/contact/dashboard' },
624
624
  { label: t('title') },
625
625
  ]}
@@ -1146,6 +1146,11 @@ export function PersonFormSheet({
1146
1146
  ? `${process.env.NEXT_PUBLIC_API_BASE_URL}/person/avatar/${fileId}`
1147
1147
  : '/placeholder.png';
1148
1148
 
1149
+ const getUserPhotoUrl = (photoId?: number | null) =>
1150
+ typeof photoId === 'number' && photoId > 0
1151
+ ? `${process.env.NEXT_PUBLIC_API_BASE_URL}/user/avatar/${photoId}`
1152
+ : undefined;
1153
+
1149
1154
  const resolveApiUrl = (url: string) =>
1150
1155
  /^https?:\/\//i.test(url)
1151
1156
  ? url
@@ -2508,6 +2513,15 @@ export function PersonFormSheet({
2508
2513
  '')
2509
2514
  : ''
2510
2515
  );
2516
+ const userPhotoId = (
2517
+ opt as { photo_id?: number | null } | null
2518
+ )?.photo_id;
2519
+ if (val != null && userPhotoId && !avatarId) {
2520
+ setAvatarId(userPhotoId);
2521
+ setAvatarPreviewUrl(
2522
+ getUserPhotoUrl(userPhotoId) ?? '/placeholder.png'
2523
+ );
2524
+ }
2511
2525
  }}
2512
2526
  placeholder={t('selectLinkedUser')}
2513
2527
  entityLabel={t('user')}
@@ -2518,7 +2532,12 @@ export function PersonFormSheet({
2518
2532
  const params = new URLSearchParams();
2519
2533
  if (search) params.set('search', search);
2520
2534
  const response = await request<
2521
- Array<{ id: number; name: string; email?: string }>
2535
+ Array<{
2536
+ id: number;
2537
+ name: string;
2538
+ email?: string;
2539
+ photo_id?: number | null;
2540
+ }>
2522
2541
  >({
2523
2542
  url: `/person/linked-user-options?${params.toString()}`,
2524
2543
  method: 'GET',
@@ -791,7 +791,7 @@ export default function PeoplePage() {
791
791
  <Page>
792
792
  <PageHeader
793
793
  breadcrumbs={[
794
- { label: 'Home', href: '/' },
794
+ { label: crmT('breadcrumbs.home'), href: '/' },
795
795
  { label: crmT('breadcrumbs.crm'), href: '/contact/dashboard' },
796
796
  {
797
797
  label: allowCompanyRegistration
@@ -1,50 +1,50 @@
1
1
  'use client';
2
2
 
3
3
  import {
4
- EmptyState,
5
- Page,
6
- PageHeader,
7
- PaginationFooter,
8
- SearchBar,
9
- type SearchBarControl,
4
+ EmptyState,
5
+ Page,
6
+ PageHeader,
7
+ PaginationFooter,
8
+ SearchBar,
9
+ type SearchBarControl,
10
10
  } from '@/components/entity-list';
11
+ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
11
12
  import { Badge } from '@/components/ui/badge';
12
13
  import { Button } from '@/components/ui/button';
13
14
  import { Card, CardContent } from '@/components/ui/card';
14
15
  import {
15
- DropdownMenu,
16
- DropdownMenuContent,
17
- DropdownMenuItem,
18
- DropdownMenuSeparator,
19
- DropdownMenuTrigger,
16
+ DropdownMenu,
17
+ DropdownMenuContent,
18
+ DropdownMenuItem,
19
+ DropdownMenuSeparator,
20
+ DropdownMenuTrigger,
20
21
  } from '@/components/ui/dropdown-menu';
21
- import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
22
22
  import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
23
23
  import { Skeleton } from '@/components/ui/skeleton';
24
24
  import {
25
- Table,
26
- TableBody,
27
- TableCell,
28
- TableHead,
29
- TableHeader,
30
- TableRow,
25
+ Table,
26
+ TableBody,
27
+ TableCell,
28
+ TableHead,
29
+ TableHeader,
30
+ TableRow,
31
31
  } from '@/components/ui/table';
32
32
  import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
33
33
  import { cn } from '@/lib/utils';
34
34
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
35
35
  import {
36
- CheckCircle2,
37
- Clock3,
38
- FileCheck2,
39
- FileText,
40
- LayoutGrid,
41
- List,
42
- Loader2,
43
- MoreHorizontal,
44
- Pencil,
45
- RefreshCcw,
46
- Send,
47
- XCircle,
36
+ CheckCircle2,
37
+ Clock3,
38
+ FileCheck2,
39
+ FileText,
40
+ LayoutGrid,
41
+ List,
42
+ Loader2,
43
+ MoreHorizontal,
44
+ Pencil,
45
+ RefreshCcw,
46
+ Send,
47
+ XCircle,
48
48
  } from 'lucide-react';
49
49
  import { useTranslations } from 'next-intl';
50
50
  import { useEffect, useMemo, useState } from 'react';
@@ -53,8 +53,8 @@ import { toast } from 'sonner';
53
53
  import type { PaginatedResult } from '../../person/_components/person-types';
54
54
  import { ProposalFormSheet } from './proposal-form-sheet';
55
55
  import {
56
- openStoredFile,
57
- type GenerateProposalDocumentResponse,
56
+ openStoredFile,
57
+ type GenerateProposalDocumentResponse,
58
58
  } from './proposal-types';
59
59
 
60
60
  type ProposalStatus =
@@ -161,7 +161,9 @@ function getAvatarInitials(name?: string | null) {
161
161
  if (!name) return '?';
162
162
  const parts = name.trim().split(/\s+/);
163
163
  if (parts.length === 1) return (parts[0] ?? '').slice(0, 2).toUpperCase();
164
- return ((parts[0]?.[0] ?? '') + (parts[parts.length - 1]?.[0] ?? '')).toUpperCase();
164
+ return (
165
+ (parts[0]?.[0] ?? '') + (parts[parts.length - 1]?.[0] ?? '')
166
+ ).toUpperCase();
165
167
  }
166
168
 
167
169
  function canSubmitProposal(status?: ProposalStatus | null) {
@@ -199,7 +201,9 @@ export function ProposalsManagementPage({
199
201
  const [viewMode, setViewMode] = useState<ProposalViewMode>('table');
200
202
  const [actionKey, setActionKey] = useState<string | null>(null);
201
203
  const [editSheetOpen, setEditSheetOpen] = useState(false);
202
- const [editingProposalId, setEditingProposalId] = useState<number | null>(null);
204
+ const [editingProposalId, setEditingProposalId] = useState<number | null>(
205
+ null
206
+ );
203
207
  const [editingPersonId, setEditingPersonId] = useState<number | null>(null);
204
208
 
205
209
  useEffect(() => {
@@ -452,7 +456,7 @@ export function ProposalsManagementPage({
452
456
  <Page>
453
457
  <PageHeader
454
458
  breadcrumbs={[
455
- { label: 'Home', href: '/' },
459
+ { label: crmT('breadcrumbs.home'), href: '/' },
456
460
  { label: crmT('breadcrumbs.crm'), href: '/contact/dashboard' },
457
461
  { label: pageTitle },
458
462
  ]}
@@ -615,7 +619,9 @@ export function ProposalsManagementPage({
615
619
  <TableCell>
616
620
  <div className="flex items-center gap-3">
617
621
  <Avatar className="h-8 w-8 shrink-0">
618
- <AvatarImage src={getPersonAvatarUrl(proposal.person?.avatar_id)} />
622
+ <AvatarImage
623
+ src={getPersonAvatarUrl(proposal.person?.avatar_id)}
624
+ />
619
625
  <AvatarFallback className="bg-primary/10 text-[11px] font-semibold text-primary">
620
626
  {getAvatarInitials(customerName)}
621
627
  </AvatarFallback>
@@ -671,66 +677,101 @@ export function ProposalsManagementPage({
671
677
  </TableCell>
672
678
 
673
679
  <TableCell className="text-right">
674
- <DropdownMenu>
675
- <DropdownMenuTrigger asChild>
676
- <Button variant="ghost" size="icon" className="h-8 w-8">
677
- {actionKey?.startsWith(`${proposal.id}-`) || actionKey === `generate-pdf-${proposal.id}` || actionKey === `submit-${proposal.id}` || actionKey === `approve-${proposal.id}` || actionKey === `reject-${proposal.id}` ? (
678
- <Loader2 className="h-4 w-4 animate-spin" />
679
- ) : (
680
- <MoreHorizontal className="h-4 w-4" />
681
- )}
680
+ <div className="flex items-center justify-end gap-2">
681
+ {canEditProposal(proposal.status) ? (
682
+ <Button
683
+ variant="outline"
684
+ size="sm"
685
+ className="gap-1.5"
686
+ onClick={() => handleEdit(proposal)}
687
+ >
688
+ <Pencil className="h-3.5 w-3.5" />
689
+ {proposalT('actions.edit')}
682
690
  </Button>
683
- </DropdownMenuTrigger>
684
- <DropdownMenuContent align="end">
685
- {canEditProposal(proposal.status) ? (
686
- <DropdownMenuItem onClick={() => handleEdit(proposal)}>
687
- <Pencil className="mr-2 h-4 w-4" />
688
- {proposalT('actions.edit')}
689
- </DropdownMenuItem>
690
- ) : null}
691
-
692
- {canSubmitProposal(proposal.status) ? (
693
- <DropdownMenuItem
694
- disabled={actionKey === `submit-${proposal.id}`}
695
- onClick={() => void handleStatusAction(proposal, 'submit')}
691
+ ) : null}
692
+ <DropdownMenu>
693
+ <DropdownMenuTrigger asChild>
694
+ <Button
695
+ variant="ghost"
696
+ size="icon"
697
+ className="h-8 w-8"
696
698
  >
697
- <Send className="mr-2 h-4 w-4" />
698
- {proposalT('actions.submit')}
699
- </DropdownMenuItem>
700
- ) : null}
701
-
702
- {proposal.status === 'pending_approval' &&
703
- !proposal.current_user_has_approved ? (
704
- <>
699
+ {actionKey?.startsWith(`${proposal.id}-`) ||
700
+ actionKey === `generate-pdf-${proposal.id}` ||
701
+ actionKey === `submit-${proposal.id}` ||
702
+ actionKey === `approve-${proposal.id}` ||
703
+ actionKey === `reject-${proposal.id}` ? (
704
+ <Loader2 className="h-4 w-4 animate-spin" />
705
+ ) : (
706
+ <MoreHorizontal className="h-4 w-4" />
707
+ )}
708
+ </Button>
709
+ </DropdownMenuTrigger>
710
+ <DropdownMenuContent align="end">
711
+ {canEditProposal(proposal.status) ? (
705
712
  <DropdownMenuItem
706
- disabled={actionKey === `approve-${proposal.id}`}
707
- onClick={() => void handleStatusAction(proposal, 'approve')}
713
+ onClick={() => handleEdit(proposal)}
708
714
  >
709
- <CheckCircle2 className="mr-2 h-4 w-4" />
710
- {proposalT('actions.approve')}
715
+ <Pencil className="mr-2 h-4 w-4" />
716
+ {proposalT('actions.edit')}
711
717
  </DropdownMenuItem>
718
+ ) : null}
719
+
720
+ {canSubmitProposal(proposal.status) ? (
712
721
  <DropdownMenuItem
713
- disabled={actionKey === `reject-${proposal.id}`}
714
- className="text-destructive focus:text-destructive"
715
- onClick={() => void handleStatusAction(proposal, 'reject')}
722
+ disabled={actionKey === `submit-${proposal.id}`}
723
+ onClick={() =>
724
+ void handleStatusAction(proposal, 'submit')
725
+ }
716
726
  >
717
- <XCircle className="mr-2 h-4 w-4" />
718
- {proposalT('actions.reject')}
727
+ <Send className="mr-2 h-4 w-4" />
728
+ {proposalT('actions.submit')}
719
729
  </DropdownMenuItem>
720
- </>
721
- ) : null}
722
-
723
- <DropdownMenuSeparator />
730
+ ) : null}
731
+
732
+ {proposal.status === 'pending_approval' &&
733
+ !proposal.current_user_has_approved ? (
734
+ <>
735
+ <DropdownMenuItem
736
+ disabled={
737
+ actionKey === `approve-${proposal.id}`
738
+ }
739
+ onClick={() =>
740
+ void handleStatusAction(proposal, 'approve')
741
+ }
742
+ >
743
+ <CheckCircle2 className="mr-2 h-4 w-4" />
744
+ {proposalT('actions.approve')}
745
+ </DropdownMenuItem>
746
+ <DropdownMenuItem
747
+ disabled={
748
+ actionKey === `reject-${proposal.id}`
749
+ }
750
+ className="text-destructive focus:text-destructive"
751
+ onClick={() =>
752
+ void handleStatusAction(proposal, 'reject')
753
+ }
754
+ >
755
+ <XCircle className="mr-2 h-4 w-4" />
756
+ {proposalT('actions.reject')}
757
+ </DropdownMenuItem>
758
+ </>
759
+ ) : null}
760
+
761
+ <DropdownMenuSeparator />
724
762
 
725
- <DropdownMenuItem
726
- disabled={actionKey === `generate-pdf-${proposal.id}`}
727
- onClick={() => void handleGeneratePdf(proposal)}
728
- >
729
- <FileText className="mr-2 h-4 w-4" />
730
- {proposalT('actions.generatePdf')}
731
- </DropdownMenuItem>
732
- </DropdownMenuContent>
733
- </DropdownMenu>
763
+ <DropdownMenuItem
764
+ disabled={
765
+ actionKey === `generate-pdf-${proposal.id}`
766
+ }
767
+ onClick={() => void handleGeneratePdf(proposal)}
768
+ >
769
+ <FileText className="mr-2 h-4 w-4" />
770
+ {proposalT('actions.generatePdf')}
771
+ </DropdownMenuItem>
772
+ </DropdownMenuContent>
773
+ </DropdownMenu>
774
+ </div>
734
775
  </TableCell>
735
776
  </TableRow>
736
777
  );
@@ -755,11 +796,13 @@ export function ProposalsManagementPage({
755
796
  <div className="flex items-start justify-between gap-3">
756
797
  <div className="flex min-w-0 items-start gap-2.5">
757
798
  <Avatar className="mt-0.5 h-8 w-8 shrink-0">
758
- <AvatarImage src={getPersonAvatarUrl(proposal.person?.avatar_id)} />
759
- <AvatarFallback className="bg-primary/10 text-[11px] font-semibold text-primary">
760
- {getAvatarInitials(customerName)}
761
- </AvatarFallback>
762
- </Avatar>
799
+ <AvatarImage
800
+ src={getPersonAvatarUrl(proposal.person?.avatar_id)}
801
+ />
802
+ <AvatarFallback className="bg-primary/10 text-[11px] font-semibold text-primary">
803
+ {getAvatarInitials(customerName)}
804
+ </AvatarFallback>
805
+ </Avatar>
763
806
  <div className="min-w-0 space-y-1">
764
807
  <p className="line-clamp-2 text-sm font-semibold text-foreground">
765
808
  {proposal.title}
@@ -824,11 +867,25 @@ export function ProposalsManagementPage({
824
867
  </div>
825
868
  </div>
826
869
 
827
- <div className="mt-auto flex justify-end">
870
+ <div className="mt-auto flex justify-end gap-2">
871
+ {canEditProposal(proposal.status) ? (
872
+ <Button
873
+ variant="outline"
874
+ size="sm"
875
+ className="gap-1.5"
876
+ onClick={() => handleEdit(proposal)}
877
+ >
878
+ <Pencil className="h-3.5 w-3.5" />
879
+ {proposalT('actions.edit')}
880
+ </Button>
881
+ ) : null}
828
882
  <DropdownMenu>
829
883
  <DropdownMenuTrigger asChild>
830
884
  <Button variant="outline" size="sm" className="gap-1.5">
831
- {actionKey === `generate-pdf-${proposal.id}` || actionKey === `submit-${proposal.id}` || actionKey === `approve-${proposal.id}` || actionKey === `reject-${proposal.id}` ? (
885
+ {actionKey === `generate-pdf-${proposal.id}` ||
886
+ actionKey === `submit-${proposal.id}` ||
887
+ actionKey === `approve-${proposal.id}` ||
888
+ actionKey === `reject-${proposal.id}` ? (
832
889
  <Loader2 className="h-3.5 w-3.5 animate-spin" />
833
890
  ) : (
834
891
  <MoreHorizontal className="h-3.5 w-3.5" />
@@ -838,7 +895,9 @@ export function ProposalsManagementPage({
838
895
  </DropdownMenuTrigger>
839
896
  <DropdownMenuContent align="end">
840
897
  {canEditProposal(proposal.status) ? (
841
- <DropdownMenuItem onClick={() => handleEdit(proposal)}>
898
+ <DropdownMenuItem
899
+ onClick={() => handleEdit(proposal)}
900
+ >
842
901
  <Pencil className="mr-2 h-4 w-4" />
843
902
  {proposalT('actions.edit')}
844
903
  </DropdownMenuItem>
@@ -847,7 +906,9 @@ export function ProposalsManagementPage({
847
906
  {canSubmitProposal(proposal.status) ? (
848
907
  <DropdownMenuItem
849
908
  disabled={actionKey === `submit-${proposal.id}`}
850
- onClick={() => void handleStatusAction(proposal, 'submit')}
909
+ onClick={() =>
910
+ void handleStatusAction(proposal, 'submit')
911
+ }
851
912
  >
852
913
  <Send className="mr-2 h-4 w-4" />
853
914
  {proposalT('actions.submit')}
@@ -859,7 +920,9 @@ export function ProposalsManagementPage({
859
920
  <>
860
921
  <DropdownMenuItem
861
922
  disabled={actionKey === `approve-${proposal.id}`}
862
- onClick={() => void handleStatusAction(proposal, 'approve')}
923
+ onClick={() =>
924
+ void handleStatusAction(proposal, 'approve')
925
+ }
863
926
  >
864
927
  <CheckCircle2 className="mr-2 h-4 w-4" />
865
928
  {proposalT('actions.approve')}
@@ -867,7 +930,9 @@ export function ProposalsManagementPage({
867
930
  <DropdownMenuItem
868
931
  disabled={actionKey === `reject-${proposal.id}`}
869
932
  className="text-destructive focus:text-destructive"
870
- onClick={() => void handleStatusAction(proposal, 'reject')}
933
+ onClick={() =>
934
+ void handleStatusAction(proposal, 'reject')
935
+ }
871
936
  >
872
937
  <XCircle className="mr-2 h-4 w-4" />
873
938
  {proposalT('actions.reject')}
@@ -501,6 +501,7 @@
501
501
  },
502
502
  "CrmMenu": {
503
503
  "breadcrumbs": {
504
+ "home": "Home",
504
505
  "crm": "CRM"
505
506
  },
506
507
  "current": "Current",
@@ -500,6 +500,7 @@
500
500
  },
501
501
  "CrmMenu": {
502
502
  "breadcrumbs": {
503
+ "home": "Home",
503
504
  "crm": "CRM"
504
505
  },
505
506
  "current": "Atual",