@homefile/components-v2 2.14.32 → 2.15.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 (33) hide show
  1. package/dist/components/homeAssistant/monitorAlerts/WeatherDetail.d.ts +6 -0
  2. package/dist/components/homeAssistant/monitorAlerts/WeatherDetail.js +7 -0
  3. package/dist/components/homeAssistant/monitorAlerts/WeatherWidget.d.ts +2 -0
  4. package/dist/components/homeAssistant/monitorAlerts/WeatherWidget.js +26 -0
  5. package/dist/components/homeAssistant/monitorAlerts/index.d.ts +1 -0
  6. package/dist/components/homeAssistant/monitorAlerts/index.js +1 -0
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +2 -2
  9. package/dist/interfaces/homeAssistant/WeatherWidget.interface.d.ts +40 -0
  10. package/dist/interfaces/homeAssistant/WeatherWidget.interface.js +1 -0
  11. package/dist/interfaces/homeAssistant/index.d.ts +1 -0
  12. package/dist/interfaces/homeAssistant/index.js +1 -0
  13. package/dist/mocks/homeAssistant/index.d.ts +1 -0
  14. package/dist/mocks/homeAssistant/index.js +1 -0
  15. package/dist/mocks/homeAssistant/weather.d.ts +37 -0
  16. package/dist/mocks/homeAssistant/weather.js +268 -0
  17. package/dist/stories/homeAssistant/HomeMonitor.stories.js +6 -4
  18. package/dist/utils/Weather.utils.d.ts +3 -0
  19. package/dist/utils/Weather.utils.js +60 -0
  20. package/dist/utils/index.d.ts +1 -0
  21. package/dist/utils/index.js +1 -0
  22. package/package.json +1 -1
  23. package/src/components/homeAssistant/monitorAlerts/WeatherDetail.tsx +26 -0
  24. package/src/components/homeAssistant/monitorAlerts/WeatherWidget.tsx +141 -0
  25. package/src/components/homeAssistant/monitorAlerts/index.ts +1 -0
  26. package/src/index.ts +6 -1
  27. package/src/interfaces/homeAssistant/WeatherWidget.interface.ts +39 -0
  28. package/src/interfaces/homeAssistant/index.ts +1 -0
  29. package/src/mocks/homeAssistant/index.ts +1 -0
  30. package/src/mocks/homeAssistant/weather.ts +282 -0
  31. package/src/stories/homeAssistant/HomeMonitor.stories.tsx +6 -3
  32. package/src/utils/Weather.utils.ts +81 -0
  33. package/src/utils/index.ts +1 -0
@@ -0,0 +1,6 @@
1
+ interface WeatherDetailProps {
2
+ label: string;
3
+ value?: string | number;
4
+ }
5
+ export declare const WeatherDetail: ({ label, value }: WeatherDetailProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text, VStack } from '@chakra-ui/react';
3
+ export const WeatherDetail = ({ label, value }) => {
4
+ if (!value)
5
+ return null; // Não renderiza se o valor for undefined ou null
6
+ return (_jsxs(VStack, { spacing: "0", align: "start", fontFamily: "secondary", textTransform: "uppercase", children: [_jsx(Text, { fontSize: "xs", lineHeight: "1", children: label }), _jsx(Text, { fontSize: "xs", lineHeight: "1", children: value })] }));
7
+ };
@@ -0,0 +1,2 @@
1
+ import { WeatherWidgetI } from '../../../interfaces';
2
+ export declare const WeatherWidget: ({ current, details, forecast, header, }: WeatherWidgetI) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Stack, Flex, Text, HStack, VStack, Divider, chakra, } from '@chakra-ui/react';
3
+ import { extractCodeFromUrl } from '../../../utils';
4
+ import { LuSnowflake, LuSun, LuCloudSun, LuCloudy, LuCloud, LuCloudRain, LuCloudLightning, } from 'react-icons/lu';
5
+ import { colors } from '../../../theme/colors';
6
+ const weatherIconMap = {
7
+ skc: LuSun,
8
+ few: LuCloudSun,
9
+ sct: LuCloud,
10
+ bkn: LuCloudy,
11
+ ovc: LuCloudy,
12
+ rain: LuCloudRain,
13
+ tsra: LuCloudLightning,
14
+ snow: LuSnowflake,
15
+ };
16
+ export const WeatherWidget = ({ current, details, forecast, header, }) => {
17
+ return (_jsxs(Stack, { spacing: "base", p: "4", zIndex: "2", children: [_jsxs(Flex, { justify: "space-between", align: "center", children: [_jsx(Text, { fontSize: "sm", fontFamily: "secondary", textTransform: "uppercase", children: header.date }), _jsx(Text, { fontSize: "sm", fontFamily: "secondary", textTransform: "uppercase", children: header.location })] }), _jsxs(Stack, { spacing: "0", align: "end", children: [_jsxs(HStack, { align: "start", spacing: "2", children: [_jsxs(Text, { fontSize: "6xl", fontWeight: "medium", lineHeight: 1, color: "gray.4", children: [current.temp, "\u00B0"] }), getWeatherIcon(current.icon, 50)] }), _jsxs(Text, { fontSize: "md", children: [_jsx(chakra.span, { color: "gray.2", children: "H " }), " ", current.high, "\u00B0 \u00A0", _jsx(chakra.span, { color: "gray.2", children: "L " }), current.low, "\u00B0"] })] }), _jsx(Divider, { borderColor: "gray.2", borderStyle: "dashed" }), _jsxs(Flex, { justify: "space-between", children: [_jsxs(VStack, { spacing: "0", align: "start", children: [_jsx(WeatherDetailText, { children: "Precipitation" }), details.humidity && _jsx(WeatherDetailText, { children: "Humidity" }), _jsx(WeatherDetailText, { children: "Wind" })] }), _jsxs(VStack, { spacing: "0", align: "start", children: [_jsxs(WeatherDetailText, { children: [details.precipitation, "%"] }), details.humidity && (_jsxs(WeatherDetailText, { children: [details.humidity, "%"] })), _jsx(WeatherDetailText, { children: details.wind })] })] }), _jsx(Flex, { justify: "space-between", gap: "1", children: forecast.map((f) => (_jsxs(VStack, { spacing: "0", border: "1px solid", borderColor: "gray.2", borderRadius: "sm", children: [_jsx(Text, { fontFamily: "secondary", textTransform: "uppercase", fontSize: "xxs", color: "gray.2", children: f.day }), _jsx(Divider, { borderColor: "gray.2" }), _jsxs(Stack, { spacing: "0", py: "1", px: "2", align: "center", children: [getWeatherIcon(f.icon, 16, colors.gray[3]), _jsxs(Text, { fontSize: "sm", fontWeight: "medium", mb: "-1", children: [f.high, "\u00B0"] }), _jsxs(WeatherDetailText, { children: ["L ", f.low, "\u00B0"] })] })] }, f.day))) })] }));
18
+ };
19
+ const WeatherDetailText = ({ children }) => {
20
+ return (_jsx(Text, { fontFamily: "secondary", textTransform: "uppercase", fontSize: "xs", lineHeight: "1.2", children: children }));
21
+ };
22
+ const getWeatherIcon = (iconUrl, size = 48, color = colors.gray[4]) => {
23
+ const code = extractCodeFromUrl(iconUrl);
24
+ const IconComponent = weatherIconMap[code] || LuSun;
25
+ return _jsx(IconComponent, { size: size, color: color });
26
+ };
@@ -3,6 +3,7 @@ export * from './AlertHeader';
3
3
  export * from './AlertTemplate';
4
4
  export * from './AlertTitle';
5
5
  export * from './BaseAlertCard';
6
+ export * from './WeatherWidget';
6
7
  export * from './HomefileMonitoring';
7
8
  export * from './MonitorAlerts';
8
9
  export * from './Notifications';
@@ -3,6 +3,7 @@ export * from './AlertHeader';
3
3
  export * from './AlertTemplate';
4
4
  export * from './AlertTitle';
5
5
  export * from './BaseAlertCard';
6
+ export * from './WeatherWidget';
6
7
  export * from './HomefileMonitoring';
7
8
  export * from './MonitorAlerts';
