@trackany-device/components 1.1.0 → 1.2.0

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.
Files changed (159) hide show
  1. package/README.md +9 -9
  2. package/package.json +133 -4
  3. package/src/assets/index.ts +120 -0
  4. package/src/assets/media/avatars/300-1.png +0 -0
  5. package/src/assets/media/avatars/300-10.png +0 -0
  6. package/src/assets/media/avatars/300-11.png +0 -0
  7. package/src/assets/media/avatars/300-12.png +0 -0
  8. package/src/assets/media/avatars/300-13.png +0 -0
  9. package/src/assets/media/avatars/300-14.png +0 -0
  10. package/src/assets/media/avatars/300-15.png +0 -0
  11. package/src/assets/media/avatars/300-16.png +0 -0
  12. package/src/assets/media/avatars/300-17.png +0 -0
  13. package/src/assets/media/avatars/300-18.png +0 -0
  14. package/src/assets/media/avatars/300-19.png +0 -0
  15. package/src/assets/media/avatars/300-2.png +0 -0
  16. package/src/assets/media/avatars/300-20.png +0 -0
  17. package/src/assets/media/avatars/300-21.png +0 -0
  18. package/src/assets/media/avatars/300-22.png +0 -0
  19. package/src/assets/media/avatars/300-23.png +0 -0
  20. package/src/assets/media/avatars/300-24.png +0 -0
  21. package/src/assets/media/avatars/300-25.png +0 -0
  22. package/src/assets/media/avatars/300-26.png +0 -0
  23. package/src/assets/media/avatars/300-27.png +0 -0
  24. package/src/assets/media/avatars/300-28.png +0 -0
  25. package/src/assets/media/avatars/300-29.png +0 -0
  26. package/src/assets/media/avatars/300-3.png +0 -0
  27. package/src/assets/media/avatars/300-30.png +0 -0
  28. package/src/assets/media/avatars/300-31.png +0 -0
  29. package/src/assets/media/avatars/300-32.png +0 -0
  30. package/src/assets/media/avatars/300-33.png +0 -0
  31. package/src/assets/media/avatars/300-34.png +0 -0
  32. package/src/assets/media/avatars/300-4.png +0 -0
  33. package/src/assets/media/avatars/300-5.png +0 -0
  34. package/src/assets/media/avatars/300-6.png +0 -0
  35. package/src/assets/media/avatars/300-7.png +0 -0
  36. package/src/assets/media/avatars/300-8.png +0 -0
  37. package/src/assets/media/avatars/300-9.png +0 -0
  38. package/src/assets/media/avatars/blank.png +0 -0
  39. package/src/assets/media/avatars/gray/1.png +0 -0
  40. package/src/assets/media/avatars/gray/2.png +0 -0
  41. package/src/assets/media/avatars/gray/3.png +0 -0
  42. package/src/assets/media/avatars/gray/4.png +0 -0
  43. package/src/assets/media/avatars/gray/5.png +0 -0
  44. package/src/assets/media/illustrations/1-dark.svg +78 -0
  45. package/src/assets/media/illustrations/1.svg +78 -0
  46. package/src/assets/media/illustrations/10-dark.svg +148 -0
  47. package/src/assets/media/illustrations/10.svg +148 -0
  48. package/src/assets/media/illustrations/11-dark.svg +234 -0
  49. package/src/assets/media/illustrations/11.svg +234 -0
  50. package/src/assets/media/illustrations/12.svg +138 -0
  51. package/src/assets/media/illustrations/13.svg +205 -0
  52. package/src/assets/media/illustrations/14.svg +259 -0
  53. package/src/assets/media/illustrations/15.svg +242 -0
  54. package/src/assets/media/illustrations/16.svg +128 -0
  55. package/src/assets/media/illustrations/17.svg +180 -0
  56. package/src/assets/media/illustrations/18-dark.svg +6 -0
  57. package/src/assets/media/illustrations/18.svg +6 -0
  58. package/src/assets/media/illustrations/19-dark.svg +8 -0
  59. package/src/assets/media/illustrations/19.svg +8 -0
  60. package/src/assets/media/illustrations/2-dark.svg +78 -0
  61. package/src/assets/media/illustrations/2.svg +78 -0
  62. package/src/assets/media/illustrations/20-dark.svg +13 -0
  63. package/src/assets/media/illustrations/20.svg +13 -0
  64. package/src/assets/media/illustrations/21-dark.svg +9 -0
  65. package/src/assets/media/illustrations/21.svg +9 -0
  66. package/src/assets/media/illustrations/22-dark.svg +17 -0
  67. package/src/assets/media/illustrations/22.svg +17 -0
  68. package/src/assets/media/illustrations/23-dark.svg +13 -0
  69. package/src/assets/media/illustrations/23.svg +13 -0
  70. package/src/assets/media/illustrations/24.svg +6 -0
  71. package/src/assets/media/illustrations/25.svg +8 -0
  72. package/src/assets/media/illustrations/26.svg +8 -0
  73. package/src/assets/media/illustrations/27.svg +6 -0
  74. package/src/assets/media/illustrations/28-dark.svg +28 -0
  75. package/src/assets/media/illustrations/28.svg +14 -0
  76. package/src/assets/media/illustrations/29-dark.svg +6 -0
  77. package/src/assets/media/illustrations/29.svg +6 -0
  78. package/src/assets/media/illustrations/3-dark.svg +70 -0
  79. package/src/assets/media/illustrations/3.svg +70 -0
  80. package/src/assets/media/illustrations/30-dark.svg +8 -0
  81. package/src/assets/media/illustrations/30.svg +8 -0
  82. package/src/assets/media/illustrations/31-dark.svg +9 -0
  83. package/src/assets/media/illustrations/31.svg +9 -0
  84. package/src/assets/media/illustrations/32-dark.svg +10 -0
  85. package/src/assets/media/illustrations/32.svg +10 -0
  86. package/src/assets/media/illustrations/33-dark.svg +15 -0
  87. package/src/assets/media/illustrations/33.svg +15 -0
  88. package/src/assets/media/illustrations/34-dark.svg +5 -0
  89. package/src/assets/media/illustrations/34.svg +5 -0
  90. package/src/assets/media/illustrations/35-dark.svg +11 -0
  91. package/src/assets/media/illustrations/35.svg +4 -0
  92. package/src/assets/media/illustrations/4-dark.svg +51 -0
  93. package/src/assets/media/illustrations/4.svg +51 -0
  94. package/src/assets/media/illustrations/5-dark.svg +78 -0
  95. package/src/assets/media/illustrations/5.svg +78 -0
  96. package/src/assets/media/illustrations/6.svg +58 -0
  97. package/src/assets/media/illustrations/7.svg +49 -0
  98. package/src/assets/media/illustrations/8.svg +61 -0
  99. package/src/assets/media/illustrations/9.svg +57 -0
  100. package/src/assets/media/misc/placeholder.svg +15 -0
  101. package/src/components/devices/devices-mini-map.tsx +32 -26
  102. package/src/components/devices/map-marker.tsx +98 -0
  103. package/src/components/ui/checklist-item.tsx +55 -0
  104. package/src/components/ui/plan-card.tsx +68 -0
  105. package/src/components/ui/settings-row.tsx +32 -0
  106. package/src/components/ui/settings-section.tsx +22 -0
  107. package/src/components/ui/usage-meter.tsx +35 -0
  108. package/src/index.ts +12 -1
  109. package/src/layouts/LayoutSwitcher.tsx +220 -0
  110. package/src/layouts/app/MegaMenuLayout.tsx +69 -34
  111. package/src/layouts/app/MegaMenuNavbarLayout.tsx +73 -37
  112. package/src/layouts/app/NavbarCollapsibleLayout.tsx +53 -4
  113. package/src/layouts/app/NavbarSidebarLayout.tsx +74 -29
  114. package/src/layouts/app/SidebarDualMenuLayout.tsx +48 -5
  115. package/src/layouts/app/SidebarFixedLayout.tsx +15 -10
  116. package/src/layouts/app/SidebarMinimalLayout.tsx +51 -3
  117. package/src/layouts/app/SidebarTabsLayout.tsx +48 -2
  118. package/src/layouts/app/SplitSidebarLayout.tsx +91 -43
  119. package/src/layouts/app/TopNavLayout.tsx +7 -12
  120. package/src/layouts/app/WorkspaceSidebarLayout.tsx +103 -46
  121. package/src/layouts/app/partials/Navbar.tsx +61 -10
  122. package/src/layouts/app/partials/Toolbar.tsx +1 -1
  123. package/src/layouts/auth/AuthCenteredLayout.tsx +10 -4
  124. package/src/lib/map-markers.ts +21 -3
  125. package/src/pages/login/ConfirmPasswordPage.tsx +35 -0
  126. package/src/pages/login/ForgotPasswordPage.tsx +41 -0
  127. package/src/pages/login/LoginPage.tsx +50 -0
  128. package/src/pages/login/RegisterPage.tsx +41 -0
  129. package/src/pages/login/ResetPasswordPage.tsx +35 -0
  130. package/src/pages/login/TwoFactorChallengePage.tsx +41 -0
  131. package/src/pages/login/VerifyEmailPage.tsx +31 -0
  132. package/src/pages/my/ActivityPage.tsx +160 -0
  133. package/src/pages/my/GetStartedPage.tsx +221 -0
  134. package/src/pages/my/NotificationsPage.tsx +133 -0
  135. package/src/pages/my/ProfilePage.tsx +650 -0
  136. package/src/pages/my/TenantsPage.tsx +37 -0
  137. package/src/pages/tenant/AssigneesPage.tsx +155 -0
  138. package/src/pages/tenant/BeatsPage.tsx +403 -0
  139. package/src/pages/tenant/DashboardPage.tsx +195 -0
  140. package/src/pages/tenant/GeofencePage.tsx +422 -0
  141. package/src/pages/tenant/IncidentsPage.tsx +214 -0
  142. package/src/pages/tenant/IntegrationsPage.tsx +352 -0
  143. package/src/pages/tenant/InvitePage.tsx +153 -0
  144. package/src/pages/tenant/LiveStreamPage.tsx +141 -0
  145. package/src/pages/tenant/MembersPage.tsx +414 -0
  146. package/src/pages/tenant/TenantProfilePage.tsx +701 -0
  147. package/src/platform/adapters/default.tsx +1 -1
  148. package/src/platform/types.ts +2 -0
  149. package/src/styles/components/apexcharts.css +101 -0
  150. package/src/styles/components/image-input.css +51 -0
  151. package/src/styles/components/leaflet.css +25 -0
  152. package/src/styles/components/rating.css +89 -0
  153. package/src/styles/components/scrollable.css +119 -0
  154. package/src/styles/layout.css +24 -0
  155. package/src/styles/layouts/sidebar-fixed.css +93 -138
  156. package/src/styles/themes.css +5 -5
  157. package/src/vite-env.d.ts +21 -0
  158. package/src/layouts/SettingsLayout.tsx +0 -21
  159. package/src/layouts/app-layout.tsx +0 -29
