@campxdev/react-native-blueprint 0.1.14 → 0.1.16
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.
- package/global.css +672 -0
- package/lib/module/assets/Loading Animation.json +1 -0
- package/lib/module/assets/Success-Tick.json +1 -0
- package/lib/module/assets/lotties/index.js +3 -1
- package/lib/module/assets/lotties/index.js.map +1 -1
- package/lib/module/components/DataDisplay/Accordion/Accordion.js +1 -0
- package/lib/module/components/DataDisplay/Accordion/Accordion.js.map +1 -1
- package/lib/module/components/DataDisplay/AccordionItem/AccordionItem.js +1 -0
- package/lib/module/components/DataDisplay/AccordionItem/AccordionItem.js.map +1 -1
- package/lib/module/components/DataDisplay/Badge/Badge.figma.js +1 -0
- package/lib/module/components/DataDisplay/Badge/Badge.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Badge/Badge.js +1 -0
- package/lib/module/components/DataDisplay/Badge/Badge.js.map +1 -1
- package/lib/module/components/DataDisplay/Banner/Banner.figma.js +25 -0
- package/lib/module/components/DataDisplay/Banner/Banner.figma.js.map +1 -0
- package/lib/module/components/DataDisplay/Banner/Banner.js +101 -0
- package/lib/module/components/DataDisplay/Banner/Banner.js.map +1 -0
- package/lib/module/components/DataDisplay/BannerRow/BannerRow.js +1 -0
- package/lib/module/components/DataDisplay/BannerRow/BannerRow.js.map +1 -1
- package/lib/module/components/DataDisplay/CalendarItem/CalendarItem.js +1 -0
- package/lib/module/components/DataDisplay/CalendarItem/CalendarItem.js.map +1 -1
- package/lib/module/components/DataDisplay/Card/Card.js +1 -0
- package/lib/module/components/DataDisplay/Card/Card.js.map +1 -1
- package/lib/module/components/DataDisplay/Chips/Chips.js +1 -0
- package/lib/module/components/DataDisplay/Chips/Chips.js.map +1 -1
- package/lib/module/components/DataDisplay/ChipsRow/ChipsRow.js +1 -0
- package/lib/module/components/DataDisplay/ChipsRow/ChipsRow.js.map +1 -1
- package/lib/module/components/DataDisplay/DataListItem/DataListItem.js +1 -0
- package/lib/module/components/DataDisplay/DataListItem/DataListItem.js.map +1 -1
- package/lib/module/components/DataDisplay/Datalist/Datalist.js +1 -0
- package/lib/module/components/DataDisplay/Datalist/Datalist.js.map +1 -1
- package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js +15 -0
- package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js.map +1 -0
- package/lib/module/components/DataDisplay/Greeting/Greeting.js +121 -0
- package/lib/module/components/DataDisplay/Greeting/Greeting.js.map +1 -0
- package/lib/module/components/DataDisplay/MonthCalendar/MonthCalendar.figma.js +5 -7
- package/lib/module/components/DataDisplay/MonthCalendar/MonthCalendar.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Separator/Separator.js +1 -0
- package/lib/module/components/DataDisplay/Separator/Separator.js.map +1 -1
- package/lib/module/components/DataDisplay/Skeleton/Skeleton.js +1 -0
- package/lib/module/components/DataDisplay/Skeleton/Skeleton.js.map +1 -1
- package/lib/module/components/DataDisplay/Tooltip/Tooltip.figma.js +1 -0
- package/lib/module/components/DataDisplay/Tooltip/Tooltip.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Tooltip/Tooltip.js +1 -0
- package/lib/module/components/DataDisplay/Tooltip/Tooltip.js.map +1 -1
- package/lib/module/components/Feedback/InfoBar/InfoBar.figma.js +32 -0
- package/lib/module/components/Feedback/InfoBar/InfoBar.figma.js.map +1 -0
- package/lib/module/components/Feedback/InfoBar/InfoBar.js +107 -0
- package/lib/module/components/Feedback/InfoBar/InfoBar.js.map +1 -0
- package/lib/module/components/Feedback/ProgressCircular/Progress-circular.js +1 -0
- package/lib/module/components/Feedback/ProgressCircular/Progress-circular.js.map +1 -1
- package/lib/module/components/Feedback/ProgressLinear/Progress-linear.js +1 -0
- package/lib/module/components/Feedback/ProgressLinear/Progress-linear.js.map +1 -1
- package/lib/module/components/Input/Button/Button.js +99 -43
- package/lib/module/components/Input/Button/Button.js.map +1 -1
- package/lib/module/components/Input/Checkbox/Checkbox.js +1 -0
- package/lib/module/components/Input/Checkbox/Checkbox.js.map +1 -1
- package/lib/module/components/Input/RadioGroup/Radio-Group.figma.js +3 -3
- package/lib/module/components/Input/RadioGroup/Radio-Group.figma.js.map +1 -1
- package/lib/module/components/Input/RadioGroup/Radio-Group.js +1 -0
- package/lib/module/components/Input/RadioGroup/Radio-Group.js.map +1 -1
- package/lib/module/components/Input/Select/Select.js +1 -0
- package/lib/module/components/Input/Select/Select.js.map +1 -1
- package/lib/module/components/Input/TextField/Textfield.figma.js +4 -2
- package/lib/module/components/Input/TextField/Textfield.figma.js.map +1 -1
- package/lib/module/components/Input/TextField/Textfield.js +219 -43
- package/lib/module/components/Input/TextField/Textfield.js.map +1 -1
- package/lib/module/components/Input/Toggle/Toggle.figma.js +32 -0
- package/lib/module/components/Input/Toggle/Toggle.figma.js.map +1 -0
- package/lib/module/components/Input/Toggle/Toggle.js +52 -23
- package/lib/module/components/Input/Toggle/Toggle.js.map +1 -1
- package/lib/module/components/Input/ToggleGroup/Toggle-Group.js +1 -0
- package/lib/module/components/Input/ToggleGroup/Toggle-Group.js.map +1 -1
- package/lib/module/components/Input/switch/Switch.figma.js +1 -0
- package/lib/module/components/Input/switch/Switch.figma.js.map +1 -1
- package/lib/module/components/Input/switch/Switch.js +1 -0
- package/lib/module/components/Input/switch/Switch.js.map +1 -1
- package/lib/module/components/Layout/Tabs/Tabs.figma.js +1 -0
- package/lib/module/components/Layout/Tabs/Tabs.figma.js.map +1 -1
- package/lib/module/components/Layout/Tabs/Tabs.js +1 -0
- package/lib/module/components/Layout/Tabs/Tabs.js.map +1 -1
- package/lib/module/components/Navigation/Appbar/AppBar.figma.js +1 -0
- package/lib/module/components/Navigation/Appbar/AppBar.figma.js.map +1 -1
- package/lib/module/components/Navigation/FloatingAction/Floating-Action.js +1 -0
- package/lib/module/components/Navigation/FloatingAction/Floating-Action.js.map +1 -1
- package/lib/module/components/Navigation/Popover/Popover.figma.js +1 -0
- package/lib/module/components/Navigation/Popover/Popover.figma.js.map +1 -1
- package/lib/module/components/Navigation/Popover/Popover.js +1 -0
- package/lib/module/components/Navigation/Popover/Popover.js.map +1 -1
- package/lib/module/components/ui/Custom-Card.js +1 -0
- package/lib/module/components/ui/Custom-Card.js.map +1 -1
- package/lib/module/components/ui/Dropdown-Menu.js +1 -0
- package/lib/module/components/ui/Dropdown-Menu.js.map +1 -1
- package/lib/module/components/ui/Hover-Card.js +1 -0
- package/lib/module/components/ui/Hover-Card.js.map +1 -1
- package/lib/module/components/ui/Icon.js +1 -0
- package/lib/module/components/ui/Icon.js.map +1 -1
- package/lib/module/components/ui/Input.js +1 -0
- package/lib/module/components/ui/Input.js.map +1 -1
- package/lib/module/components/ui/Menubar.js +1 -0
- package/lib/module/components/ui/Menubar.js.map +1 -1
- package/lib/module/components/ui/Slider.js +1 -0
- package/lib/module/components/ui/Slider.js.map +1 -1
- package/lib/module/components/ui/Table.js +1 -0
- package/lib/module/components/ui/Table.js.map +1 -1
- package/lib/module/components/ui/Toast.js +1 -0
- package/lib/module/components/ui/Toast.js.map +1 -1
- package/lib/module/components/ui/index.js +4 -1
- package/lib/module/components/ui/index.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/patterns/pattern-components/AlertDialogPattern/AlertDialogPattern.js +1 -0
- package/lib/module/patterns/pattern-components/AlertDialogPattern/AlertDialogPattern.js.map +1 -1
- package/lib/module/patterns/pattern-components/AlertPattern/AlertPattern.js +1 -0
- package/lib/module/patterns/pattern-components/AlertPattern/AlertPattern.js.map +1 -1
- package/lib/module/patterns/pattern-components/BottomSheetPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/BottomSheetPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/CalendarPattern/CalendarPattern.figma.js +1 -0
- package/lib/module/patterns/pattern-components/CalendarPattern/CalendarPattern.figma.js.map +1 -1
- package/lib/module/patterns/pattern-components/CalendarPattern/CalendarPattern.js +1 -0
- package/lib/module/patterns/pattern-components/CalendarPattern/CalendarPattern.js.map +1 -1
- package/lib/module/patterns/pattern-components/CalendarPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/CalendarPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/DashboardPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/DashboardPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/EmptyState/EmptyState.js +1 -0
- package/lib/module/patterns/pattern-components/EmptyState/EmptyState.js.map +1 -1
- package/lib/module/patterns/pattern-components/EntityPatternGuided/EntityPatternGuided.js +1 -0
- package/lib/module/patterns/pattern-components/EntityPatternGuided/EntityPatternGuided.js.map +1 -1
- package/lib/module/patterns/pattern-components/EntityPatternGuided/index.js +4 -0
- package/lib/module/patterns/pattern-components/EntityPatternGuided/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/EntityPatternOverview/EntityPatternOverview.js +1 -0
- package/lib/module/patterns/pattern-components/EntityPatternOverview/EntityPatternOverview.js.map +1 -1
- package/lib/module/patterns/pattern-components/EntityPatternStructured/EntityPatternStructured.js +1 -0
- package/lib/module/patterns/pattern-components/EntityPatternStructured/EntityPatternStructured.js.map +1 -1
- package/lib/module/patterns/pattern-components/FormPattern/FormPattern.js +1 -0
- package/lib/module/patterns/pattern-components/FormPattern/FormPattern.js.map +1 -1
- package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.js +38 -0
- package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.js +91 -0
- package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/SuccessPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/SuccessPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/index.js +5 -3
- package/lib/module/patterns/pattern-components/index.js.map +1 -1
- package/package.json +4 -3
- package/src/assets/Loading Animation.json +1 -0
- package/src/assets/Success-Tick.json +1 -0
- package/src/assets/lotties/index.ts +2 -0
- package/src/components/DataDisplay/Accordion/Accordion.tsx +1 -0
- package/src/components/DataDisplay/AccordionItem/AccordionItem.tsx +1 -0
- package/src/components/DataDisplay/Badge/Badge.figma.tsx +1 -0
- package/src/components/DataDisplay/Badge/Badge.tsx +1 -0
- package/src/components/DataDisplay/Banner/Banner.figma.tsx +26 -0
- package/src/components/DataDisplay/Banner/Banner.tsx +108 -0
- package/src/components/DataDisplay/BannerRow/BannerRow.tsx +1 -0
- package/src/components/DataDisplay/CalendarItem/CalendarItem.tsx +1 -0
- package/src/components/DataDisplay/Card/Card.tsx +1 -0
- package/src/components/DataDisplay/Chips/Chips.tsx +1 -0
- package/src/components/DataDisplay/ChipsRow/ChipsRow.tsx +1 -0
- package/src/components/DataDisplay/DataListItem/DataListItem.tsx +1 -0
- package/src/components/DataDisplay/Datalist/Datalist.tsx +1 -0
- package/src/components/DataDisplay/Greeting/Greeting.figma.tsx +12 -0
- package/src/components/DataDisplay/Greeting/Greeting.tsx +154 -0
- package/src/components/DataDisplay/MonthCalendar/MonthCalendar.figma.tsx +7 -11
- package/src/components/DataDisplay/Separator/Separator.tsx +1 -0
- package/src/components/DataDisplay/Skeleton/Skeleton.tsx +1 -0
- package/src/components/DataDisplay/Tooltip/Tooltip.figma.tsx +1 -0
- package/src/components/DataDisplay/Tooltip/Tooltip.tsx +1 -0
- package/src/components/Feedback/InfoBar/InfoBar.figma.tsx +31 -0
- package/src/components/Feedback/InfoBar/InfoBar.tsx +127 -0
- package/src/components/Feedback/ProgressCircular/Progress-circular.tsx +1 -0
- package/src/components/Feedback/ProgressLinear/Progress-linear.tsx +1 -0
- package/src/components/Input/Button/Button.tsx +110 -43
- package/src/components/Input/Checkbox/Checkbox.tsx +1 -0
- package/src/components/Input/RadioGroup/Radio-Group.figma.tsx +3 -3
- package/src/components/Input/RadioGroup/Radio-Group.tsx +1 -0
- package/src/components/Input/Select/Select.tsx +1 -0
- package/src/components/Input/TextField/Textfield.figma.tsx +2 -0
- package/src/components/Input/TextField/Textfield.tsx +280 -48
- package/src/components/Input/Toggle/Toggle.figma.tsx +37 -0
- package/src/components/Input/Toggle/Toggle.tsx +49 -22
- package/src/components/Input/ToggleGroup/Toggle-Group.tsx +1 -0
- package/src/components/Input/switch/Switch.figma.tsx +1 -0
- package/src/components/Input/switch/Switch.tsx +1 -0
- package/src/components/Layout/Tabs/Tabs.figma.tsx +1 -0
- package/src/components/Layout/Tabs/Tabs.tsx +1 -0
- package/src/components/Navigation/Appbar/AppBar.figma.tsx +1 -0
- package/src/components/Navigation/FloatingAction/Floating-Action.tsx +1 -0
- package/src/components/Navigation/Popover/Popover.figma.tsx +1 -0
- package/src/components/Navigation/Popover/Popover.tsx +1 -0
- package/src/components/ui/Custom-Card.tsx +1 -0
- package/src/components/ui/Dropdown-Menu.tsx +1 -0
- package/src/components/ui/Hover-Card.tsx +1 -0
- package/src/components/ui/Icon.tsx +1 -0
- package/src/components/ui/Input.tsx +1 -0
- package/src/components/ui/Menubar.tsx +1 -0
- package/src/components/ui/Slider.tsx +1 -0
- package/src/components/ui/Table.tsx +1 -0
- package/src/components/ui/Toast.tsx +1 -0
- package/src/components/ui/index.ts +5 -1
- package/src/index.tsx +3 -0
- package/src/patterns/pattern-components/AlertDialogPattern/AlertDialogPattern.tsx +1 -0
- package/src/patterns/pattern-components/AlertPattern/AlertPattern.tsx +1 -0
- package/src/patterns/pattern-components/BottomSheetPattern/index.ts +1 -0
- package/src/patterns/pattern-components/CalendarPattern/CalendarPattern.figma.tsx +1 -0
- package/src/patterns/pattern-components/CalendarPattern/CalendarPattern.tsx +1 -0
- package/src/patterns/pattern-components/CalendarPattern/index.ts +1 -0
- package/src/patterns/pattern-components/DashboardPattern/index.ts +1 -0
- package/src/patterns/pattern-components/EmptyState/EmptyState.tsx +1 -0
- package/src/patterns/pattern-components/EntityPatternGuided/EntityPatternGuided.tsx +1 -0
- package/src/patterns/pattern-components/EntityPatternGuided/index.ts +1 -0
- package/src/patterns/pattern-components/EntityPatternOverview/EntityPatternOverview.tsx +1 -0
- package/src/patterns/pattern-components/EntityPatternStructured/EntityPatternStructured.tsx +1 -0
- package/src/patterns/pattern-components/FormPattern/FormPattern.tsx +1 -0
- package/src/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.tsx +38 -0
- package/src/patterns/pattern-components/SuccessPattern/SuccessPattern.tsx +119 -0
- package/src/patterns/pattern-components/SuccessPattern/index.ts +2 -0
- package/src/patterns/pattern-components/index.ts +3 -1
- package/lib/module/components/ui/Greeting-Card.js +0 -392
- package/lib/module/components/ui/Greeting-Card.js.map +0 -1
- package/src/components/ui/Greeting-Card.tsx +0 -471
|
@@ -1,471 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Image,
|
|
4
|
-
Pressable,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
View,
|
|
7
|
-
useColorScheme,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
import { cssInterop } from 'nativewind';
|
|
10
|
-
import { cn } from '../../lib/utils';
|
|
11
|
-
import { CustomCard } from './Custom-Card';
|
|
12
|
-
import { Text } from '../Input/Text/Text';
|
|
13
|
-
|
|
14
|
-
cssInterop(View, { className: 'style' });
|
|
15
|
-
cssInterop(Pressable, { className: 'style' });
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Weather data structure for the greeting card
|
|
19
|
-
*/
|
|
20
|
-
export interface Weather {
|
|
21
|
-
/** Temperature in Celsius */
|
|
22
|
-
temperature: number;
|
|
23
|
-
/** Human-readable weather description (e.g., "Clear Sky", "Rainy") */
|
|
24
|
-
weatherDescription: string;
|
|
25
|
-
/** Path to the weather icon image */
|
|
26
|
-
weatherImage: any;
|
|
27
|
-
/** Weather code from Open-Meteo API */
|
|
28
|
-
weatherCode: number;
|
|
29
|
-
/** Timestamp of last weather update */
|
|
30
|
-
lastUpdated: Date;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Weather icon mappings for different weather conditions
|
|
35
|
-
*/
|
|
36
|
-
const WEATHER_ICONS = {
|
|
37
|
-
sunny: require('../../assets/icons/weather_icons/sunny_weather.png'),
|
|
38
|
-
partlyCloudy: require('../../assets/icons/weather_icons/partly_cloudy.png'),
|
|
39
|
-
foggy: require('../../assets/icons/weather_icons/foggy.png'),
|
|
40
|
-
drizzle: require('../../assets/icons/weather_icons/drizzle.png'),
|
|
41
|
-
rainy: require('../../assets/icons/weather_icons/rainy.png'),
|
|
42
|
-
freezingRain: require('../../assets/icons/weather_icons/freezing_rain.png'),
|
|
43
|
-
showers: require('../../assets/icons/weather_icons/showers.png'),
|
|
44
|
-
thunderstorm: require('../../assets/icons/weather_icons/thunderstorm.png'),
|
|
45
|
-
thunderstormHail: require('../../assets/icons/weather_icons/thunderstorm_hail.png'),
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Converts a weather code from Open-Meteo API to a description and icon
|
|
50
|
-
*
|
|
51
|
-
* @param {number} code - Weather code from Open-Meteo API (0-99)
|
|
52
|
-
* @returns {Object} Object containing description and icon path
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```tsx
|
|
56
|
-
* const weatherInfo = getWeatherDescription(0);
|
|
57
|
-
* // Returns: { description: 'Clear Sky (Sunny)', weatherImage: ... }
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
export function getWeatherDescription(code: number): {
|
|
61
|
-
description: string;
|
|
62
|
-
weatherImage: any;
|
|
63
|
-
} {
|
|
64
|
-
const weatherMap: {
|
|
65
|
-
[key: string]: { description: string; icon: keyof typeof WEATHER_ICONS };
|
|
66
|
-
} = {
|
|
67
|
-
'0': { description: 'Clear Sky (Sunny)', icon: 'sunny' },
|
|
68
|
-
'1,2,3': { description: 'Partly Cloudy', icon: 'partlyCloudy' },
|
|
69
|
-
'45,48': { description: 'Foggy', icon: 'foggy' },
|
|
70
|
-
'51,53,55': { description: 'Drizzle', icon: 'drizzle' },
|
|
71
|
-
'56,57': { description: 'Freezing Drizzle', icon: 'drizzle' },
|
|
72
|
-
'61,63,65': { description: 'Rainy', icon: 'rainy' },
|
|
73
|
-
'66,67': { description: 'Freezing Rain', icon: 'freezingRain' },
|
|
74
|
-
'80,81,82': { description: 'Showers', icon: 'showers' },
|
|
75
|
-
'95': { description: 'Thunderstorm', icon: 'thunderstorm' },
|
|
76
|
-
'96,99': {
|
|
77
|
-
description: 'Thunderstorm with Hail',
|
|
78
|
-
icon: 'thunderstormHail',
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
for (const [codes, info] of Object.entries(weatherMap)) {
|
|
83
|
-
if (codes.split(',').map(Number).includes(code)) {
|
|
84
|
-
return {
|
|
85
|
-
description: info.description,
|
|
86
|
-
weatherImage: WEATHER_ICONS[info.icon],
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return {
|
|
92
|
-
description: 'Unknown Weather',
|
|
93
|
-
weatherImage: WEATHER_ICONS.sunny,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Returns a greeting based on the current time of day
|
|
99
|
-
*
|
|
100
|
-
* @returns {string} Time-appropriate greeting
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```tsx
|
|
104
|
-
* const greeting = getTimeBasedGreeting();
|
|
105
|
-
* // Returns: "Good Morning" (if it's morning)
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
export function getTimeBasedGreeting(): string {
|
|
109
|
-
const hour = new Date().getHours();
|
|
110
|
-
|
|
111
|
-
if (hour >= 5 && hour < 12) {
|
|
112
|
-
return 'Good Morning';
|
|
113
|
-
} else if (hour >= 12 && hour < 17) {
|
|
114
|
-
return 'Good Afternoon';
|
|
115
|
-
} else if (hour >= 17 && hour < 21) {
|
|
116
|
-
return 'Good Evening';
|
|
117
|
-
} else {
|
|
118
|
-
return 'Good Night';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Formats a date to a readable string format
|
|
124
|
-
*
|
|
125
|
-
* @param {Date} date - Date to format
|
|
126
|
-
* @returns {string} Formatted date string (e.g., "Monday, 16 October")
|
|
127
|
-
*/
|
|
128
|
-
export function formatDate(date: Date): string {
|
|
129
|
-
const days = [
|
|
130
|
-
'Sunday',
|
|
131
|
-
'Monday',
|
|
132
|
-
'Tuesday',
|
|
133
|
-
'Wednesday',
|
|
134
|
-
'Thursday',
|
|
135
|
-
'Friday',
|
|
136
|
-
'Saturday',
|
|
137
|
-
];
|
|
138
|
-
const months = [
|
|
139
|
-
'January',
|
|
140
|
-
'February',
|
|
141
|
-
'March',
|
|
142
|
-
'April',
|
|
143
|
-
'May',
|
|
144
|
-
'June',
|
|
145
|
-
'July',
|
|
146
|
-
'August',
|
|
147
|
-
'September',
|
|
148
|
-
'October',
|
|
149
|
-
'November',
|
|
150
|
-
'December',
|
|
151
|
-
];
|
|
152
|
-
|
|
153
|
-
const dayName = days[date.getDay()];
|
|
154
|
-
const day = date.getDate();
|
|
155
|
-
const monthName = months[date.getMonth()];
|
|
156
|
-
|
|
157
|
-
return `${dayName}, ${day} ${monthName}`;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Fetches weather data from Open-Meteo API
|
|
162
|
-
*
|
|
163
|
-
* @param {number} latitude - Latitude coordinate
|
|
164
|
-
* @param {number} longitude - Longitude coordinate
|
|
165
|
-
* @returns {Promise<Weather | null>} Weather data or null if fetch fails
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```tsx
|
|
169
|
-
* const weather = await fetchWeather(37.7749, -122.4194);
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
export async function fetchWeather(
|
|
173
|
-
latitude: number,
|
|
174
|
-
longitude: number
|
|
175
|
-
): Promise<Weather | null> {
|
|
176
|
-
const url = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,weathercode`;
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
const response = await fetch(url);
|
|
180
|
-
|
|
181
|
-
if (response.ok) {
|
|
182
|
-
const data = await response.json();
|
|
183
|
-
|
|
184
|
-
const temperature: number = data.current?.temperature_2m ?? 0;
|
|
185
|
-
const weatherCode: number = data.current?.weathercode ?? 0;
|
|
186
|
-
|
|
187
|
-
const weatherInfo = getWeatherDescription(weatherCode);
|
|
188
|
-
|
|
189
|
-
return {
|
|
190
|
-
temperature,
|
|
191
|
-
weatherDescription: weatherInfo.description,
|
|
192
|
-
weatherImage: weatherInfo.weatherImage,
|
|
193
|
-
weatherCode,
|
|
194
|
-
lastUpdated: new Date(),
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return null;
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error('Failed to fetch weather:', error);
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Props for the GreetingCard component
|
|
207
|
-
*/
|
|
208
|
-
export interface GreetingCardProps {
|
|
209
|
-
/** User's full name to display in the greeting (required) */
|
|
210
|
-
userName: string;
|
|
211
|
-
/** Latitude coordinate for weather fetching (optional - weather shown only when both lat and lng provided) */
|
|
212
|
-
lat?: number;
|
|
213
|
-
/** Longitude coordinate for weather fetching (optional - weather shown only when both lat and lng provided) */
|
|
214
|
-
lng?: number;
|
|
215
|
-
/** Custom greeting message (overrides time-based greeting) */
|
|
216
|
-
customGreeting?: string;
|
|
217
|
-
/** Custom date to display (defaults to current date) */
|
|
218
|
-
date?: Date;
|
|
219
|
-
/** Action button text (e.g., "View Schedule") */
|
|
220
|
-
actionText?: string;
|
|
221
|
-
/** Callback when the card or action button is pressed */
|
|
222
|
-
onPress?: () => void;
|
|
223
|
-
/** Additional CSS classes for the card container */
|
|
224
|
-
className?: string;
|
|
225
|
-
/** Whether to show the action button section */
|
|
226
|
-
showAction?: boolean;
|
|
227
|
-
/** Cache duration in milliseconds (default: 15 minutes) */
|
|
228
|
-
cacheDuration?: number;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* GreetingCard - A personalized greeting card with weather information
|
|
233
|
-
*
|
|
234
|
-
* Displays a personalized greeting with the user's name, current date, and optional
|
|
235
|
-
* weather information fetched from Open-Meteo API. Includes an optional action button
|
|
236
|
-
* (e.g., "View Schedule"). Weather data is automatically cached for 15 minutes.
|
|
237
|
-
*
|
|
238
|
-
* @component
|
|
239
|
-
* @example
|
|
240
|
-
* ```tsx
|
|
241
|
-
* // Basic usage without weather
|
|
242
|
-
* <GreetingCard
|
|
243
|
-
* userName="John Doe"
|
|
244
|
-
* actionText="View Schedule"
|
|
245
|
-
* onPress={() => navigation.navigate('Schedule')}
|
|
246
|
-
* />
|
|
247
|
-
*
|
|
248
|
-
* // With automatic weather fetching (provide both lat and lng)
|
|
249
|
-
* <GreetingCard
|
|
250
|
-
* userName="Jane Smith"
|
|
251
|
-
* lat={37.7749}
|
|
252
|
-
* lng={-122.4194}
|
|
253
|
-
* actionText="View Dashboard"
|
|
254
|
-
* onPress={() => console.log('Card pressed')}
|
|
255
|
-
* />
|
|
256
|
-
*
|
|
257
|
-
* // Custom greeting without action
|
|
258
|
-
* <GreetingCard
|
|
259
|
-
* userName="Alice"
|
|
260
|
-
* customGreeting="Welcome back"
|
|
261
|
-
* showAction={false}
|
|
262
|
-
* />
|
|
263
|
-
* ```
|
|
264
|
-
*
|
|
265
|
-
* @property {string} userName - User's full name to display in greeting (required)
|
|
266
|
-
* @property {number} [lat] - Latitude coordinate for weather fetching (optional)
|
|
267
|
-
* @property {number} [lng] - Longitude coordinate for weather fetching (optional)
|
|
268
|
-
* @property {string} [customGreeting] - Override the time-based greeting
|
|
269
|
-
* @property {Date} [date] - Custom date to display (defaults to current date)
|
|
270
|
-
* @property {string} [actionText="View Details"] - Text for the action button
|
|
271
|
-
* @property {Function} [onPress] - Handler called when card or action is pressed
|
|
272
|
-
* @property {string} [className] - Additional Tailwind classes for styling
|
|
273
|
-
* @property {boolean} [showAction=true] - Whether to show the action button section
|
|
274
|
-
* @property {number} [cacheDuration=900000] - Cache duration in ms (default: 15 min)
|
|
275
|
-
*/
|
|
276
|
-
export function GreetingCard({
|
|
277
|
-
userName,
|
|
278
|
-
lat,
|
|
279
|
-
lng,
|
|
280
|
-
customGreeting,
|
|
281
|
-
date = new Date(),
|
|
282
|
-
actionText = 'View Details',
|
|
283
|
-
onPress,
|
|
284
|
-
className,
|
|
285
|
-
showAction = true,
|
|
286
|
-
cacheDuration = 15 * 60 * 1000, // 15 minutes
|
|
287
|
-
}: GreetingCardProps) {
|
|
288
|
-
const colorScheme = useColorScheme();
|
|
289
|
-
const isDark = colorScheme === 'dark';
|
|
290
|
-
const [weather, setWeather] = React.useState<Weather | null>(null);
|
|
291
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
292
|
-
const cacheRef = React.useRef<{
|
|
293
|
-
data: Weather | null;
|
|
294
|
-
timestamp: number;
|
|
295
|
-
} | null>(null);
|
|
296
|
-
|
|
297
|
-
// Dynamic styles based on theme
|
|
298
|
-
const dynamicStyles = React.useMemo(
|
|
299
|
-
() => ({
|
|
300
|
-
separator: {
|
|
301
|
-
...styles.separator,
|
|
302
|
-
backgroundColor: isDark
|
|
303
|
-
? 'rgba(255, 255, 255, 0.15)'
|
|
304
|
-
: 'rgba(0, 0, 0, 0.1)',
|
|
305
|
-
},
|
|
306
|
-
}),
|
|
307
|
-
[isDark]
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
React.useEffect(() => {
|
|
311
|
-
const loadWeather = async () => {
|
|
312
|
-
if (lat === undefined || lng === undefined) {
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const now = Date.now();
|
|
317
|
-
|
|
318
|
-
// Check cache
|
|
319
|
-
if (
|
|
320
|
-
cacheRef.current &&
|
|
321
|
-
now - cacheRef.current.timestamp < cacheDuration
|
|
322
|
-
) {
|
|
323
|
-
setWeather(cacheRef.current.data);
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
setIsLoading(true);
|
|
328
|
-
|
|
329
|
-
try {
|
|
330
|
-
const weatherData = await fetchWeather(lat, lng);
|
|
331
|
-
setWeather(weatherData);
|
|
332
|
-
cacheRef.current = {
|
|
333
|
-
data: weatherData,
|
|
334
|
-
timestamp: now,
|
|
335
|
-
};
|
|
336
|
-
} catch (error) {
|
|
337
|
-
console.error('Error loading weather:', error);
|
|
338
|
-
} finally {
|
|
339
|
-
setIsLoading(false);
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
loadWeather();
|
|
344
|
-
}, [lat, lng, cacheDuration]);
|
|
345
|
-
|
|
346
|
-
const greeting = customGreeting || getTimeBasedGreeting();
|
|
347
|
-
const formattedDate = formatDate(date);
|
|
348
|
-
|
|
349
|
-
const CardWrapper = onPress ? Pressable : View;
|
|
350
|
-
const wrapperProps = onPress
|
|
351
|
-
? {
|
|
352
|
-
onPress,
|
|
353
|
-
android_ripple: { color: 'rgba(0, 0, 0, 0.1)' },
|
|
354
|
-
}
|
|
355
|
-
: {};
|
|
356
|
-
|
|
357
|
-
return (
|
|
358
|
-
<CardWrapper {...wrapperProps}>
|
|
359
|
-
<CustomCard
|
|
360
|
-
cornerRadius={20}
|
|
361
|
-
cornerSmoothing={1}
|
|
362
|
-
className={cn('border-primary/20 dark:border-primary/30', className)}
|
|
363
|
-
>
|
|
364
|
-
{/* Wrapper with negative margin to counteract CustomCard's default padding */}
|
|
365
|
-
<View style={styles.contentWrapper}>
|
|
366
|
-
{/* Header Section with Greeting and Weather */}
|
|
367
|
-
<View style={styles.headerSection}>
|
|
368
|
-
{/* Greeting Text */}
|
|
369
|
-
<View style={styles.greetingText}>
|
|
370
|
-
<Text className="text-sm font-semibold text-card-foreground dark:text-card-foreground">
|
|
371
|
-
Hi {userName},
|
|
372
|
-
</Text>
|
|
373
|
-
<Text className="mt-1.5 text-xs tracking-wider text-muted-foreground dark:text-muted-foreground">
|
|
374
|
-
{greeting}, {formattedDate}
|
|
375
|
-
</Text>
|
|
376
|
-
</View>
|
|
377
|
-
|
|
378
|
-
{/* Weather Display */}
|
|
379
|
-
{(weather || isLoading) && (
|
|
380
|
-
<View style={styles.weatherContainer}>
|
|
381
|
-
{isLoading ? (
|
|
382
|
-
<Text className="text-xs text-muted-foreground dark:text-muted-foreground">
|
|
383
|
-
Loading...
|
|
384
|
-
</Text>
|
|
385
|
-
) : (
|
|
386
|
-
weather && (
|
|
387
|
-
<>
|
|
388
|
-
<View style={styles.weatherRow}>
|
|
389
|
-
<Image
|
|
390
|
-
source={weather.weatherImage}
|
|
391
|
-
style={styles.weatherIcon}
|
|
392
|
-
resizeMode="contain"
|
|
393
|
-
/>
|
|
394
|
-
<Text className="ml-1 text-xs text-card-foreground dark:text-card-foreground">
|
|
395
|
-
{Math.round(weather.temperature)}° C
|
|
396
|
-
</Text>
|
|
397
|
-
</View>
|
|
398
|
-
<Text className="mt-0.5 text-xs text-muted-foreground/70 dark:text-muted-foreground/70">
|
|
399
|
-
{weather.weatherDescription}
|
|
400
|
-
</Text>
|
|
401
|
-
</>
|
|
402
|
-
)
|
|
403
|
-
)}
|
|
404
|
-
</View>
|
|
405
|
-
)}
|
|
406
|
-
</View>
|
|
407
|
-
|
|
408
|
-
{/* Action Section */}
|
|
409
|
-
{showAction && (
|
|
410
|
-
<>
|
|
411
|
-
<View style={dynamicStyles.separator} />
|
|
412
|
-
<View style={styles.actionSection}>
|
|
413
|
-
<Text className="text-sm font-semibold text-card-foreground dark:text-card-foreground">
|
|
414
|
-
{actionText}
|
|
415
|
-
</Text>
|
|
416
|
-
<Text className="text-2xl text-primary dark:text-primary">
|
|
417
|
-
›
|
|
418
|
-
</Text>
|
|
419
|
-
</View>
|
|
420
|
-
</>
|
|
421
|
-
)}
|
|
422
|
-
</View>
|
|
423
|
-
</CustomCard>
|
|
424
|
-
</CardWrapper>
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
GreetingCard.displayName = 'GreetingCard';
|
|
429
|
-
|
|
430
|
-
const styles = StyleSheet.create({
|
|
431
|
-
weatherIcon: {
|
|
432
|
-
width: 40,
|
|
433
|
-
height: 35,
|
|
434
|
-
},
|
|
435
|
-
contentWrapper: {
|
|
436
|
-
margin: -24, // Counteract CustomCard's default padding of 24
|
|
437
|
-
},
|
|
438
|
-
headerSection: {
|
|
439
|
-
flexDirection: 'row',
|
|
440
|
-
alignItems: 'flex-start',
|
|
441
|
-
justifyContent: 'space-between',
|
|
442
|
-
paddingHorizontal: 20,
|
|
443
|
-
paddingTop: 20,
|
|
444
|
-
paddingBottom: 16,
|
|
445
|
-
},
|
|
446
|
-
greetingText: {
|
|
447
|
-
flex: 1,
|
|
448
|
-
},
|
|
449
|
-
weatherContainer: {
|
|
450
|
-
marginLeft: 12,
|
|
451
|
-
alignItems: 'flex-end',
|
|
452
|
-
},
|
|
453
|
-
weatherRow: {
|
|
454
|
-
flexDirection: 'row',
|
|
455
|
-
alignItems: 'center',
|
|
456
|
-
},
|
|
457
|
-
separator: {
|
|
458
|
-
height: 1,
|
|
459
|
-
marginVertical: 8,
|
|
460
|
-
},
|
|
461
|
-
actionSection: {
|
|
462
|
-
flexDirection: 'row',
|
|
463
|
-
alignItems: 'center',
|
|
464
|
-
justifyContent: 'space-between',
|
|
465
|
-
paddingHorizontal: 20,
|
|
466
|
-
paddingBottom: 12,
|
|
467
|
-
paddingTop: 4,
|
|
468
|
-
},
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
export { WEATHER_ICONS };
|