8
9
  export * from './Notifications';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { ActivateAccount, ActiveSubscription, AddCardBanner, AddEditContactPanel, AddFolder, AddHomeContent, AddHomeItem, AddHomeItemHeader, AddMedia, AddPropertyRecords, Address, AddPopup, AddTile, AlertBanner, AphwTile, AppBar, AssignableReceipts, BackHeader, BarDivider, CancelAccount, CatalogPopup, CloudsAnimation, ContactList, ContactsContent, ContainerHeader, CreateDocumentHeader, CreateHouseholdItemHeader, CreditCardContainer, CreditCardError, CustomerTile, DeleteBanner, Dialog, DisplayFiles, DisplayFilesDetail, DisplayOptions, DisplayReceipts, DocumentMenu, DocumentNameHeader, DocumentPreview, DynamicForm, EditAccountType, EditHomeBody, EditHomeFooter, EditHomeHeader, EditHomePanel, EmailPermissions, EmailValidation, Feedback, FileDetail, FilesUploader, FlowStep, FolderDetail, FolderDetailBody, FolderDetailContent, FolderDetailFooter, FolderDetailHeader, FolderInfo, FolderSharing, FolderTypeSelection, FooterButtons, FooterDrawer, GenericBackHeader, GroupCard, GroupsContainer, GroupsHeader, Header, HelpContent, HomeAssistant, HomeAssistantPanel, HomeBoardGrid, HomeBoardTour, HomeCard, HomeCardWithRecipent, HomeDetailsContent, HomefileMonitoring, HomeHeader, HomeMonitor, HomeMonitorSteps, HomeSharedWith, InboxForwardBanner, InboxTile, ItemFormPanel, ItemFormTabs, ItemNameHeader, ItemsReviewBanner, ItemSubTypeSelect, Launchpad, LaunchpadAutofilerBanner, LaunchpadReceiptAutofiler, LaunchpadReceiptPanel, LaunchpadTour, LeftPanel, Loading, MediaDetailsStep, MessagePanel, MessageChatPanel, MonitorAlerts, MonthlyCharge, MortgageInfo, MoveModal, MyHomes, MyProfileBody, MyProfileContent, MyProfileFooter, MyProfileHeader, MyProfilePanel, NewCreditCard, NewCreditCardHeader, NewPassword, NotBeChargedBanner, Notifications, NotificationsReminder, NotificationsPanel, NotificationCard, Overlay, PanelHeader, PartnerActiveSubscription, PartnerCatalogPanel, PartnerContent, PartnerCustomerCode, PartnerDetails, PartnerImages, PartnerPanel, PasswordInput, PaymentReceipts, PdfButton, PeopleConnected, ProfileDetailsTab, ProfilePaymentTab, ProjectList, PropertyRecords, PropertyTaxes, ReadOnlyDynamicForm, ReadOnlyImage, ReadOnlyToggle, ReceiptAutofiler, ReceiptBody, ReceiptContent, ReceiptDetails, ReceiptFilters, ReceiptFooter, ReceiptHeader, ReceiptInfos, ReceiptItem, ReceiptItems, ReceiptPDF, ReceiptsDisplayOptions, ReceiptsFiled, ReceiptsHeader, ReceiptsInfo, ReceiptsReceivedContent, RecipientForm, RecipientsToShare, RecipientTab, RecordsInputs, ResendResetPassword, ResetPassword, ReviewBanner, RightPanel, RolePermissionsTab, RoomHeader, RoomsBoardTour, RoomsMenu, RoomsMenuMobile, RoomStep, RoomVideo, SalesTax, SatisfactionTile, SectionHeader, SendCommunication, ShareContactsContent, SharedAccounts, SharedHomeContent, SharedHomeHeader, ShareHome, ShareHomeConnections, ShareHomeForm, ShineTile, ShortPartnerTile, SignIn, SignUp, SkeletonBox, StepHeader, StorageUsed, Subscription, SubscriptionCard, SubscriptionTable, Summary, TabsHeader, TextInput, ToBeDeletedBody, ToBeDeletedContent, ToBeDeletedFooter, ToBeDeletedHeader, TourButton, Trash, TrendingValue, TrialBanner, TutorialsButton, TwoFactor, TwoFactorSetting, UpdateList, UserDetails, ValueMonitor, ViewContactPanel, VideoPlayer, VideoPlayerModal, WellDone, YtdTile, } from './components';
1
+ export { ActivateAccount, ActiveSubscription, AddCardBanner, AddEditContactPanel, AddFolder, AddHomeContent, AddHomeItem, AddHomeItemHeader, AddMedia, AddPropertyRecords, Address, AddPopup, AddTile, AlertBanner, AphwTile, AppBar, AssignableReceipts, BackHeader, BarDivider, CancelAccount, CatalogPopup, CloudsAnimation, ContactList, ContactsContent, ContainerHeader, CreateDocumentHeader, CreateHouseholdItemHeader, CreditCardContainer, CreditCardError, CustomerTile, DeleteBanner, Dialog, DisplayFiles, DisplayFilesDetail, DisplayOptions, DisplayReceipts, DocumentMenu, DocumentNameHeader, DocumentPreview, DynamicForm, EditAccountType, EditHomeBody, EditHomeFooter, EditHomeHeader, EditHomePanel, EmailPermissions, EmailValidation, Feedback, FileDetail, FilesUploader, FlowStep, FolderDetail, FolderDetailBody, FolderDetailContent, FolderDetailFooter, FolderDetailHeader, FolderInfo, FolderSharing, FolderTypeSelection, FooterButtons, FooterDrawer, GenericBackHeader, GroupCard, GroupsContainer, GroupsHeader, Header, HelpContent, HomeAssistant, HomeAssistantPanel, HomeBoardGrid, HomeBoardTour, HomeCard, HomeCardWithRecipent, HomeDetailsContent, HomefileMonitoring, HomeHeader, HomeMonitor, HomeMonitorSteps, HomeSharedWith, InboxForwardBanner, InboxTile, ItemFormPanel, ItemFormTabs, ItemNameHeader, ItemsReviewBanner, ItemSubTypeSelect, Launchpad, LaunchpadAutofilerBanner, LaunchpadReceiptAutofiler, LaunchpadReceiptPanel, LaunchpadTour, LeftPanel, Loading, MediaDetailsStep, MessagePanel, MessageChatPanel, MonitorAlerts, MonthlyCharge, MortgageInfo, MoveModal, MyHomes, MyProfileBody, MyProfileContent, MyProfileFooter, MyProfileHeader, MyProfilePanel, NewCreditCard, NewCreditCardHeader, NewPassword, NotBeChargedBanner, Notifications, NotificationsReminder, NotificationsPanel, NotificationCard, Overlay, PanelHeader, PartnerActiveSubscription, PartnerCatalogPanel, PartnerContent, PartnerCustomerCode, PartnerDetails, PartnerImages, PartnerPanel, PasswordInput, PaymentReceipts, PdfButton, PeopleConnected, ProfileDetailsTab, ProfilePaymentTab, ProjectList, PropertyRecords, PropertyTaxes, ReadOnlyDynamicForm, ReadOnlyImage, ReadOnlyToggle, ReceiptAutofiler, ReceiptBody, ReceiptContent, ReceiptDetails, ReceiptFilters, ReceiptFooter, ReceiptHeader, ReceiptInfos, ReceiptItem, ReceiptItems, ReceiptPDF, ReceiptsDisplayOptions, ReceiptsFiled, ReceiptsHeader, ReceiptsInfo, ReceiptsReceivedContent, RecipientForm, RecipientsToShare, RecipientTab, RecordsInputs, ResendResetPassword, ResetPassword, ReviewBanner, RightPanel, RolePermissionsTab, RoomHeader, RoomsBoardTour, RoomsMenu, RoomsMenuMobile, RoomStep, RoomVideo, SalesTax, SatisfactionTile, SectionHeader, SendCommunication, ShareContactsContent, SharedAccounts, SharedHomeContent, SharedHomeHeader, ShareHome, ShareHomeConnections, ShareHomeForm, ShineTile, ShortPartnerTile, SignIn, SignUp, SkeletonBox, StepHeader, StorageUsed, Subscription, SubscriptionCard, SubscriptionTable, Summary, TabsHeader, TextInput, ToBeDeletedBody, ToBeDeletedContent, ToBeDeletedFooter, ToBeDeletedHeader, TourButton, Trash, TrendingValue, TrialBanner, TutorialsButton, TwoFactor, TwoFactorSetting, UpdateList, UserDetails, ValueMonitor, ViewContactPanel, VideoPlayer, VideoPlayerModal, WeatherWidget, WellDone, YtdTile, } from './components';
2
2
  export { useCustomToast } from './hooks';
3
- export { randomColor, mapApiObjectToFormFields } from './utils';
3
+ export { randomColor, mapApiObjectToFormFields, mapForecastToWidget, } from './utils';
4
4
  export { Contacts, MagnifyingGlassReport, Message, Register, Receipts, Price, BlueFolderShared, Calendar, Create, Notes, } from './assets/images';
5
5
  export { billingProxy, dynamicFormProxy, homeCardProxy, partnerContentProxy, partnerDetailsProxy, paymentMethodProxy, recordsInputsProxy, recordsInputsToDBProxy, userDetailsProxy, confirmAddressProxy, } from './proxies';