@@ -0,0 +1,153 @@
1
+ import {
2
+ Avatar, AvatarFallback,
3
+ Badge, Button,
4
+ Card, CardContent, CardFooter, CardHeader, CardTitle,
5
+ Input, Label, Select,
6
+ Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
7
+ } from '@trackany-device/components';
8
+ import { LayoutResolved } from '../../layouts/LayoutSwitcher';
9
+ import type { LayoutName } from '../../layouts/LayoutSwitcher';
10
+ import { CheckCircle2, Copy, Gift, Link2, Mail, Plus, UserPlus, XCircle } from 'lucide-react';
11
+ import { useState } from 'react';
12
+
13
+ export type InviteStatus = 'Accepted' | 'Pending' | 'Declined';
14
+
15
+ export interface SentInvite {
16
+ name: string;
17
+ email: string;
18
+ status: InviteStatus;
19
+ activity: string;
20
+ initials: string;
21
+ }
22
+
23
+ const statusStyle: Record<InviteStatus, string> = {
24
+ Accepted: 'text-green-600 border-green-200 bg-green-50',
25
+ Pending: 'text-amber-600 border-amber-200 bg-amber-50',
26
+ Declined: 'text-red-600 border-red-200 bg-red-50',
27
+ };
28
+
29
+ export function InvitePeoplePage({ layout }: { layout: LayoutName }) {
30
+ const [email, setEmail] = useState('');
31
+ const [sent, setSent] = useState(false);
32
+ return (
33
+ <LayoutResolved layout={layout} title="Invite" currentUrl="/invite">
34
+ <div className="p-6 max-w-xl mx-auto space-y-6">
35
+ <h1 className="text-xl font-semibold">Invite a team member</h1>
36
+
37
+ {sent && (
38
+ <div className="flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-4 py-2.5 text-sm text-green-700">
39
+ <CheckCircle2 className="h-4 w-4 shrink-0" />Invitation sent to <strong>{email}</strong>
40
+ </div>
41
+ )}
42
+
43
+ <Card>
44
+ <CardHeader><CardTitle>Send an invitation</CardTitle></CardHeader>
45
+ <CardContent className="space-y-4">
46
+ <div className="space-y-1.5">
47
+ <Label htmlFor="inv-email">Email address</Label>
48
+ <Input id="inv-email" type="email" placeholder="colleague@example.com" value={email} onChange={(e) => setEmail(e.target.value)} />
49
+ </div>
50
+ <div className="space-y-1.5">
51
+ <Label htmlFor="inv-role">Role</Label>
52
+ <Select id="inv-role" defaultValue="member">
53
+ <option value="member">Member</option>
54
+ <option value="operator">Operator</option>
55
+ <option value="supervisor">Supervisor</option>
56
+ <option value="admin">Admin</option>
57
+ </Select>
58
+ </div>
59
+ <Button variant="outline" size="sm" className="w-full border-dashed"><Plus className="h-3.5 w-3.5 mr-1.5" />Add another email</Button>
60
+ </CardContent>
61
+ <CardFooter className="justify-center">
62
+ <Button onClick={() => { if (email) setSent(true); }}><UserPlus className="h-4 w-4 mr-1.5" />Send invitation</Button>
63
+ </CardFooter>
64
+ </Card>
65
+
66
+ <Card>
67
+ <CardHeader><CardTitle>Invite via link</CardTitle></CardHeader>
68
+ <CardContent className="space-y-3">
69
+ <p className="text-sm text-muted-foreground">Share this link — anyone with it can join your organisation as a Member.</p>
70
+ <div className="flex gap-2">
71
+ <Input value="https://tad.io/invite/track-any-device/abc123xyz" readOnly className="text-xs font-mono" />
72
+ <Button variant="outline" size="icon"><Copy className="h-4 w-4" /></Button>
73
+ </div>
74
+ <Button variant="outline" size="sm" className="w-full"><Link2 className="h-3.5 w-3.5 mr-1.5" />Regenerate link</Button>
75
+ </CardContent>
76
+ </Card>
77
+
78
+ <Card>
79
+ <CardHeader><CardTitle>Referral rewards</CardTitle></CardHeader>
80
+ <CardContent className="space-y-3">
81
+ <div className="flex items-center gap-3 rounded-lg bg-primary/5 border border-primary/20 p-4">
82
+ <Gift className="h-8 w-8 text-primary shrink-0" />
83
+ <div>
84
+ <p className="text-sm font-semibold">Earn 1 month free</p>
85
+ <p className="text-xs text-muted-foreground mt-0.5">For every team member who joins and activates, you get 1 month free.</p>
86
+ </div>
87
+ </div>
88
+ <div className="grid grid-cols-3 gap-3 text-center">
89
+ {[{ v: '5', l: 'Invites sent' }, { v: '3', l: 'Accepted' }, { v: '2', l: 'Months earned' }].map(({ v, l }) => (
90
+ <div key={l} className="rounded-lg border border-border p-3">
91
+ <p className="text-xl font-bold text-primary">{v}</p>
92
+ <p className="text-xs text-muted-foreground mt-0.5">{l}</p>
93
+ </div>
94
+ ))}
95
+ </div>
96
+ </CardContent>
97
+ </Card>
98
+ </div>
99
+ </LayoutResolved>
100
+ );
101
+ }
102
+
103
+ export function SentInvitesPage({ layout, invites }: { layout: LayoutName; invites: SentInvite[] }) {
104
+ return (
105
+ <LayoutResolved layout={layout} title="Sent Invites" currentUrl="/invite/sent">
106
+ <div className="p-6 max-w-3xl mx-auto space-y-6">
107
+ <div className="flex items-center justify-between">
108
+ <h1 className="text-xl font-semibold">Sent invites</h1>
109
+ <Button size="sm"><Mail className="h-4 w-4 mr-1.5" />Invite members</Button>
110
+ </div>
111
+
112
+ <Card>
113
+ <CardContent className="p-0">
114
+ <Table>
115
+ <TableHeader>
116
+ <TableRow>
117
+ <TableHead>Person</TableHead>
118
+ <TableHead>Status</TableHead>
119
+ <TableHead>Last activity</TableHead>
120
+ <TableHead />
121
+ </TableRow>
122
+ </TableHeader>
123
+ <TableBody>
124
+ {invites.map((inv) => (
125
+ <TableRow key={inv.email}>
126
+ <TableCell>
127
+ <div className="flex items-center gap-2.5">
128
+ <Avatar className="h-7 w-7"><AvatarFallback className="text-xs">{inv.initials}</AvatarFallback></Avatar>
129
+ <div>
130
+ <p className="text-sm font-medium">{inv.name}</p>
131
+ <p className="text-xs text-muted-foreground">{inv.email}</p>
132
+ </div>
133
+ </div>
134
+ </TableCell>
135
+ <TableCell>
136
+ <Badge variant="outline" className={`text-xs ${statusStyle[inv.status]}`}>{inv.status}</Badge>
137
+ </TableCell>
138
+ <TableCell className="text-sm text-muted-foreground">{inv.activity}</TableCell>
139
+ <TableCell className="text-right">
140
+ {inv.status === 'Pending' && (
141
+ <Button variant="ghost" size="sm" className="h-7 px-2 text-xs text-destructive"><XCircle className="h-3.5 w-3.5 mr-1" />Revoke</Button>
142
+ )}
143
+ </TableCell>
144
+ </TableRow>
145
+ ))}
146
+ </TableBody>
147
+ </Table>
148
+ </CardContent>
149
+ </Card>
150
+ </div>
151
+ </LayoutResolved>
152
+ );
153
+ }
@@ -0,0 +1,141 @@
1
+ import { Badge, StatCard, Card, CardContent, CardHeader, CardTitle } from '@trackany-device/components';
2
+ import { LayoutResolved } from '../../layouts/LayoutSwitcher';
3
+ import type { LayoutName } from '../../layouts/LayoutSwitcher';
4
+ import { AlertTriangle, MonitorPlay, Users, Wifi } from 'lucide-react';
5
+ import { DevicesMiniMap } from '../../components/devices/devices-mini-map';
6
+ import type { MiniMapDevice, MiniMapIncident } from '../../components/devices/devices-mini-map';
7
+
8
+ export type { MiniMapDevice, MiniMapIncident };
9
+
10
+ export type LiveIncidentPriority = 'critical' | 'high' | 'medium';
11
+
12
+ export interface LiveIncident {
13
+ id: string;
14
+ assignee: string;
15
+ rule: string;
16
+ priority: LiveIncidentPriority;
17
+ }
18
+
19
+ export interface LiveVehicle {
20
+ reg: string;
21
+ location: string;
22
+ speed: string;
23
+ }
24
+
25
+ export interface LiveStats {
26
+ online: number;
27
+ offline: number;
28
+ activeTrips: number;
29
+ activeIncidents: number;
30
+ lastSync: string;
31
+ }
32
+
33
+ const priorityStyle: Record<LiveIncidentPriority, string> = {
34
+ critical: 'text-red-600 border-red-200 bg-red-50 text-xs',
35
+ high: 'text-orange-600 border-orange-200 bg-orange-50 text-xs',
36
+ medium: 'text-amber-600 border-amber-200 bg-amber-50 text-xs',
37
+ };
38
+
39
+ export function LiveStreamPage({
40
+ layout,
41
+ stats,
42
+ devices = [],
43
+ mapIncidents = [],
44
+ }: {
45
+ layout: LayoutName;
46
+ stats: LiveStats;
47
+ devices?: MiniMapDevice[];
48
+ mapIncidents?: MiniMapIncident[];
49
+ }) {
50
+ return (
51
+ <LayoutResolved layout={layout} title="Live Monitoring" currentUrl="/map">
52
+ <div className="relative flex h-[calc(100vh-3.5rem)] flex-col">
53
+ <div className="flex-1 relative">
54
+ <DevicesMiniMap
55
+ devices={devices}
56
+ incidents={mapIncidents}
57
+ height="100%"
58
+ className="rounded-none border-0"
59
+ />
60
+ </div>
61
+ <div className="flex items-center justify-between border-t border-border bg-background/95 px-4 py-2 text-xs text-muted-foreground backdrop-blur-sm">
62
+ <div className="flex items-center gap-4">
63
+ <span className="flex items-center gap-1.5"><Wifi className="h-3.5 w-3.5 text-green-500" />{stats.online} online</span>
64
+ <span className="flex items-center gap-1.5"><Users className="h-3.5 w-3.5" />{stats.offline} offline</span>
65
+ <span className="flex items-center gap-1.5"><MonitorPlay className="h-3.5 w-3.5 text-blue-500" />{stats.activeTrips} active trips</span>
66
+ </div>
67
+ <div className="flex items-center gap-2">
68
+ <Badge variant="destructive">{stats.activeIncidents} active incidents</Badge>
69
+ <span>Last sync {stats.lastSync}</span>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </LayoutResolved>
74
+ );
75
+ }
76
+
77
+ export function LiveStreamWithSidebarPage({
78
+ layout,
79
+ stats,
80
+ incidents,
81
+ vehicles,
82
+ devices = [],
83
+ mapIncidents = [],
84
+ }: {
85
+ layout: LayoutName;
86
+ stats: Pick<LiveStats, 'online' | 'activeIncidents'>;
87
+ incidents: LiveIncident[];
88
+ vehicles: LiveVehicle[];
89
+ devices?: MiniMapDevice[];
90
+ mapIncidents?: MiniMapIncident[];
91
+ }) {
92
+ return (
93
+ <LayoutResolved layout={layout} title="Live Monitoring" currentUrl="/map">
94
+ <div className="flex h-[calc(100vh-3.5rem)]">
95
+ <div className="flex-1 relative">
96
+ <DevicesMiniMap
97
+ devices={devices}
98
+ incidents={mapIncidents}
99
+ height="100%"
100
+ className="rounded-none border-0"
101
+ />
102
+ </div>
103
+ <div className="w-80 border-l border-border bg-background flex flex-col overflow-hidden">
104
+ <div className="p-4 border-b border-border space-y-3">
105
+ <div className="grid grid-cols-2 gap-2">
106
+ <StatCard icon={Wifi} label="Online" value={String(stats.online)} />
107
+ <StatCard icon={AlertTriangle} label="Incidents" value={String(stats.activeIncidents)} />
108
+ </div>
109
+ </div>
110
+ <div className="flex-1 overflow-y-auto divide-y divide-border">
111
+ <div className="px-4 py-2 bg-muted/30">
112
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">Active Incidents</p>
113
+ </div>
114
+ {incidents.map((inc) => (
115
+ <div key={inc.id} className="p-3 hover:bg-muted/30 cursor-pointer">
116
+ <div className="flex items-center justify-between mb-1">
117
+ <span className="text-xs font-mono text-muted-foreground">{inc.id}</span>
118
+ <Badge variant="outline" className={priorityStyle[inc.priority]}>{inc.priority}</Badge>
119
+ </div>
120
+ <p className="text-sm font-medium">{inc.assignee}</p>
121
+ <p className="text-xs text-muted-foreground">{inc.rule}</p>
122
+ </div>
123
+ ))}
124
+ <div className="px-4 py-2 bg-muted/30 mt-2">
125
+ <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">Online Vehicles</p>
126
+ </div>
127
+ {vehicles.map((v) => (
128
+ <div key={v.reg} className="p-3 hover:bg-muted/30 cursor-pointer">
129
+ <p className="text-sm font-mono font-medium">{v.reg}</p>
130
+ <div className="flex items-center justify-between text-xs text-muted-foreground mt-0.5">
131
+ <span>{v.location}</span>
132
+ <span>{v.speed}</span>
133
+ </div>
134
+ </div>
135
+ ))}
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </LayoutResolved>
140
+ );
141
+ }