6
6
  import theme from './theme';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { ActivateAccount, ActiveSubscription, AddCardBanner, AddEditContactPanel, AddFolder, AddHomeContent, AddHomeItem, AddHomeItemHeader, AddMedia, AddPropertyRecords, Address, AddPopup, AddTile, AlertBanner, AphwTile, AppBar, AssignableReceipts, BackHeader, BarDivider, CancelAccount, CatalogPopup, CloudsAnimation, ContactList, ContactsContent, ContainerHeader, CreateDocumentHeader, CreateHouseholdItemHeader, CreditCardContainer, CreditCardError, CustomerTile, DeleteBanner, Dialog, DisplayFiles, DisplayFilesDetail, DisplayOptions, DisplayReceipts, DocumentMenu, DocumentNameHeader, DocumentPreview, DynamicForm, EditAccountType, EditHomeBody, EditHomeFooter, EditHomeHeader, EditHomePanel, EmailPermissions, EmailValidation, Feedback, FileDetail, FilesUploader, FlowStep, FolderDetail, FolderDetailBody, FolderDetailContent, FolderDetailFooter, FolderDetailHeader, FolderInfo, FolderSharing, FolderTypeSelection, FooterButtons, FooterDrawer, GenericBackHeader, GroupCard, GroupsContainer, GroupsHeader, Header, HelpContent, HomeAssistant, HomeAssistantPanel, HomeBoardGrid, HomeBoardTour, HomeCard, HomeCardWithRecipent, HomeDetailsContent, HomefileMonitoring, HomeHeader, HomeMonitor, HomeMonitorSteps, HomeSharedWith, InboxForwardBanner, InboxTile, ItemFormPanel, ItemFormTabs, ItemNameHeader, ItemsReviewBanner, ItemSubTypeSelect, Launchpad, LaunchpadAutofilerBanner, LaunchpadReceiptAutofiler, LaunchpadReceiptPanel, LaunchpadTour, LeftPanel, Loading, MediaDetailsStep, MessagePanel, MessageChatPanel, MonitorAlerts, MonthlyCharge, MortgageInfo, MoveModal, MyHomes, MyProfileBody, MyProfileContent, MyProfileFooter, MyProfileHeader, MyProfilePanel, NewCreditCard, NewCreditCardHeader, NewPassword, NotBeChargedBanner, Notifications, NotificationsReminder, NotificationsPanel, NotificationCard, Overlay, PanelHeader, PartnerActiveSubscription, PartnerCatalogPanel, PartnerContent, PartnerCustomerCode, PartnerDetails, PartnerImages, PartnerPanel, PasswordInput, PaymentReceipts, PdfButton, PeopleConnected, ProfileDetailsTab, ProfilePaymentTab, ProjectList, PropertyRecords, PropertyTaxes, ReadOnlyDynamicForm, ReadOnlyImage, ReadOnlyToggle, ReceiptAutofiler, ReceiptBody, ReceiptContent, ReceiptDetails, ReceiptFilters, ReceiptFooter, ReceiptHeader, ReceiptInfos, ReceiptItem, ReceiptItems, ReceiptPDF, ReceiptsDisplayOptions, ReceiptsFiled, ReceiptsHeader, ReceiptsInfo, ReceiptsReceivedContent, RecipientForm, RecipientsToShare, RecipientTab, RecordsInputs, ResendResetPassword, ResetPassword, ReviewBanner, RightPanel, RolePermissionsTab, RoomHeader, RoomsBoardTour, RoomsMenu, RoomsMenuMobile, RoomStep, RoomVideo, SalesTax, SatisfactionTile, SectionHeader, SendCommunication, ShareContactsContent, SharedAccounts, SharedHomeContent, SharedHomeHeader, ShareHome, ShareHomeConnections, ShareHomeForm, ShineTile, ShortPartnerTile, SignIn, SignUp, SkeletonBox, StepHeader, StorageUsed, Subscription, SubscriptionCard, SubscriptionTable, Summary, TabsHeader, TextInput, ToBeDeletedBody, ToBeDeletedContent, ToBeDeletedFooter, ToBeDeletedHeader, TourButton, Trash, TrendingValue, TrialBanner, TutorialsButton, TwoFactor, TwoFactorSetting, UpdateList, UserDetails, ValueMonitor, ViewContactPanel, VideoPlayer, VideoPlayerModal, WellDone, YtdTile, } from './components';
1
+ export { ActivateAccount, ActiveSubscription, AddCardBanner, AddEditContactPanel, AddFolder, AddHomeContent, AddHomeItem, AddHomeItemHeader, AddMedia, AddPropertyRecords, Address, AddPopup, AddTile, AlertBanner, AphwTile, AppBar, AssignableReceipts, BackHeader, BarDivider, CancelAccount, CatalogPopup, CloudsAnimation, ContactList, ContactsContent, ContainerHeader, CreateDocumentHeader, CreateHouseholdItemHeader, CreditCardContainer, CreditCardError, CustomerTile, DeleteBanner, Dialog, DisplayFiles, DisplayFilesDetail, DisplayOptions, DisplayReceipts, DocumentMenu, DocumentNameHeader, DocumentPreview, DynamicForm, EditAccountType, EditHomeBody, EditHomeFooter, EditHomeHeader, EditHomePanel, EmailPermissions, EmailValidation, Feedback, FileDetail, FilesUploader, FlowStep, FolderDetail, FolderDetailBody, FolderDetailContent, FolderDetailFooter, FolderDetailHeader, FolderInfo, FolderSharing, FolderTypeSelection, FooterButtons, FooterDrawer, GenericBackHeader, GroupCard, GroupsContainer, GroupsHeader, Header, HelpContent, HomeAssistant, HomeAssistantPanel, HomeBoardGrid, HomeBoardTour, HomeCard, HomeCardWithRecipent, HomeDetailsContent, HomefileMonitoring, HomeHeader, HomeMonitor, HomeMonitorSteps, HomeSharedWith, InboxForwardBanner, InboxTile, ItemFormPanel, ItemFormTabs, ItemNameHeader, ItemsReviewBanner, ItemSubTypeSelect, Launchpad, LaunchpadAutofilerBanner, LaunchpadReceiptAutofiler, LaunchpadReceiptPanel, LaunchpadTour, LeftPanel, Loading, MediaDetailsStep, MessagePanel, MessageChatPanel, MonitorAlerts, MonthlyCharge, MortgageInfo, MoveModal, MyHomes, MyProfileBody, MyProfileContent, MyProfileFooter, MyProfileHeader, MyProfilePanel, NewCreditCard, NewCreditCardHeader, NewPassword, NotBeChargedBanner, Notifications, NotificationsReminder, NotificationsPanel, NotificationCard, Overlay, PanelHeader, PartnerActiveSubscription, PartnerCatalogPanel, PartnerContent, PartnerCustomerCode, PartnerDetails, PartnerImages, PartnerPanel, PasswordInput, PaymentReceipts, PdfButton, PeopleConnected, ProfileDetailsTab, ProfilePaymentTab, ProjectList, PropertyRecords, PropertyTaxes, ReadOnlyDynamicForm, ReadOnlyImage, ReadOnlyToggle, ReceiptAutofiler, ReceiptBody, ReceiptContent, ReceiptDetails, ReceiptFilters, ReceiptFooter, ReceiptHeader, ReceiptInfos, ReceiptItem, ReceiptItems, ReceiptPDF, ReceiptsDisplayOptions, ReceiptsFiled, ReceiptsHeader, ReceiptsInfo, ReceiptsReceivedContent, RecipientForm, RecipientsToShare, RecipientTab, RecordsInputs, ResendResetPassword, ResetPassword, ReviewBanner, RightPanel, RolePermissionsTab, RoomHeader, RoomsBoardTour, RoomsMenu, RoomsMenuMobile, RoomStep, RoomVideo, SalesTax, SatisfactionTile, SectionHeader, SendCommunication, ShareContactsContent, SharedAccounts, SharedHomeContent, SharedHomeHeader, ShareHome, ShareHomeConnections, ShareHomeForm, ShineTile, ShortPartnerTile, SignIn, SignUp, SkeletonBox, StepHeader, StorageUsed, Subscription, SubscriptionCard, SubscriptionTable, Summary, TabsHeader, TextInput, ToBeDeletedBody, ToBeDeletedContent, ToBeDeletedFooter, ToBeDeletedHeader, TourButton, Trash, TrendingValue, TrialBanner, TutorialsButton, TwoFactor, TwoFactorSetting, UpdateList, UserDetails, ValueMonitor, ViewContactPanel, VideoPlayer, VideoPlayerModal, WeatherWidget, WellDone, YtdTile, } from './components';
2
2
  export { useCustomToast } from './hooks';
3
- export { randomColor, mapApiObjectToFormFields } from './utils';
3
+ export { randomColor, mapApiObjectToFormFields, mapForecastToWidget, } from './utils';
4
4
  export { Contacts, MagnifyingGlassReport, Message, Register, Receipts, Price, BlueFolderShared, Calendar, Create, Notes, } from './assets/images';
5
5
  export { billingProxy, dynamicFormProxy, homeCardProxy, partnerContentProxy, partnerDetailsProxy, paymentMethodProxy, recordsInputsProxy, recordsInputsToDBProxy, userDetailsProxy, confirmAddressProxy, } from './proxies';
6
6
  import theme from './theme';
@@ -0,0 +1,40 @@
1
+ export interface ForecastPeriodI {
2
+ number: number;
3
+ name: string;
4
+ startTime: string;
5
+ endTime: string;
6
+ isDaytime: boolean;
7
+ temperature: number;
8
+ temperatureUnit: string;
9
+ probabilityOfPrecipitation: {
10
+ value: number | null;
11
+ };
12
+ windSpeed: string;
13
+ windDirection: string;
14
+ icon: string;
15
+ shortForecast: string;
16
+ detailedForecast: string;
17
+ }
18
+ export interface WeatherWidgetI {
19
+ header: {
20
+ date: string;
21
+ location: string;
22
+ };
23
+ current: {
24
+ temp: number;
25
+ icon: string;
26
+ high: number;
27
+ low: number;
28
+ };
29
+ details: {
30
+ precipitation: number;
31
+ humidity?: number;
32
+ wind: string;
33
+ };
34
+ forecast: Array<{
35
+ day: string;
36
+ icon: string;
37
+ high: number;
38
+ low: number;
39
+ }>;
40
+ }
@@ -8,3 +8,4 @@ export * from './HomeAssistantSteps.interface';
8
8
  export * from './HomeAssistantTutorial.interface';
9
9
  export * from './HomeMonitorSteps.interface';
10
10
  export * from './MonitorAlerts.interface';
11
+ export * from './WeatherWidget.interface';
@@ -8,3 +8,4 @@ export * from './HomeAssistantSteps.interface';
8
8
  export * from './HomeAssistantTutorial.interface';
9
9
  export * from './HomeMonitorSteps.interface';
10
10
  export * from './MonitorAlerts.interface';
11
+ export * from './WeatherWidget.interface';
@@ -1 +1,2 @@
1
1
  export * from './homeAssistantForms';
2
+ export * from './weather';
@@ -1 +1,2 @@
1
1
  export * from './homeAssistantForms';
2
+ export * from './weather';
@@ -0,0 +1,37 @@
1
+ export declare const weatherDataMock: ({
2
+ number: number;
3
+ name: string;
4
+ startTime: string;
5
+ endTime: string;
6
+ isDaytime: boolean;
7
+ temperature: number;
8
+ temperatureUnit: string;
9
+ temperatureTrend: string;
10
+ probabilityOfPrecipitation: {
11
+ unitCode: string;
12
+ value: null;
13
+ };
14
+ windSpeed: string;
15
+ windDirection: string;
16
+ icon: string;
17
+ shortForecast: string;
18
+ detailedForecast: string;
19
+ } | {
20
+ number: number;
21
+ name: string;
22
+ startTime: string;
23
+ endTime: string;
24
+ isDaytime: boolean;
25
+ temperature: number;
26
+ temperatureUnit: string;
27
+ temperatureTrend: string;
28
+ probabilityOfPrecipitation: {
29
+ unitCode: string;
30
+ value: number;
31
+ };
32
+ windSpeed: string;
33
+ windDirection: string;
34
+ icon: string;
35
+ shortForecast: string;
36
+ detailedForecast: string;
37
+ })[];
@@ -0,0 +1,268 @@
1
+ export const weatherDataMock = [
2
+ {
3
+ number: 1,
4
+ name: 'This Afternoon',
5
+ startTime: '2025-05-09T14:00:00-04:00',
6
+ endTime: '2025-05-09T18:00:00-04:00',
7
+ isDaytime: true,
8
+ temperature: 78,
9
+ temperatureUnit: 'F',
10
+ temperatureTrend: '',
11
+ probabilityOfPrecipitation: {
12
+ unitCode: 'wmoUnit:percent',
13
+ value: null,
14
+ },
15
+ windSpeed: '6 mph',
16
+ windDirection: 'NW',
17
+ icon: 'https://api.weather.gov/icons/land/day/sct?size=medium',
18
+ shortForecast: 'Mostly Sunny',
19
+ detailedForecast: 'Mostly sunny, with a high near 78. Northwest wind around 6 mph.',
20
+ },
21
+ {
22
+ number: 2,
23
+ name: 'Tonight',
24
+ startTime: '2025-05-09T18:00:00-04:00',
25
+ endTime: '2025-05-10T06:00:00-04:00',
26
+ isDaytime: false,
27
+ temperature: 46,
28
+ temperatureUnit: 'F',
29
+ temperatureTrend: '',
30
+ probabilityOfPrecipitation: {
31
+ unitCode: 'wmoUnit:percent',
32
+ value: null,
33
+ },
34
+ windSpeed: '2 to 6 mph',
35
+ windDirection: 'N',
36
+ icon: 'https://api.weather.gov/icons/land/night/bkn?size=medium',
37
+ shortForecast: 'Mostly Cloudy',
38
+ detailedForecast: 'Mostly cloudy, with a low around 46. North wind 2 to 6 mph.',
39
+ },
40
+ {
41
+ number: 3,
42
+ name: 'Saturday',
43
+ startTime: '2025-05-10T06:00:00-04:00',
44
+ endTime: '2025-05-10T18:00:00-04:00',
45
+ isDaytime: true,
46
+ temperature: 72,
47
+ temperatureUnit: 'F',
48
+ temperatureTrend: '',
49
+ probabilityOfPrecipitation: {
50
+ unitCode: 'wmoUnit:percent',
51
+ value: null,
52
+ },
53
+ windSpeed: '3 mph',
54
+ windDirection: 'NE',
55
+ icon: 'https://api.weather.gov/icons/land/day/bkn?size=medium',
56
+ shortForecast: 'Mostly Cloudy',
57
+ detailedForecast: 'Mostly cloudy, with a high near 72. Northeast wind around 3 mph.',
58
+ },
59
+ {
60
+ number: 4,
61
+ name: 'Saturday Night',
62
+ startTime: '2025-05-10T18:00:00-04:00',
63
+ endTime: '2025-05-11T06:00:00-04:00',
64
+ isDaytime: false,
65
+ temperature: 52,
66
+ temperatureUnit: 'F',
67
+ temperatureTrend: '',
68
+ probabilityOfPrecipitation: {
69
+ unitCode: 'wmoUnit:percent',
70
+ value: 20,
71
+ },
72
+ windSpeed: '2 mph',
73
+ windDirection: 'NE',
74
+ icon: 'https://api.weather.gov/icons/land/night/rain,20?size=medium',
75
+ shortForecast: 'Slight Chance Light Rain',
76
+ detailedForecast: 'A slight chance of rain between 11pm and 5am, then a slight chance of rain showers. Mostly cloudy, with a low around 52. Northeast wind around 2 mph. Chance of precipitation is 20%. New rainfall amounts less than a tenth of an inch possible.',
77
+ },
78
+ {
79
+ number: 5,
80
+ name: 'Sunday',
81
+ startTime: '2025-05-11T06:00:00-04:00',
82
+ endTime: '2025-05-11T18:00:00-04:00',
83
+ isDaytime: true,
84
+ temperature: 68,
85
+ temperatureUnit: 'F',
86
+ temperatureTrend: '',
87
+ probabilityOfPrecipitation: {
88
+ unitCode: 'wmoUnit:percent',
89
+ value: 30,
90
+ },
91
+ windSpeed: '3 to 7 mph',
92
+ windDirection: 'NE',
93
+ icon: 'https://api.weather.gov/icons/land/day/rain_showers,20/rain,30?size=medium',
94
+ shortForecast: 'Chance Rain Showers then Chance Light Rain',
95
+ detailedForecast: 'A chance of rain showers before 2pm, then a chance of rain between 2pm and 4pm, then a chance of rain showers. Mostly cloudy, with a high near 68. Northeast wind 3 to 7 mph. Chance of precipitation is 30%.',
96
+ },
97
+ {
98
+ number: 6,
99
+ name: 'Sunday Night',
100
+ startTime: '2025-05-11T18:00:00-04:00',
101
+ endTime: '2025-05-12T06:00:00-04:00',
102
+ isDaytime: false,
103
+ temperature: 53,
104
+ temperatureUnit: 'F',
105
+ temperatureTrend: '',
106
+ probabilityOfPrecipitation: {
107
+ unitCode: 'wmoUnit:percent',
108
+ value: 50,
109
+ },
110
+ windSpeed: '6 mph',
111
+ windDirection: 'ENE',
112
+ icon: 'https://api.weather.gov/icons/land/night/rain_showers,30/tsra,50?size=medium',
113
+ shortForecast: 'Chance Rain Showers',
114
+ detailedForecast: 'A chance of rain showers before 2am, then a chance of showers and thunderstorms. Mostly cloudy, with a low around 53. Chance of precipitation is 50%.',
115
+ },
116
+ {
117
+ number: 7,
118
+ name: 'Monday',
119
+ startTime: '2025-05-12T06:00:00-04:00',
120
+ endTime: '2025-05-12T18:00:00-04:00',
121
+ isDaytime: true,
122
+ temperature: 65,
123
+ temperatureUnit: 'F',
124
+ temperatureTrend: '',
125
+ probabilityOfPrecipitation: {
126
+ unitCode: 'wmoUnit:percent',
127
+ value: 80,
128
+ },
129
+ windSpeed: '8 mph',
130
+ windDirection: 'ENE',
131
+ icon: 'https://api.weather.gov/icons/land/day/tsra,70/tsra,80?size=medium',
132
+ shortForecast: 'Showers And Thunderstorms',
133
+ detailedForecast: 'Showers and thunderstorms. Mostly cloudy, with a high near 65. Chance of precipitation is 80%.',
134
+ },
135
+ {
136
+ number: 8,
137
+ name: 'Monday Night',
138
+ startTime: '2025-05-12T18:00:00-04:00',
139
+ endTime: '2025-05-13T06:00:00-04:00',
140
+ isDaytime: false,
141
+ temperature: 59,
142
+ temperatureUnit: 'F',
143
+ temperatureTrend: '',
144
+ probabilityOfPrecipitation: {
145
+ unitCode: 'wmoUnit:percent',
146
+ value: 90,
147
+ },
148
+ windSpeed: '7 mph',
149
+ windDirection: 'E',
150
+ icon: 'https://api.weather.gov/icons/land/night/tsra,90?size=medium',
151
+ shortForecast: 'Showers And Thunderstorms',
152
+ detailedForecast: 'Showers and thunderstorms. Mostly cloudy, with a low around 59. Chance of precipitation is 90%.',
153
+ },
154
+ {
155
+ number: 9,
156
+ name: 'Tuesday',
157
+ startTime: '2025-05-13T06:00:00-04:00',
158
+ endTime: '2025-05-13T18:00:00-04:00',
159
+ isDaytime: true,
160
+ temperature: 73,
161
+ temperatureUnit: 'F',
162
+ temperatureTrend: '',
163
+ probabilityOfPrecipitation: {
164
+ unitCode: 'wmoUnit:percent',
165
+ value: 90,
166
+ },
167
+ windSpeed: '6 mph',
168
+ windDirection: 'ESE',
169
+ icon: 'https://api.weather.gov/icons/land/day/tsra,80/tsra,90?size=medium',
170
+ shortForecast: 'Showers And Thunderstorms',
171
+ detailedForecast: 'Showers and thunderstorms. Mostly cloudy, with a high near 73. Chance of precipitation is 90%.',
172
+ },
173
+ {
174
+ number: 10,
175
+ name: 'Tuesday Night',
176
+ startTime: '2025-05-13T18:00:00-04:00',
177
+ endTime: '2025-05-14T06:00:00-04:00',
178
+ isDaytime: false,
179
+ temperature: 58,
180
+ temperatureUnit: 'F',
181
+ temperatureTrend: '',
182
+ probabilityOfPrecipitation: {
183
+ unitCode: 'wmoUnit:percent',
184
+ value: 90,
185
+ },
186
+ windSpeed: '1 to 5 mph',
187
+ windDirection: 'E',
188
+ icon: 'https://api.weather.gov/icons/land/night/tsra_sct,90/tsra_sct,50?size=medium',
189
+ shortForecast: 'Showers And Thunderstorms',
190
+ detailedForecast: 'Showers and thunderstorms. Mostly cloudy, with a low around 58. Chance of precipitation is 90%.',
191
+ },
192
+ {
193
+ number: 11,
194
+ name: 'Wednesday',
195
+ startTime: '2025-05-14T06:00:00-04:00',
196
+ endTime: '2025-05-14T18:00:00-04:00',
197
+ isDaytime: true,
198
+ temperature: 79,
199
+ temperatureUnit: 'F',
200
+ temperatureTrend: '',
201
+ probabilityOfPrecipitation: {
202
+ unitCode: 'wmoUnit:percent',
203
+ value: 80,
204
+ },
205
+ windSpeed: '3 mph',
206
+ windDirection: 'WSW',
207
+ icon: 'https://api.weather.gov/icons/land/day/rain_showers,50/tsra_hi,80?size=medium',
208
+ shortForecast: 'Showers And Thunderstorms',
209
+ detailedForecast: 'Rain showers likely before 2pm, then showers and thunderstorms. Partly sunny, with a high near 79. Chance of precipitation is 80%.',
210
+ },
211
+ {
212
+ number: 12,
213
+ name: 'Wednesday Night',
214
+ startTime: '2025-05-14T18:00:00-04:00',
215
+ endTime: '2025-05-15T06:00:00-04:00',
216
+ isDaytime: false,
217
+ temperature: 58,
218
+ temperatureUnit: 'F',
219
+ temperatureTrend: '',
220
+ probabilityOfPrecipitation: {
221
+ unitCode: 'wmoUnit:percent',
222
+ value: 70,
223
+ },
224
+ windSpeed: '2 mph',
225
+ windDirection: 'W',
226
+ icon: 'https://api.weather.gov/icons/land/night/tsra_hi,70/tsra_hi?size=medium',
227
+ shortForecast: 'Showers And Thunderstorms Likely',
228
+ detailedForecast: 'Showers and thunderstorms likely before 1am. Partly cloudy, with a low around 58. Chance of precipitation is 70%.',
229
+ },
230
+ {
231
+ number: 13,
232
+ name: 'Thursday',
233
+ startTime: '2025-05-15T06:00:00-04:00',
234
+ endTime: '2025-05-15T18:00:00-04:00',
235
+ isDaytime: true,
236
+ temperature: 85,
237
+ temperatureUnit: 'F',
238
+ temperatureTrend: '',
239
+ probabilityOfPrecipitation: {
240
+ unitCode: 'wmoUnit:percent',
241
+ value: 40,
242
+ },
243
+ windSpeed: '1 to 5 mph',
244
+ windDirection: 'W',
245
+ icon: 'https://api.weather.gov/icons/land/day/few/tsra_hi,40?size=medium',
246
+ shortForecast: 'Sunny then Chance Showers And Thunderstorms',
247
+ detailedForecast: 'A slight chance of rain showers between 1pm and 2pm, then a chance of showers and thunderstorms. Sunny, with a high near 85. Chance of precipitation is 40%.',
248
+ },
249
+ {
250
+ number: 14,
251
+ name: 'Thursday Night',
252
+ startTime: '2025-05-15T18:00:00-04:00',
253
+ endTime: '2025-05-16T06:00:00-04:00',
254
+ isDaytime: false,
255
+ temperature: 62,
256
+ temperatureUnit: 'F',
257
+ temperatureTrend: '',
258
+ probabilityOfPrecipitation: {
259
+ unitCode: 'wmoUnit:percent',
260
+ value: 30,
261
+ },
262
+ windSpeed: '3 mph',
263
+ windDirection: 'W',
264
+ icon: 'https://api.weather.gov/icons/land/night/tsra_hi,30/sct?size=medium',
265
+ shortForecast: 'Chance Showers And Thunderstorms then Partly Cloudy',
266
+ detailedForecast: 'A chance of showers and thunderstorms before 11pm. Partly cloudy, with a low around 62. Chance of precipitation is 30%.',
267
+ },
268
+ ];
@@ -1,18 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { HomefileMonitoring, HomeMonitor, HomeMonitorSteps, Notifications, } from '../../components';
2
+ import { HomefileMonitoring, HomeMonitor, HomeMonitorSteps, WeatherWidget, } from '../../components';
3
3
  import { Box, Flex, Stack } from '@chakra-ui/react';
4
4
  import { action } from '@storybook/addon-actions';
5
- import { menuMock } from '../../mocks';
5
+ import { menuMock, weatherDataMock } from '../../mocks';
6
+ import { mapForecastToWidget } from '../../utils';
6
7
  export default {
7
8
  title: 'Components/HomeAssistant',
8
9
  component: HomeMonitor,
9
10
  decorators: [
10
- (Story) => (_jsx(Box, { p: "base", w: ['full', '669px'], h: "477px", children: _jsx(Story, {}) })),
11
+ (Story) => (_jsx(Box, { p: "base", w: ['full', '800px'], h: "fit-content", children: _jsx(Story, {}) })),
11
12
  ],
12
13
  };
13
14
  export const HomeMonitorComponent = () => {
14
15
  const handleAlertClick = (step) => {
15
16
  action('onStepClick')(step);
16
17
  };
17
- return (_jsx(HomeMonitor, { children: _jsxs(Stack, { spacing: "base", children: [_jsxs(Flex, { gap: "base", children: [_jsx(HomefileMonitoring, {}), _jsx(Notifications, { date: "10-10-24", local: "TX - Houston" })] }), _jsx(HomeMonitorSteps, { menuItems: menuMock, stepsWithAlerts: [], onStepClick: handleAlertClick })] }) }));
18
+ const weatherData = mapForecastToWidget(weatherDataMock, 'TX, Houston');
19
+ return (_jsx(HomeMonitor, { children: _jsxs(Stack, { spacing: "base", children: [_jsxs(Flex, { gap: "base", children: [_jsx(HomefileMonitoring, {}), _jsx(WeatherWidget, Object.assign({}, weatherData))] }), _jsx(HomeMonitorSteps, { menuItems: menuMock, stepsWithAlerts: [], onStepClick: handleAlertClick })] }) }));
18
20
  };
@@ -0,0 +1,3 @@
1
+ import { ForecastPeriodI, WeatherWidgetI } from '../interfaces';
2
+ export declare function mapForecastToWidget(periods: ForecastPeriodI[], location: string): WeatherWidgetI;
3
+ export declare function extractCodeFromUrl(iconUrl: string): string;
@@ -0,0 +1,60 @@
1
+ import { parseISO, format } from 'date-fns';
2
+ export function mapForecastToWidget(periods, location) {
3
+ var _a, _b, _c, _d;
4
+ if (!periods.length) {
5
+ throw new Error('Nenhum período disponível para mapping');
6
+ }
7
+ // --- HEADER DATE ---
8
+ const todayDate = parseISO(periods[0].startTime);
9
+ const headerDate = format(todayDate, 'EEEE, MMMM do')
10
+ .toUpperCase()
11
+ .replace(',', '');
12
+ // --- CURRENT CONDITIONS ---
13
+ const day0 = (_a = periods.find((p) => p.isDaytime)) !== null && _a !== void 0 ? _a : periods[0];
14
+ const night0 = (_c = (_b = periods.find((p) => !p.isDaytime &&
15
+ format(parseISO(p.startTime), 'yyyy-MM-dd') ===
16
+ format(parseISO(day0.startTime), 'yyyy-MM-dd'))) !== null && _b !== void 0 ? _b : periods.find((p) => !p.isDaytime)) !== null && _c !== void 0 ? _c : day0;
17
+ console.log({ night0 });
18
+ const currentTemp = day0.temperature;
19
+ const currentIcon = day0.icon;
20
+ const highTemp = day0.temperature;
21
+ const lowTemp = night0.temperature;
22
+ // --- DETAILS ---
23
+ const precipitation = (_d = day0.probabilityOfPrecipitation.value) !== null && _d !== void 0 ? _d : 0;
24
+ const wind = `${day0.windDirection} ${day0.windSpeed}`;
25
+ const humidity = undefined;
26
+ // --- 5-DAY FORECAST ---
27
+ const dayPeriods = periods.filter((p) => p.isDaytime).slice(1, 6);
28
+ const forecast = dayPeriods.map((p) => {
29
+ var _a;
30
+ const night = periods.find((n) => !n.isDaytime &&
31
+ format(parseISO(n.startTime), 'yyyy-MM-dd') ===
32
+ format(parseISO(p.startTime), 'yyyy-MM-dd'));
33
+ const low = (_a = night === null || night === void 0 ? void 0 : night.temperature) !== null && _a !== void 0 ? _a : p.temperature;
34
+ const icon = p.icon;
35
+ const day = format(parseISO(p.startTime), 'EEE').toUpperCase(); // "TUE"
36
+ return { day, icon, high: p.temperature, low };
37
+ });
38
+ return {
39
+ header: { date: headerDate, location },
40
+ current: {
41
+ temp: currentTemp,
42
+ icon: currentIcon,
43
+ high: highTemp,
44
+ low: lowTemp,
45
+ },
46
+ details: { precipitation, humidity, wind },
47
+ forecast,
48
+ };
49
+ }
50
+ export function extractCodeFromUrl(iconUrl) {
51
+ try {
52
+ const parsed = new URL(iconUrl);
53
+ const segments = parsed.pathname.split('/');
54
+ const raw = segments[segments.length - 1] || '';
55
+ return raw.split(',')[0].toLowerCase();
56
+ }
57
+ catch (_a) {
58
+ return '';
59
+ }
60
+ }
@@ -15,3 +15,4 @@ export * from './ShowingText.utils';
15
15
  export * from './Styles.utils';
16
16
  export * from './Validations.utils';
17
17
  export * from './ViewPort.utils';
18
+ export * from './Weather.utils';
@@ -15,3 +15,4 @@ export * from './ShowingText.utils';
15
15
  export * from './Styles.utils';
16
16
  export * from './Validations.utils';
17
17
  export * from './ViewPort.utils';
18
+ export * from './Weather.utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homefile/components-v2",
3
- "version": "2.14.32",
3
+ "version": "2.15.0",
4
4
  "author": "Homefile",
5
5
  "license": "UNLICENSED",
6
6
  "typings": "dist/index.d.ts",
@@ -0,0 +1,26 @@
1
+ import { Text, VStack } from '@chakra-ui/react'
2
+
3
+ interface WeatherDetailProps {
4
+ label: string
5
+ value?: string | number
6
+ }
7
+
8
+ export const WeatherDetail = ({ label, value }: WeatherDetailProps) => {
9
+ if (!value) return null // Não renderiza se o valor for undefined ou null
10
+
11
+ return (
12
+ <VStack
13
+ spacing="0"
14
+ align="start"
15
+ fontFamily="secondary"
16
+ textTransform="uppercase"
17
+ >
18
+ <Text fontSize="xs" lineHeight="1">
19
+ {label}
20
+ </Text>
21
+ <Text fontSize="xs" lineHeight="1">
22
+ {value}
23
+ </Text>
24
+ </VStack>
25
+ )
26
+ }
@@ -0,0 +1,141 @@
1
+ import { PropsWithChildren } from 'react'
2
+ import { WeatherWidgetI } from '@/interfaces'
3
+ import {
4
+ Stack,
5
+ Flex,
6
+ Box,
7
+ Text,
8
+ HStack,
9
+ VStack,
10
+ Divider,
11
+ chakra,
12
+ } from '@chakra-ui/react'
13
+ import { extractCodeFromUrl } from '@/utils'
14
+ import {
15
+ LuSnowflake,
16
+ LuSun,
17
+ LuCloudSun,
18
+ LuCloudy,
19
+ LuCloud,
20
+ LuCloudRain,
21
+ LuCloudLightning,
22
+ } from 'react-icons/lu'
23
+ import { colors } from '@/theme/colors'
24
+
25
+ const weatherIconMap: Record<
26
+ string,
27
+ React.FC<{ size?: number; color?: string }>
28
+ > = {
29
+ skc: LuSun,
30
+ few: LuCloudSun,
31
+ sct: LuCloud,
32
+ bkn: LuCloudy,
33
+ ovc: LuCloudy,
34
+ rain: LuCloudRain,
35
+ tsra: LuCloudLightning,
36
+ snow: LuSnowflake,
37
+ }
38
+
39
+ export const WeatherWidget = ({
40
+ current,
41
+ details,
42
+ forecast,
43
+ header,
44
+ }: WeatherWidgetI) => {
45
+ return (
46
+ <Stack spacing="base" p="4" zIndex="2">
47
+ <Flex justify="space-between" align="center">
48
+ <Text fontSize="sm" fontFamily="secondary" textTransform="uppercase">
49
+ {header.date}
50
+ </Text>
51
+ <Text fontSize="sm" fontFamily="secondary" textTransform="uppercase">
52
+ {header.location}
53
+ </Text>
54
+ </Flex>
55
+
56
+ <Stack spacing="0" align="end">
57
+ <HStack align="start" spacing="2">
58
+ <Text
59
+ fontSize="6xl"
60
+ fontWeight="medium"
61
+ lineHeight={1}
62
+ color="gray.4"
63
+ >
64
+ {current.temp}°
65
+ </Text>
66
+ {getWeatherIcon(current.icon, 50)}
67
+ </HStack>
68
+ <Text fontSize="md">
69
+ <chakra.span color="gray.2">H </chakra.span> {current.high}° &nbsp;
70
+ <chakra.span color="gray.2">L </chakra.span>
71
+ {current.low}°
72
+ </Text>
73
+ </Stack>
74
+
75
+ <Divider borderColor="gray.2" borderStyle="dashed" />
76
+
77
+ <Flex justify="space-between">
78
+ <VStack spacing="0" align="start">
79
+ <WeatherDetailText>Precipitation</WeatherDetailText>
80
+ {details.humidity && <WeatherDetailText>Humidity</WeatherDetailText>}
81
+ <WeatherDetailText>Wind</WeatherDetailText>
82
+ </VStack>
83
+ <VStack spacing="0" align="start">
84
+ <WeatherDetailText>{details.precipitation}%</WeatherDetailText>
85
+ {details.humidity && (
86
+ <WeatherDetailText>{details.humidity}%</WeatherDetailText>
87
+ )}
88
+ <WeatherDetailText>{details.wind}</WeatherDetailText>
89
+ </VStack>
90
+ </Flex>
91
+
92
+ <Flex justify="space-between" gap="1">
93
+ {forecast.map((f) => (
94
+ <VStack
95
+ key={f.day}
96
+ spacing="0"
97
+ border="1px solid"
98
+ borderColor="gray.2"
99
+ borderRadius="sm"
100
+ >
101
+ <Text
102
+ fontFamily="secondary"
103
+ textTransform="uppercase"
104
+ fontSize="xxs"
105
+ color="gray.2"
106
+ >
107
+ {f.day}
108
+ </Text>
109
+ <Divider borderColor="gray.2" />
110
+ <Stack spacing="0" py="1" px="2" align="center">
111
+ {getWeatherIcon(f.icon, 16, colors.gray[3])}
112
+ <Text fontSize="sm" fontWeight="medium" mb="-1">
113
+ {f.high}°
114
+ </Text>
115
+ <WeatherDetailText>L {f.low}°</WeatherDetailText>
116
+ </Stack>
117
+ </VStack>
118
+ ))}
119
+ </Flex>
120
+ </Stack>
121
+ )
122
+ }
123
+
124
+ const WeatherDetailText = ({ children }: PropsWithChildren) => {
125
+ return (
126
+ <Text
127
+ fontFamily="secondary"
128
+ textTransform="uppercase"
129
+ fontSize="xs"
130
+ lineHeight="1.2"
131
+ >
132
+ {children}
133
+ </Text>
134
+ )
135
+ }
136
+
137
+ const getWeatherIcon = (iconUrl: string, size = 48, color = colors.gray[4]) => {
138
+ const code = extractCodeFromUrl(iconUrl)
139
+ const IconComponent = weatherIconMap[code] || LuSun
140
+ return <IconComponent size={size} color={color} />
141
+ }
@@ -3,6 +3,7 @@ export * from './AlertHeader'
3
3
  export * from './AlertTemplate'
4
4
  export * from './AlertTitle'
5
5
  export * from './BaseAlertCard'
6
+ export * from './WeatherWidget'
6
7
  export * from './HomefileMonitoring'
7
8
  export * from './MonitorAlerts'
8
9
  export * from './Notifications'
package/src/index.ts CHANGED
@@ -206,13 +206,18 @@ export {
206
206
  ViewContactPanel,
207
207
  VideoPlayer,
208
208
  VideoPlayerModal,
209
+ WeatherWidget,
209
210
  WellDone,
210
211
  YtdTile,
211
212
  } from './components'
212
213
 
213
214
  export { useCustomToast } from './hooks'
214
215
 
215
- export { randomColor, mapApiObjectToFormFields } from './utils'
216
+ export {
217
+ randomColor,
218
+ mapApiObjectToFormFields,
219
+ mapForecastToWidget,
220
+ } from './utils'
216
221
 
217
222
  export {
218
223
  Contacts,
@@ -0,0 +1,39 @@
1
+ export interface ForecastPeriodI {
2
+ number: number
3
+ name: string
4
+ startTime: string
5
+ endTime: string
6
+ isDaytime: boolean
7
+ temperature: number
8
+ temperatureUnit: string
9
+ probabilityOfPrecipitation: { value: number | null }
10
+ windSpeed: string
11
+ windDirection: string
12
+ icon: string
13
+ shortForecast: string
14
+ detailedForecast: string
15
+ }
16
+
17
+ export interface WeatherWidgetI {
18
+ header: {
19
+ date: string
20
+ location: string
21
+ }
22
+ current: {
23
+ temp: number
24
+ icon: string
25
+ high: number
26
+ low: number
27
+ }
28
+ details: {
29
+ precipitation: number
30
+ humidity?: number
31
+ wind: string
32
+ }
33
+ forecast: Array<{
34
+ day: string
35
+ icon: string
36
+ high: number
37
+ low: number
38
+ }>
39
+ }
@@ -8,3 +8,4 @@ export * from './HomeAssistantSteps.interface'
8
8
  export * from './HomeAssistantTutorial.interface'
9
9
  export * from './HomeMonitorSteps.interface'
10
10
  export * from './MonitorAlerts.interface'
11
+ export * from './WeatherWidget.interface'
@@ -1 +1,2 @@
1
1
  export * from './homeAssistantForms'
2
+ export * from './weather'
@@ -0,0 +1,282 @@
1
+ export const weatherDataMock = [
2
+ {
3
+ number: 1,
4
+ name: 'This Afternoon',
5
+ startTime: '2025-05-09T14:00:00-04:00',
6
+ endTime: '2025-05-09T18:00:00-04:00',
7
+ isDaytime: true,
8
+ temperature: 78,
9
+ temperatureUnit: 'F',
10
+ temperatureTrend: '',
11
+ probabilityOfPrecipitation: {
12
+ unitCode: 'wmoUnit:percent',
13
+ value: null,
14
+ },
15
+ windSpeed: '6 mph',
16
+ windDirection: 'NW',
17
+ icon: 'https://api.weather.gov/icons/land/day/sct?size=medium',
18
+ shortForecast: 'Mostly Sunny',
19
+ detailedForecast:
20
+ 'Mostly sunny, with a high near 78. Northwest wind around 6 mph.',
21
+ },
22
+ {
23
+ number: 2,
24
+ name: 'Tonight',
25
+ startTime: '2025-05-09T18:00:00-04:00',
26
+ endTime: '2025-05-10T06:00:00-04:00',
27
+ isDaytime: false,
28
+ temperature: 46,
29
+ temperatureUnit: 'F',
30
+ temperatureTrend: '',
31
+ probabilityOfPrecipitation: {
32
+ unitCode: 'wmoUnit:percent',
33
+ value: null,
34
+ },
35
+ windSpeed: '2 to 6 mph',
36
+ windDirection: 'N',
37
+ icon: 'https://api.weather.gov/icons/land/night/bkn?size=medium',
38
+ shortForecast: 'Mostly Cloudy',
39
+ detailedForecast:
40
+ 'Mostly cloudy, with a low around 46. North wind 2 to 6 mph.',
41
+ },
42
+ {
43
+ number: 3,
44
+ name: 'Saturday',
45
+ startTime: '2025-05-10T06:00:00-04:00',
46
+ endTime: '2025-05-10T18:00:00-04:00',
47
+ isDaytime: true,
48
+ temperature: 72,
49
+ temperatureUnit: 'F',
50
+ temperatureTrend: '',
51
+ probabilityOfPrecipitation: {
52
+ unitCode: 'wmoUnit:percent',
53
+ value: null,
54
+ },
55
+ windSpeed: '3 mph',
56
+ windDirection: 'NE',
57
+ icon: 'https://api.weather.gov/icons/land/day/bkn?size=medium',
58
+ shortForecast: 'Mostly Cloudy',
59
+ detailedForecast:
60
+ 'Mostly cloudy, with a high near 72. Northeast wind around 3 mph.',
61
+ },
62
+ {
63
+ number: 4,
64
+ name: 'Saturday Night',
65
+ startTime: '2025-05-10T18:00:00-04:00',
66
+ endTime: '2025-05-11T06:00:00-04:00',
67
+ isDaytime: false,
68
+ temperature: 52,
69
+ temperatureUnit: 'F',
70
+ temperatureTrend: '',
71
+ probabilityOfPrecipitation: {
72
+ unitCode: 'wmoUnit:percent',
73
+ value: 20,
74
+ },
75
+ windSpeed: '2 mph',
76
+ windDirection: 'NE',
77
+ icon: 'https://api.weather.gov/icons/land/night/rain,20?size=medium',
78
+ shortForecast: 'Slight Chance Light Rain',
79
+ detailedForecast:
80
+ 'A slight chance of rain between 11pm and 5am, then a slight chance of rain showers. Mostly cloudy, with a low around 52. Northeast wind around 2 mph. Chance of precipitation is 20%. New rainfall amounts less than a tenth of an inch possible.',
81
+ },
82
+ {
83
+ number: 5,
84
+ name: 'Sunday',
85
+ startTime: '2025-05-11T06:00:00-04:00',
86
+ endTime: '2025-05-11T18:00:00-04:00',
87
+ isDaytime: true,
88
+ temperature: 68,
89
+ temperatureUnit: 'F',
90
+ temperatureTrend: '',
91
+ probabilityOfPrecipitation: {
92
+ unitCode: 'wmoUnit:percent',
93
+ value: 30,
94
+ },
95
+ windSpeed: '3 to 7 mph',
96
+ windDirection: 'NE',
97
+ icon: 'https://api.weather.gov/icons/land/day/rain_showers,20/rain,30?size=medium',
98
+ shortForecast: 'Chance Rain Showers then Chance Light Rain',
99
+ detailedForecast:
100
+ 'A chance of rain showers before 2pm, then a chance of rain between 2pm and 4pm, then a chance of rain showers. Mostly cloudy, with a high near 68. Northeast wind 3 to 7 mph. Chance of precipitation is 30%.',
101
+ },
102
+ {
103
+ number: 6,
104
+ name: 'Sunday Night',
105
+ startTime: '2025-05-11T18:00:00-04:00',
106
+ endTime: '2025-05-12T06:00:00-04:00',
107
+ isDaytime: false,
108
+ temperature: 53,
109
+ temperatureUnit: 'F',
110
+ temperatureTrend: '',
111
+ probabilityOfPrecipitation: {
112
+ unitCode: 'wmoUnit:percent',
113
+ value: 50,
114
+ },
115
+ windSpeed: '6 mph',
116
+ windDirection: 'ENE',
117
+ icon: 'https://api.weather.gov/icons/land/night/rain_showers,30/tsra,50?size=medium',
118
+ shortForecast: 'Chance Rain Showers',
119
+ detailedForecast:
120
+ 'A chance of rain showers before 2am, then a chance of showers and thunderstorms. Mostly cloudy, with a low around 53. Chance of precipitation is 50%.',
121
+ },
122
+ {
123
+ number: 7,
124
+ name: 'Monday',
125
+ startTime: '2025-05-12T06:00:00-04:00',
126
+ endTime: '2025-05-12T18:00:00-04:00',
127
+ isDaytime: true,
128
+ temperature: 65,
129
+ temperatureUnit: 'F',
130
+ temperatureTrend: '',
131
+ probabilityOfPrecipitation: {
132
+ unitCode: 'wmoUnit:percent',
133
+ value: 80,
134
+ },
135
+ windSpeed: '8 mph',
136
+ windDirection: 'ENE',
137
+ icon: 'https://api.weather.gov/icons/land/day/tsra,70/tsra,80?size=medium',
138
+ shortForecast: 'Showers And Thunderstorms',
139
+ detailedForecast:
140
+ 'Showers and thunderstorms. Mostly cloudy, with a high near 65. Chance of precipitation is 80%.',
141
+ },
142
+ {
143
+ number: 8,
144
+ name: 'Monday Night',
145
+ startTime: '2025-05-12T18:00:00-04:00',
146
+ endTime: '2025-05-13T06:00:00-04:00',
147
+ isDaytime: false,
148
+ temperature: 59,
149
+ temperatureUnit: 'F',
150
+ temperatureTrend: '',
151
+ probabilityOfPrecipitation: {
152
+ unitCode: 'wmoUnit:percent',
153
+ value: 90,
154
+ },
155
+ windSpeed: '7 mph',
156
+ windDirection: 'E',
157
+ icon: 'https://api.weather.gov/icons/land/night/tsra,90?size=medium',
158
+ shortForecast: 'Showers And Thunderstorms',
159
+ detailedForecast:
160
+ 'Showers and thunderstorms. Mostly cloudy, with a low around 59. Chance of precipitation is 90%.',
161
+ },
162
+ {
163
+ number: 9,
164
+ name: 'Tuesday',
165
+ startTime: '2025-05-13T06:00:00-04:00',
166
+ endTime: '2025-05-13T18:00:00-04:00',
167
+ isDaytime: true,
168
+ temperature: 73,
169
+ temperatureUnit: 'F',
170
+ temperatureTrend: '',
171
+ probabilityOfPrecipitation: {
172
+ unitCode: 'wmoUnit:percent',
173
+ value: 90,
174
+ },
175
+ windSpeed: '6 mph',
176
+ windDirection: 'ESE',
177
+ icon: 'https://api.weather.gov/icons/land/day/tsra,80/tsra,90?size=medium',
178
+ shortForecast: 'Showers And Thunderstorms',
179
+ detailedForecast:
180
+ 'Showers and thunderstorms. Mostly cloudy, with a high near 73. Chance of precipitation is 90%.',
181
+ },
182
+ {
183
+ number: 10,
184
+ name: 'Tuesday Night',
185
+ startTime: '2025-05-13T18:00:00-04:00',
186
+ endTime: '2025-05-14T06:00:00-04:00',
187
+ isDaytime: false,
188
+ temperature: 58,
189
+ temperatureUnit: 'F',
190
+ temperatureTrend: '',
191
+ probabilityOfPrecipitation: {
192
+ unitCode: 'wmoUnit:percent',
193
+ value: 90,
194
+ },
195
+ windSpeed: '1 to 5 mph',
196
+ windDirection: 'E',
197
+ icon: 'https://api.weather.gov/icons/land/night/tsra_sct,90/tsra_sct,50?size=medium',
198
+ shortForecast: 'Showers And Thunderstorms',
199
+ detailedForecast:
200
+ 'Showers and thunderstorms. Mostly cloudy, with a low around 58. Chance of precipitation is 90%.',
201
+ },
202
+ {
203
+ number: 11,
204
+ name: 'Wednesday',
205
+ startTime: '2025-05-14T06:00:00-04:00',
206
+ endTime: '2025-05-14T18:00:00-04:00',
207
+ isDaytime: true,
208
+ temperature: 79,
209
+ temperatureUnit: 'F',
210
+ temperatureTrend: '',
211
+ probabilityOfPrecipitation: {
212
+ unitCode: 'wmoUnit:percent',
213
+ value: 80,
214
+ },
215
+ windSpeed: '3 mph',
216
+ windDirection: 'WSW',
217
+ icon: 'https://api.weather.gov/icons/land/day/rain_showers,50/tsra_hi,80?size=medium',
218
+ shortForecast: 'Showers And Thunderstorms',
219
+ detailedForecast:
220
+ 'Rain showers likely before 2pm, then showers and thunderstorms. Partly sunny, with a high near 79. Chance of precipitation is 80%.',
221
+ },
222
+ {
223
+ number: 12,
224
+ name: 'Wednesday Night',
225
+ startTime: '2025-05-14T18:00:00-04:00',
226
+ endTime: '2025-05-15T06:00:00-04:00',
227
+ isDaytime: false,
228
+ temperature: 58,
229
+ temperatureUnit: 'F',
230
+ temperatureTrend: '',
231
+ probabilityOfPrecipitation: {
232
+ unitCode: 'wmoUnit:percent',
233
+ value: 70,
234
+ },
235
+ windSpeed: '2 mph',
236
+ windDirection: 'W',
237
+ icon: 'https://api.weather.gov/icons/land/night/tsra_hi,70/tsra_hi?size=medium',
238
+ shortForecast: 'Showers And Thunderstorms Likely',
239
+ detailedForecast:
240
+ 'Showers and thunderstorms likely before 1am. Partly cloudy, with a low around 58. Chance of precipitation is 70%.',
241
+ },
242
+ {
243
+ number: 13,
244
+ name: 'Thursday',
245
+ startTime: '2025-05-15T06:00:00-04:00',
246
+ endTime: '2025-05-15T18:00:00-04:00',
247
+ isDaytime: true,
248
+ temperature: 85,
249
+ temperatureUnit: 'F',
250
+ temperatureTrend: '',
251
+ probabilityOfPrecipitation: {
252
+ unitCode: 'wmoUnit:percent',
253
+ value: 40,
254
+ },
255
+ windSpeed: '1 to 5 mph',
256
+ windDirection: 'W',
257
+ icon: 'https://api.weather.gov/icons/land/day/few/tsra_hi,40?size=medium',
258
+ shortForecast: 'Sunny then Chance Showers And Thunderstorms',
259
+ detailedForecast:
260
+ 'A slight chance of rain showers between 1pm and 2pm, then a chance of showers and thunderstorms. Sunny, with a high near 85. Chance of precipitation is 40%.',
261
+ },
262
+ {
263
+ number: 14,
264
+ name: 'Thursday Night',
265
+ startTime: '2025-05-15T18:00:00-04:00',
266
+ endTime: '2025-05-16T06:00:00-04:00',
267
+ isDaytime: false,
268
+ temperature: 62,
269
+ temperatureUnit: 'F',
270
+ temperatureTrend: '',
271
+ probabilityOfPrecipitation: {
272
+ unitCode: 'wmoUnit:percent',
273
+ value: 30,
274
+ },
275
+ windSpeed: '3 mph',
276
+ windDirection: 'W',
277
+ icon: 'https://api.weather.gov/icons/land/night/tsra_hi,30/sct?size=medium',
278
+ shortForecast: 'Chance Showers And Thunderstorms then Partly Cloudy',
279
+ detailedForecast:
280
+ 'A chance of showers and thunderstorms before 11pm. Partly cloudy, with a low around 62. Chance of precipitation is 30%.',
281
+ },
282
+ ]
@@ -4,17 +4,19 @@ import {
4
4
  HomeMonitor,
5
5
  HomeMonitorSteps,
6
6
  Notifications,
7
+ WeatherWidget,
7
8
  } from '@/components'
8
9
  import { Box, Flex, Stack } from '@chakra-ui/react'
9
10
  import { action } from '@storybook/addon-actions'
10
- import { menuMock } from '@/mocks'
11
+ import { menuMock, weatherDataMock } from '@/mocks'
12
+ import { mapForecastToWidget } from '@/utils'
11
13
 
12
14
  export default {
13
15
  title: 'Components/HomeAssistant',
14
16
  component: HomeMonitor,
15
17
  decorators: [
16
18
  (Story: any) => (
17
- <Box p="base" w={['full', '669px']} h="477px">
19
+ <Box p="base" w={['full', '800px']} h="fit-content">
18
20
  <Story />
19
21
  </Box>
20
22
  ),
@@ -25,12 +27,13 @@ export const HomeMonitorComponent = () => {
25
27
  const handleAlertClick = (step: number) => {
26
28
  action('onStepClick')(step)
27
29
  }
30
+ const weatherData = mapForecastToWidget(weatherDataMock, 'TX, Houston')
28
31
  return (
29
32
  <HomeMonitor>
30
33
  <Stack spacing="base">
31
34
  <Flex gap="base">
32
35
  <HomefileMonitoring />
33
- <Notifications date="10-10-24" local="TX - Houston" />
36
+ <WeatherWidget {...weatherData} />
34
37
  </Flex>
35
38
  <HomeMonitorSteps
36
39
  menuItems={menuMock}
@@ -0,0 +1,81 @@
1
+ import { parseISO, format } from 'date-fns'
2
+ import { ForecastPeriodI, WeatherWidgetI } from '@/interfaces'
3
+
4
+ export function mapForecastToWidget(
5
+ periods: ForecastPeriodI[],
6
+ location: string
7
+ ): WeatherWidgetI {
8
+ if (!periods.length) {
9
+ throw new Error('Nenhum período disponível para mapping')
10
+ }
11
+
12
+ // --- HEADER DATE ---
13
+ const todayDate = parseISO(periods[0].startTime)
14
+ const headerDate = format(todayDate, 'EEEE, MMMM do')
15
+ .toUpperCase()
16
+ .replace(',', '')
17
+
18
+ // --- CURRENT CONDITIONS ---
19
+ const day0 = periods.find((p) => p.isDaytime) ?? periods[0]
20
+ const night0 =
21
+ periods.find(
22
+ (p) =>
23
+ !p.isDaytime &&
24
+ format(parseISO(p.startTime), 'yyyy-MM-dd') ===
25
+ format(parseISO(day0.startTime), 'yyyy-MM-dd')
26
+ ) ??
27
+ periods.find((p) => !p.isDaytime) ??
28
+ day0
29
+
30
+ console.log({ night0 })
31
+
32
+ const currentTemp = day0.temperature
33
+ const currentIcon = day0.icon
34
+ const highTemp = day0.temperature
35
+ const lowTemp = night0.temperature
36
+
37
+ // --- DETAILS ---
38
+ const precipitation = day0.probabilityOfPrecipitation.value ?? 0
39
+ const wind = `${day0.windDirection} ${day0.windSpeed}`
40
+
41
+ const humidity = undefined
42
+
43
+ // --- 5-DAY FORECAST ---
44
+ const dayPeriods = periods.filter((p) => p.isDaytime).slice(1, 6)
45
+
46
+ const forecast = dayPeriods.map((p) => {
47
+ const night = periods.find(
48
+ (n) =>
49
+ !n.isDaytime &&
50
+ format(parseISO(n.startTime), 'yyyy-MM-dd') ===
51
+ format(parseISO(p.startTime), 'yyyy-MM-dd')
52
+ )
53
+ const low = night?.temperature ?? p.temperature
54
+ const icon = p.icon
55
+ const day = format(parseISO(p.startTime), 'EEE').toUpperCase() // "TUE"
56
+ return { day, icon, high: p.temperature, low }
57
+ })
58
+
59
+ return {
60
+ header: { date: headerDate, location },
61
+ current: {
62
+ temp: currentTemp,
63
+ icon: currentIcon,
64
+ high: highTemp,
65
+ low: lowTemp,
66
+ },
67
+ details: { precipitation, humidity, wind },
68
+ forecast,
69
+ }
70
+ }
71
+
72
+ export function extractCodeFromUrl(iconUrl: string): string {
73
+ try {
74
+ const parsed = new URL(iconUrl)
75
+ const segments = parsed.pathname.split('/')
76
+ const raw = segments[segments.length - 1] || ''
77
+ return raw.split(',')[0].toLowerCase()
78
+ } catch {
79
+ return ''
80
+ }
81
+ }
@@ -15,3 +15,4 @@ export * from './ShowingText.utils'
15
15
  export * from './Styles.utils'
16
16
  export * from './Validations.utils'
17
17
  export * from './ViewPort.utils'
18
+ export * from './Weather.utils'