Asset,Alarm,Module Screen is added

This commit is contained in:
2026-08-06 19:03:35 +05:30
parent da78de19c5
commit 2a362a2962
36 changed files with 5527 additions and 269 deletions

49
App.tsx
View File

@@ -1,25 +1,32 @@
import React from 'react'; import React, { useState } from 'react';
import { StatusBar, StyleSheet, View } from 'react-native'; import { View } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context'; import ModuleScreen from './src/screens/ModuleScreen/moduleScreen';
import HomeScreen from './src/screens/HomeScreen/homeScreen'; import AlarmsScreen from './src/screens/AlarmScreen/alarmScreen';
import { COLORS } from './src/constants/color'; import AssetsScreen from './src/screens/AssetsScreen/assetScreen';
import { AssetCard } from './src/components/assetCard'; import HomeScreen from './src/screens/HomeScreen/homeScreen';
import AssetScreen from './src/screens/AssetsScreen/assetScreen'; import BottomTabBar, { TabType } from './src/navigation/bottonTabBar';
export default function App(): React.JSX.Element {
// Use generic type annotation for useState
const [activeTab, setActiveTab] = useState<TabType>('Home');
export default function App() {
return ( return (
<SafeAreaProvider> <View style={{ flex: 1 }}>
<View style={styles.container}>
<StatusBar barStyle="light-content" backgroundColor={COLORS.background} /> {/* SCREEN AREA */}
<AssetScreen /> <View style={{ flex: 1 }}>
{activeTab === 'Home' && <HomeScreen />}
{activeTab === 'Assets' && <AssetsScreen />}
{/* {activeTab === 'Scan' && <ScanScreen />} */}
{activeTab === 'Alarms' && <AlarmsScreen />}
{activeTab === 'More' && <ModuleScreen />}
</View> </View>
</SafeAreaProvider>
);
}
const styles = StyleSheet.create({ {/* BOTTOM TAB BAR */}
container: { <BottomTabBar activeTab={activeTab} setActiveTab={setActiveTab} />
flex: 1,
backgroundColor: COLORS.background, </View>
}, );
}); }

3993
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,9 +11,13 @@
}, },
"dependencies": { "dependencies": {
"@react-native/new-app-screen": "0.86.0", "@react-native/new-app-screen": "0.86.0",
"@react-navigation/bottom-tabs": "^7.18.15",
"@react-navigation/native": "^7.3.15",
"expo-router": "^57.0.11",
"react": "19.2.3", "react": "19.2.3",
"react-native": "0.86.0", "react-native": "0.86.0",
"react-native-safe-area-context": "^5.8.0", "react-native-safe-area-context": "^5.8.1",
"react-native-screens": "^4.26.2",
"react-native-svg": "^15.15.5", "react-native-svg": "^15.15.5",
"react-native-vector-icons": "^10.3.0" "react-native-vector-icons": "^10.3.0"
}, },

View File

@@ -0,0 +1,104 @@
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { COLORS } from '../../constants/color';
import { AlarmCardProps, SeverityLevel } from '../../types/type';
import { styles } from '../../styles/Alarm/alarmcard';
// Map severity levels to designated theme colors
const getSeverityColor = (severity: SeverityLevel): string => {
switch (severity) {
case 'CRITICAL':
return COLORS.red;
case 'HIGH':
return COLORS.red;
case 'MEDIUM':
return COLORS.orange;
case 'LOW':
return COLORS.cyan;
default:
return COLORS.textSecondary;
}
};
export default function AlarmCard ({alarm,onAcknowledge,onAssign,onPressDetails }:AlarmCardProps)
{
const accentColor = getSeverityColor(alarm.severity);
return (
<View
style={[
styles.card,
alarm.isExpanded && { borderColor: accentColor },
]}
>
{/* Vertical Accent Strip */}
<View
style={[
styles.statusIndicator,
{ backgroundColor: accentColor },
]}
/>
<View style={styles.cardContent}>
{/* Header */}
<View style={styles.headerRow}>
<View
style={[
styles.badge,
{ backgroundColor: `${accentColor}20` },
]}
>
<Text
style={[
styles.badgeText,
{ color: accentColor },
]}
>
{alarm.severity}
</Text>
</View>
<Text style={styles.timeAgo}>{alarm.timeAgo}</Text>
</View>
{/* Title */}
<Text style={styles.title}>{alarm.title}</Text>
{/* Details */}
<Text style={styles.details}>{alarm.details}</Text>
{/* Expanded Buttons */}
{alarm.isExpanded && (
<View style={styles.actionRow}>
<TouchableOpacity
style={styles.acknowledgeButton}
onPress={() => onAcknowledge?.(alarm.id)}
>
<Text style={styles.acknowledgeText}>Acknowledge</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.assignButton}
onPress={() => onAssign?.(alarm.id)}
>
<Text style={styles.assignText}>Assign</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.iconButton}
onPress={() => onPressDetails?.(alarm.id)}
>
<Ionicons
name="chevron-forward"
size={18}
color={COLORS.textPrimary}
/>
</TouchableOpacity>
</View>
)}
</View>
</View>
);
};

View File

@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { View, Text } from "react-native"; import { View, Text } from "react-native";
import { Asset, AssetCardProps } from "../types/type"; import { Asset, AssetCardProps } from "../../types/type";
import { styles } from "../styles/AssetCard"; import { styles } from "../../styles/Asset/AssetCard";

View File

@@ -1,8 +1,8 @@
import React from "react"; import React from "react";
import { View, TextInput } from "react-native"; import { View, TextInput } from "react-native";
import { COLORS } from "../constants/color"; import { COLORS } from "../../constants/color";
import { styles } from "../styles/SearchbarStyles"; import { styles } from "../../styles/Home/SearchbarStyles";
import {SearchBarProps} from "../types/type" import {SearchBarProps} from "../../types/type"

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native'; import { View, Text, TouchableOpacity } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons'; import Ionicons from 'react-native-vector-icons/Ionicons';
import { styles } from '../styles/ActionGridStyles'; import { styles } from '../../styles/Home/ActionGridStyles';
import { actions } from '../constants/data'; import { actions } from '../../constants/data';

View File

@@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native'; import { View, Text, TouchableOpacity } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons'; import Ionicons from 'react-native-vector-icons/Ionicons';
import { COLORS } from '../constants/color'; import { COLORS } from '../../constants/color';
import { HeaderProps } from '../types/type'; import { HeaderProps } from '../../types/type';
import { styles } from '../styles/HeaderStyles'; import { styles } from '../../styles/Home/HeaderStyles';

View File

@@ -2,9 +2,9 @@ import React from 'react';
import { View, Text } from 'react-native'; import { View, Text } from 'react-native';
import Svg, { Circle } from 'react-native-svg'; import Svg, { Circle } from 'react-native-svg';
import { COLORS } from '../constants/color'; import { COLORS } from '../../constants/color';
import { styles } from '../styles/SiteHealthCardStyles'; import { styles } from '../../styles/Home/SiteHealthCardStyles';
import Card from '../utils/card'; import Card from '../common/card';
export default function SiteHealthCard() { export default function SiteHealthCard() {
return ( return (

View File

@@ -2,9 +2,9 @@ import React from 'react';
import { View, Text } from 'react-native'; import { View, Text } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons'; import Ionicons from 'react-native-vector-icons/Ionicons';
import { StatCardProps } from '../types/type'; import { StatCardProps } from '../../types/type';
import Card from '../utils/card'; import Card from '../common/card';
import { styles } from '../styles/StatCardStyle'; import { styles } from '../../styles/StatCardStyle';

View File

@@ -0,0 +1,76 @@
import React from 'react';
import { Text, TouchableOpacity, StyleSheet, View, Platform } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { COLORS } from '../../constants/color';
import Card from '../common/card';
export interface ModuleItem {
id: string;
title: string;
iconName: string;
iconColor: string;
}
interface ModuleTileProps {
module: ModuleItem;
onPress?: (module: ModuleItem) => void;
}
export const ModuleTile: React.FC<ModuleTileProps> = ({ module, onPress }) => {
return (
<TouchableOpacity
activeOpacity={0.7}
style={styles.touchable}
onPress={() => onPress?.(module)}
>
<Card style={styles.cardOverride}>
<View style={styles.iconContainer}>
<Ionicons name={module.iconName} size={28} color={module.iconColor} />
</View>
<Text style={styles.title} numberOfLines={2}>
{module.title}
</Text>
</Card>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
touchable: {
width: '30.5%',
},
cardOverride: {
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 16,
paddingHorizontal: 8,
height: 100,
borderRadius: 16,
backgroundColor: '#162032', // Dark card background
// --- BORDER STYLING ---
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.08)', // Subtle border highlight
// --- SHADOW FOR iOS ---
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.35,
shadowRadius: 6,
// --- SHADOW FOR ANDROID ---
elevation: 6,
},
iconContainer: {
marginBottom: 8,
alignItems: 'center',
justifyContent: 'center',
},
title: {
color: '#FFFFFF',
fontSize: 12,
fontWeight: '500',
textAlign: 'center',
},
});

View File

@@ -0,0 +1,83 @@
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { NotificationCardProps } from '../../types/type';
import Card from '../common/card';
import { COLORS } from '../../constants/color';
export const NotificationCard: React.FC<NotificationCardProps> = ({
notification,
onPress,
}) => {
return (
<TouchableOpacity
activeOpacity={0.8}
onPress={() => onPress?.(notification.id)}
style={styles.touchable}
>
<Card style={styles.cardOverride}>
{/* Left Icon Container with Soft Colored Background */}
<View style={[styles.iconContainer, { backgroundColor: notification.iconBgColor }]}>
<Ionicons
name={notification.iconName}
size={20}
color={notification.iconColor}
/>
</View>
{/* Text Content */}
<View style={styles.content}>
<Text style={styles.title} numberOfLines={1}>
{notification.title}
</Text>
<Text style={styles.subtitle} numberOfLines={1}>
{notification.subtitle}
</Text>
<Text style={styles.time}>{notification.time}</Text>
</View>
</Card>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
touchable: {
marginBottom: 12,
},
cardOverride: {
flexDirection: 'row',
alignItems: 'flex-start',
padding: 14,
borderRadius: 16,
},
iconContainer: {
width: 42,
height: 42,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
marginRight: 14,
},
content: {
flex: 1,
},
title: {
color: COLORS.textPrimary,
fontSize: 16,
fontWeight: '700',
marginBottom: 3,
},
subtitle: {
color: COLORS.textSecondary,
fontSize: 13,
marginBottom: 4,
},
time: {
color: COLORS.textSecondary,
fontSize: 12,
opacity: 0.8,
},
});

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { styles } from '../styles/cardStyle'; import { styles } from '../../styles/cardStyle';
import { CardProps } from '../types/type'; import { CardProps } from '../../types/type';

View File

@@ -1,4 +1,5 @@
import { Asset } from "../types/type"; import { ModuleItem } from "../components/Module/module";
import { AlarmItem, Asset, NotificationItem } from "../types/type";
import { COLORS } from "./color"; import { COLORS } from "./color";
export const actions = [ export const actions = [
@@ -108,4 +109,169 @@ export const SAMPLE_ASSETS: Asset[] = [
metrics: '412 V · PF 0.97', metrics: '412 V · PF 0.97',
health: 96, health: 96,
}, },
];
export const ALARM_DATA: AlarmItem[] = [
{
id: '1',
severity: 'CRITICAL',
title: 'CH-02 compressor trip',
details: 'Plant Room B1 · discharge 21.4 bar · load shifted to CH-01',
timeAgo: '4m ago',
isExpanded: true, // First item active/expanded with buttons
},
{
id: '2',
severity: 'HIGH',
title: 'AHU-03 supply fan overload',
details: 'Floor 5 · motor current 14.8 A',
timeAgo: '18m ago',
},
{
id: '3',
severity: 'MEDIUM',
title: 'P-07 vibration above baseline',
details: 'Plant Room B1 · 7.2 mm/s RMS',
timeAgo: '41m ago',
},
{
id: '4',
severity: 'MEDIUM',
title: 'IAQ CO₂ high — Zone 4A',
details: 'Floor 4 · 1,180 ppm',
timeAgo: '1h ago',
},
{
id: '5',
severity: 'LOW',
title: 'Water tank T-02 level low',
details: 'Terrace · 34% capacity',
timeAgo: '2h ago',
},
];
export const NOTIFICATIONS_DATA = [
{
title: 'TODAY',
data: [
{
id: '1',
type: 'CRITICAL',
title: 'Critical alarm — CH-02 trip',
subtitle: 'Plant Room B1 · discharge 21.4 bar',
time: '2 min ago',
iconName: 'warning-outline',
iconColor: COLORS.red,
iconBgColor: '#2D1A24',
section: 'TODAY',
},
{
id: '2',
type: 'SETPOINT',
title: 'Setpoint applied — AHU-01',
subtitle: '18.0 °C · via Remote Control',
time: '28 min ago',
iconName: 'locate-outline',
iconColor: COLORS.cyan,
iconBgColor: '#122536',
section: 'TODAY',
},
{
id: '3',
type: 'AIR_QUALITY',
title: 'Air quality — Zone 4A',
subtitle: 'CO₂ 1,180 ppm · damper auto-opened',
time: '1 h ago',
iconName: 'pulse-outline',
iconColor: COLORS.cyan,
iconBgColor: '#122536',
section: 'TODAY',
},
] as NotificationItem[],
},
{
title: 'EARLIER',
data: [
{
id: '4',
type: 'SUCCESS',
title: 'PPM-1198 completed & synced',
subtitle: 'DG-01 monthly · by Suresh K.',
time: 'Yesterday · 17:20',
iconName: 'checkmark',
iconColor: COLORS.green,
iconBgColor: '#0F2C2B',
section: 'EARLIER',
},
] as NotificationItem[],
},
];
export const MODULES_DATA: ModuleItem[] = [
{
id: '1',
title: 'Equipment',
iconName: 'cube-outline',
iconColor: COLORS.green,
},
{
id: '2',
title: 'Optix AI',
iconName: 'sparkles-outline',
iconColor: COLORS.orange,
},
{
id: '3',
title: 'Energy',
iconName: 'flash-outline',
iconColor: COLORS.orange,
},
{
id: '4',
title: 'Remote Ctrl',
iconName: 'locate-outline',
iconColor: COLORS.cyan,
},
{
id: '5',
title: 'Help Desk',
iconName: 'chatbox-outline',
iconColor: COLORS.cyan,
},
{
id: '6',
title: 'Visitors',
iconName: 'person-add-outline',
iconColor: COLORS.green,
},
{
id: '7',
title: 'Attendance',
iconName: 'checkbox-outline',
iconColor: COLORS.green,
},
{
id: '8',
title: 'Air Quality',
iconName: 'pulse-outline',
iconColor: COLORS.cyan,
},
{
id: '9',
title: 'Alerts',
iconName: 'notifications-outline',
iconColor: COLORS.orange,
},
{
id: '10',
title: 'Offline Sync',
iconName: 'sync-outline',
iconColor: COLORS.textSecondary,
},
{
id: '11',
title: 'Profile',
iconName: 'person-outline',
iconColor: COLORS.textSecondary,
},
]; ];

View File

@@ -5,57 +5,89 @@ import Ionicons from 'react-native-vector-icons/Ionicons';
import { styles } from '../styles/BottontabStyle'; import { styles } from '../styles/BottontabStyle';
import { COLORS } from '../constants/color'; import { COLORS } from '../constants/color';
export default function BottomTabBar() { // Define allowed tab names as a TypeScript type
export type TabType = 'Home' | 'Assets' | 'Scan' | 'Alarms' | 'More';
// Interface for component props
interface BottomTabBarProps {
activeTab: TabType;
setActiveTab: (tab: TabType) => void;
}
export default function BottomTabBar({ activeTab, setActiveTab }: BottomTabBarProps) {
return ( return (
<View style={styles.container}> <View style={styles.container}>
{/* Home */} {/* Home */}
<TouchableOpacity style={styles.tab}> <TouchableOpacity
<Ionicons name="home" size={22} color={COLORS.tabActive} /> style={styles.tab}
<Text style={[styles.label, { color: COLORS.tabActive }]}> onPress={() => setActiveTab('Home')}
>
<Ionicons
name={activeTab === 'Home' ? "home" : "home-outline"}
size={22}
color={activeTab === 'Home' ? COLORS.tabActive : COLORS.tabInactive}
/>
<Text style={[styles.label, { color: activeTab === 'Home' ? COLORS.tabActive : COLORS.tabInactive }]}>
Home Home
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
{/* Assets */} {/* Assets */}
<TouchableOpacity style={styles.tab}> <TouchableOpacity
<Ionicons name="cube-outline" size={22} color={COLORS.tabInactive} /> style={styles.tab}
<Text style={styles.label}> onPress={() => setActiveTab('Assets')}
>
<Ionicons
name={activeTab === 'Assets' ? "cube" : "cube-outline"}
size={22}
color={activeTab === 'Assets' ? COLORS.tabActive : COLORS.tabInactive}
/>
<Text style={[styles.label, { color: activeTab === 'Assets' ? COLORS.tabActive : COLORS.tabInactive }]}>
Assets Assets
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
{/* Scan Button */} {/* Scan Button */}
<View style={styles.scanContainer}> <View style={styles.scanContainer}>
<TouchableOpacity style={styles.scanButton}> <TouchableOpacity
style={styles.scanButton}
onPress={() => setActiveTab('Scan')}
>
<Ionicons name="scan" size={28} color="#000" /> <Ionicons name="scan" size={28} color="#000" />
</TouchableOpacity> </TouchableOpacity>
<Text style={[styles.label, { color: COLORS.tabActive }]}> <Text style={[styles.label, { color: activeTab === 'Scan' ? COLORS.tabActive : COLORS.tabInactive }]}>
Scan Scan
</Text> </Text>
</View> </View>
{/* Alarms */} {/* Alarms */}
<TouchableOpacity style={styles.tab}> <TouchableOpacity
style={styles.tab}
onPress={() => setActiveTab('Alarms')}
>
<Ionicons <Ionicons
name="notifications-outline" name={activeTab === 'Alarms' ? "notifications" : "notifications-outline"}
size={22} size={22}
color={COLORS.tabInactive} color={activeTab === 'Alarms' ? COLORS.tabActive : COLORS.tabInactive}
/> />
<Text style={styles.label}> <Text style={[styles.label, { color: activeTab === 'Alarms' ? COLORS.tabActive : COLORS.tabInactive }]}>
Alarms Alarms
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
{/* More */} {/* More */}
<TouchableOpacity style={styles.tab}> <TouchableOpacity
style={styles.tab}
onPress={() => setActiveTab('More')}
>
<Ionicons <Ionicons
name="ellipsis-horizontal" name={activeTab === 'More' ? "ellipsis-horizontal" : "ellipsis-horizontal-outline"}
size={22} size={22}
color={COLORS.tabInactive} color={activeTab === 'More' ? COLORS.tabActive : COLORS.tabInactive}
/> />
<Text style={styles.label}> <Text style={[styles.label, { color: activeTab === 'More' ? COLORS.tabActive : COLORS.tabInactive }]}>
More More
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>

View File

@@ -0,0 +1,159 @@
import React from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
SafeAreaView,
ScrollView,
StatusBar,
} from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Svg, { Circle, Path, Line } from 'react-native-svg';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { styles } from '../../styles/Airquality/airqualityScreen';
export default function AirQualityScreen() {
return (
<SafeAreaProvider style={styles.container}>
<StatusBar barStyle="light-content" backgroundColor="#070D18" />
<ScrollView
contentContainerStyle={styles.scrollContent}
showsVerticalScrollIndicator={false}
>
{/* Top Header */}
<View style={styles.header}>
<TouchableOpacity style={styles.backButton} activeOpacity={0.7}>
<Ionicons name="chevron-back" size={20} color="#FFFFFF" />
</TouchableOpacity>
<View style={styles.headerTitleContainer}>
<Text style={styles.headerTitle}>Air Quality</Text>
<Text style={styles.headerSubtitle}>Floor 4 · Zone 4A · live</Text>
</View>
</View>
{/* Main AQI Banner */}
<View style={styles.bannerCard}>
{/* Circular Gauge */}
<View style={styles.gaugeContainer}>
<Svg width={120} height={120} viewBox="0 0 120 120">
{/* Gauge Track */}
<Circle
cx="60"
cy="60"
r="46"
stroke="#1B293E"
strokeWidth="10"
fill="none"
/>
{/* Active Progress Arc */}
<Circle
cx="60"
cy="60"
r="46"
stroke="#F59E0B"
strokeWidth="10"
fill="none"
strokeDasharray="289"
strokeDashoffset="75"
strokeLinecap="round"
transform="rotate(135 60 60)"
/>
</Svg>
<View style={styles.gaugeTextContainer}>
<Text style={styles.aqiValue}>78</Text>
<Text style={styles.aqiLabel}>AQI</Text>
</View>
</View>
{/* Banner Description */}
<View style={styles.bannerDetails}>
<View style={styles.badge}>
<Text style={styles.badgeText}>MODERATE</Text>
</View>
<Text style={styles.bannerDescription}>
CO₂ slightly elevated. Fresh-air damper increased to 35% automatically.
</Text>
</View>
</View>
{/* Metric Cards Grid */}
<View style={styles.grid}>
{/* CO2 Metric */}
<View style={styles.card}>
<Text style={styles.cardTitle}>
CO<Text style={styles.subscript}>2</Text>
</Text>
<View style={styles.valueRow}>
<Text style={[styles.cardValue, { color: '#F59E0B' }]}>1,180</Text>
<Text style={styles.cardUnit}>ppm</Text>
</View>
</View>
{/* PM2.5 Metric */}
<View style={styles.card}>
<Text style={styles.cardTitle}>PM2.5</Text>
<View style={styles.valueRow}>
<Text style={[styles.cardValue, { color: '#10B981' }]}>18</Text>
<Text style={styles.cardUnit}>μg/m³</Text>
</View>
</View>
{/* TVOC Metric */}
<View style={styles.card}>
<Text style={styles.cardTitle}>TVOC</Text>
<View style={styles.valueRow}>
<Text style={[styles.cardValue, { color: '#10B981' }]}>0.31</Text>
<Text style={styles.cardUnit}>ppm</Text>
</View>
</View>
{/* Temp / RH Metric */}
<View style={styles.card}>
<Text style={styles.cardTitle}>Temp / RH</Text>
<View style={styles.valueRow}>
<Text style={[styles.cardValue, { color: '#FFFFFF' }]}>23.4°</Text>
<Text style={styles.secondaryValue}> · 52%</Text>
</View>
</View>
</View>
{/* Chart Section */}
<View style={styles.chartCard}>
<View style={styles.chartHeader}>
<Text style={styles.chartTitle}>
CO<Text style={styles.subscript}>2</Text> · LAST 12H
</Text>
<Text style={styles.chartSubtitle}>peak 1,240 · 14:00</Text>
</View>
<View style={styles.chartContainer}>
<Svg width="100%" height={70} viewBox="0 0 300 70">
{/* Threshold Line */}
<Line
x1="0"
y1="35"
x2="300"
y2="35"
stroke="#B91C1C"
strokeDasharray="4, 4"
strokeWidth="1.5"
opacity={0.6}
/>
{/* Trend Line */}
<Path
d="M 0 55 Q 60 50 120 40 T 240 48 L 300 42"
fill="none"
stroke="#F59E0B"
strokeWidth="3.5"
strokeLinecap="round"
/>
</Svg>
</View>
</View>
</ScrollView>
</SafeAreaProvider>
);
}

View File

@@ -0,0 +1,50 @@
import React, { useState } from 'react';
import {
View,
Text,
FlatList,
StyleSheet,
StatusBar,
} from 'react-native';
import { AlarmItem } from '../../types/type';
import { ALARM_DATA } from '../../constants/data';
import AlarmCard from '../../components/Alarm/alarmCard';
import { COLORS } from '../../constants/color';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { styles } from '../../styles/Alarm/alarmScreen';
export default function AlarmsScreen() {
const [alarms, setAlarms] = useState<AlarmItem[]>(ALARM_DATA);
return (
<SafeAreaProvider style={{ flex: 1, backgroundColor: COLORS.background }}>
<StatusBar barStyle="light-content" backgroundColor={COLORS.background} />
<FlatList
data={alarms}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<AlarmCard
alarm={item}
/>
)}
ListHeaderComponent={
<View style={styles.header}>
<Text style={styles.title}>Alarms</Text>
<Text style={styles.subtitle}>Live event stream</Text>
</View>
}
contentContainerStyle={styles.listContent}
showsVerticalScrollIndicator={false}
/>
</SafeAreaProvider>
);
}

View File

@@ -10,11 +10,12 @@ import {
import { SAMPLE_ASSETS } from '../../constants/data'; import { SAMPLE_ASSETS } from '../../constants/data';
import { COLORS } from '../../constants/color'; import { COLORS } from '../../constants/color';
import { } from '../../types/type'; import { } from '../../types/type';
import { SearchBar } from '../../components/searchbar'; import { SearchBar } from '../../components/Asset/searchbar';
import { AssetCard } from '../../components/assetCard'; import { AssetCard } from '../../components/Asset/assetCard';
import { SafeAreaProvider } from 'react-native-safe-area-context'; import { SafeAreaProvider } from 'react-native-safe-area-context';
import BottomTabBar from '../../navigation/bottonTabBar'; import BottomTabBar from '../../navigation/bottonTabBar';
import { ScrollView } from 'react-native'; import { ScrollView } from 'react-native';
import { styles } from '../../styles/Asset/assetScreen';
@@ -29,9 +30,10 @@ export default function AssetsScreen() {
return ( return (
<SafeAreaProvider style={{ flex: 1, backgroundColor: COLORS.background }}> <SafeAreaProvider style={{ flex: 1, backgroundColor: COLORS.background }}>
<ScrollView>
<StatusBar barStyle="light-content" backgroundColor={COLORS.background} /> <StatusBar barStyle="light-content" backgroundColor={COLORS.background} />
<View style={styles.content}> <View style={styles.content}>
{/* Header Section */} {/* Header Section */}
<Text style={styles.title}>Assets</Text> <Text style={styles.title}>Assets</Text>
<Text style={styles.subtitle}>251 assets · 242 online</Text> <Text style={styles.subtitle}>251 assets · 242 online</Text>
@@ -46,32 +48,11 @@ export default function AssetsScreen() {
renderItem={({ item }) => <AssetCard asset={item} />} renderItem={({ item }) => <AssetCard asset={item} />}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
/> />
</View> </View>
</ScrollView>
<BottomTabBar />
</SafeAreaProvider> </SafeAreaProvider>
); );
} }
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
content: {
flex: 1,
paddingHorizontal: 20,
paddingTop: 16,
},
title: {
color: COLORS.textPrimary,
fontSize: 28,
fontWeight: 'bold',
},
subtitle: {
color: COLORS.textSecondary,
fontSize: 14,
marginTop: 4,
marginBottom: 16,
},
});

View File

@@ -1,16 +1,16 @@
import React from 'react'; import React from 'react';
import { View, StyleSheet, ScrollView,Text } from 'react-native'; import { View, ScrollView,Text } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context'; import { SafeAreaProvider } from 'react-native-safe-area-context';
import { cards } from '../../constants/data'; import { cards } from '../../constants/data';
import { COLORS } from '../../constants/color'; import { COLORS } from '../../constants/color';
import Header from '../../components/header'; import Header from '../../components/Home/header';
import SiteHealthCard from '../../components/siteHealthCard'; import SiteHealthCard from '../../components/Home/siteHealthCard';
import ActionGrid from '../../components/actionGrid'; import ActionGrid from '../../components/Home/actionGrid';
import StatCard from '../../components/statCard'; import StatCard from '../../components/Home/statCard';
import BottomTabBar from '../../navigation/bottonTabBar'; import Card from '../../components/common/card';
import Card from '../../utils/card';
import Ionicons from 'react-native-vector-icons/Ionicons'; import Ionicons from 'react-native-vector-icons/Ionicons';
import styles from '../../styles/Home/homeScreen';
export default function HomeScreen() { export default function HomeScreen() {
return ( return (
@@ -92,7 +92,7 @@ export default function HomeScreen() {
</ScrollView> </ScrollView>
<BottomTabBar />
@@ -103,60 +103,4 @@ export default function HomeScreen() {
); );
}; };
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
scrollContent: {
paddingHorizontal: 16,
paddingTop: 16,
paddingBottom: 20,
},
gridRow: {
flexDirection: 'row',
flexGrow:1,
marginBottom: 8,
gap:10
},
card: {
borderColor: COLORS.orange,
marginHorizontal: 10,
marginTop: 10,
marginBottom: 20,
},
header: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
title: {
color: COLORS.orange,
fontSize: 18,
fontWeight: 'bold',
marginLeft: 8,
},
message: {
color: COLORS.textPrimary,
fontSize: 16,
lineHeight: 24,
marginLeft: 20,
},
});

View File

@@ -0,0 +1,48 @@
import React from 'react';
import {
SafeAreaView,
View,
Text,
ScrollView,
StyleSheet,
StatusBar,
} from 'react-native';
import { COLORS } from '../../constants/color';
import { ModuleTile } from '../../components/Module/module';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { MODULES_DATA } from '../../constants/data';
import styles from '../../styles/Module/module';
export default function ModulesScreen() {
return (
<SafeAreaProvider style={{ flex: 1, backgroundColor: COLORS.background }}>
<StatusBar barStyle="light-content" backgroundColor={COLORS.background} />
<ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
{/* Header Title & Subtitle */}
<View style={styles.header}>
<Text style={styles.title}>All modules</Text>
<Text style={styles.subtitle}>Facility Management & IoT platform</Text>
</View>
{/* 3-Column Grid Container */}
<View style={styles.gridContainer}>
{MODULES_DATA.map((item) => (
<ModuleTile
key={item.id}
module={item}
/>
))}
</View>
</ScrollView>
</SafeAreaProvider>
);
}

View File

@@ -0,0 +1,64 @@
import React, { useState } from 'react';
import {
SafeAreaView,
View,
Text,
SectionList,
TouchableOpacity,
StyleSheet,
StatusBar,
} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { COLORS } from '../../constants/color';
import { NOTIFICATIONS_DATA } from '../../constants/data';
import { NotificationCard } from '../../components/Notification/notificationcard';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { styles } from '../../styles/Notification/notification';
export default function NotificationsScreen({ navigation }: any) {
const [sections, setSections] = useState(NOTIFICATIONS_DATA);
const handleBackPress = () => {
if (navigation) {
navigation.goBack();
}
};
return (
<SafeAreaProvider style={styles.container}>
<StatusBar barStyle="light-content" backgroundColor={COLORS.background} />
{/* Header Bar */}
<View style={styles.headerRow}>
<TouchableOpacity style={styles.backButton} onPress={handleBackPress}>
<Ionicons name="chevron-back" size={20} color={COLORS.textPrimary} />
</TouchableOpacity>
<Text style={styles.headerTitle}>Notifications</Text>
<TouchableOpacity >
<Text style={styles.markAllReadText}>Mark all read</Text>
</TouchableOpacity>
</View>
{/* Grouped Notifications List */}
<SectionList
sections={sections}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <NotificationCard notification={item} />}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.sectionHeader}>{title}</Text>
)}
contentContainerStyle={styles.listContent}
showsVerticalScrollIndicator={false}
stickySectionHeadersEnabled={false}
/>
</SafeAreaProvider>
);
}

View File

@@ -0,0 +1,125 @@
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Switch,
ScrollView,
StatusBar,
} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { styles } from '../../styles/Profile/profile';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function ProfileScreen() {
return (
<SafeAreaProvider style={styles.container}>
<StatusBar barStyle="light-content" backgroundColor="#0A111E" />
<ScrollView contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
{/* Header */}
<View style={styles.header}>
<TouchableOpacity style={styles.backButton} activeOpacity={0.7}>
<Ionicons name="chevron-back" size={20} color="#FFFFFF" />
</TouchableOpacity>
<Text style={styles.headerTitle}>Profile</Text>
</View>
{/* Profile Card Info */}
<View style={styles.profileContainer}>
<View style={styles.avatar}>
<Text style={styles.avatarText}>AM</Text>
</View>
<View style={styles.userInfo}>
<Text style={styles.userName}>Arjun Mehta</Text>
<Text style={styles.userRole}>Facility Engineer · Shift A</Text>
<Text style={styles.userLocation}>Godrej One — Vikhroli</Text>
</View>
</View>
{/* Metrics/Stats Row */}
<View style={styles.statsRow}>
<View style={styles.statCard}>
<Text style={[styles.statValue, { color: '#FFFFFF' }]}>128</Text>
<Text style={styles.statLabel}>WOs closed</Text>
</View>
<View style={styles.statCard}>
<Text style={[styles.statValue, { color: '#10B981' }]}>96%</Text>
<Text style={styles.statLabel}>PPM on-time</Text>
</View>
<View style={styles.statCard}>
<Text style={[styles.statValue, { color: '#F97316' }]}>4.8</Text>
<Text style={styles.statLabel}>Rating</Text>
</View>
</View>
{/* Options Menu Container */}
<View style={styles.menuContainer}>
{/* Push Notifications */}
<View style={styles.menuItem}>
<View style={styles.menuLeft}>
<Ionicons name="notifications-outline" size={22} color="#60A5FA" />
<Text style={styles.menuText}>Push notifications</Text>
</View>
<Switch
trackColor={{ false: '#374151', true: '#10B981' }}
thumbColor="#0F172A"
ios_backgroundColor="#374151"
/>
</View>
<View style={styles.divider} />
{/* Biometric Login */}
<View style={styles.menuItem}>
<View style={styles.menuLeft}>
<Ionicons name="lock-closed-outline" size={22} color="#38BDF8" />
<Text style={styles.menuText}>Biometric login</Text>
</View>
<Switch
trackColor={{ false: '#374151', true: '#10B981' }}
thumbColor="#0F172A"
ios_backgroundColor="#374151"
/>
</View>
<View style={styles.divider} />
{/* Offline Sync */}
<TouchableOpacity style={styles.menuItem} activeOpacity={0.7}>
<View style={styles.menuLeft}>
<Ionicons name="refresh-outline" size={22} color="#34D399" />
<Text style={styles.menuText}>Offline sync</Text>
</View>
<Text style={styles.menuSubtext}>Wi-Fi only</Text>
</TouchableOpacity>
<View style={styles.divider} />
{/* Help & Support */}
<TouchableOpacity style={styles.menuItem} activeOpacity={0.7}>
<View style={styles.menuLeft}>
<Ionicons name="alert-circle-outline" size={22} color="#9CA3AF" />
<Text style={styles.menuText}>Help & support</Text>
</View>
<Ionicons name="chevron-forward" size={18} color="#6B7280" />
</TouchableOpacity>
</View>
{/* Sign Out Button */}
<TouchableOpacity style={styles.signOutButton} activeOpacity={0.8}>
<Ionicons name="log-out-outline" size={20} color="#EF4444" />
<Text style={styles.signOutText}>Sign out</Text>
</TouchableOpacity>
</ScrollView>
</SafeAreaProvider>
);
}

View File

@@ -0,0 +1,164 @@
import { StyleSheet } from "react-native";
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#070D18',
},
scrollContent: {
paddingHorizontal: 18,
paddingTop: 12,
paddingBottom: 24,
},
/* Header */
header: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 20,
},
backButton: {
width: 42,
height: 42,
borderRadius: 12,
backgroundColor: '#152134',
justifyContent: 'center',
alignItems: 'center',
marginRight: 16,
},
headerTitleContainer: {
justifyContent: 'center',
},
headerTitle: {
fontSize: 22,
fontWeight: '700',
color: '#FFFFFF',
},
headerSubtitle: {
fontSize: 13,
color: '#64748B',
marginTop: 2,
},
/* Banner Card */
bannerCard: {
backgroundColor: '#152134',
borderRadius: 20,
padding: 20,
flexDirection: 'row',
alignItems: 'center',
marginBottom: 16,
},
gaugeContainer: {
width: 110,
height: 110,
justifyContent: 'center',
alignItems: 'center',
},
gaugeTextContainer: {
position: 'absolute',
alignItems: 'center',
},
aqiValue: {
fontSize: 32,
fontWeight: '800',
color: '#FFFFFF',
lineHeight: 34,
},
aqiLabel: {
fontSize: 11,
fontWeight: '600',
color: '#64748B',
marginTop: 2,
},
bannerDetails: {
flex: 1,
marginLeft: 12,
alignItems: 'flex-start',
},
badge: {
backgroundColor: 'rgba(245, 158, 11, 0.15)',
paddingHorizontal: 12,
paddingVertical: 5,
borderRadius: 8,
marginBottom: 10,
},
badgeText: {
color: '#F59E0B',
fontSize: 12,
fontWeight: '700',
letterSpacing: 0.5,
},
bannerDescription: {
color: '#94A3B8',
fontSize: 13.5,
lineHeight: 20,
fontWeight: '400',
},
/* Grid Cards */
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 12,
marginBottom: 16,
},
card: {
width: '48.2%',
backgroundColor: '#152134',
borderRadius: 16,
padding: 16,
justifyContent: 'space-between',
height: 100,
},
cardTitle: {
fontSize: 14,
fontWeight: '600',
color: '#8E9BAE',
},
subscript: {
fontSize: 10,
},
valueRow: {
flexDirection: 'row',
alignItems: 'baseline',
},
cardValue: {
fontSize: 26,
fontWeight: '700',
},
cardUnit: {
fontSize: 13,
color: '#64748B',
marginLeft: 6,
fontWeight: '500',
},
secondaryValue: {
fontSize: 14,
color: '#64748B',
fontWeight: '500',
},
/* Chart Card */
chartCard: {
backgroundColor: '#152134',
borderRadius: 20,
padding: 20,
},
chartHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 16,
},
chartTitle: {
fontSize: 13,
fontWeight: '700',
color: '#8E9BAE',
letterSpacing: 0.5,
},
chartSubtitle: {
fontSize: 13,
color: '#64748B',
},
chartContainer: {
height: 70,
justifyContent: 'center',
},
});

View File

@@ -0,0 +1,27 @@
import { StyleSheet } from "react-native";
import { COLORS } from "../../constants/color";
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
listContent: {
paddingHorizontal: 18,
paddingBottom: 24,
},
header: {
paddingTop: 16,
paddingBottom: 16,
},
title: {
color: COLORS.textPrimary,
fontSize: 28,
fontWeight: 'bold',
},
subtitle: {
color: COLORS.textSecondary,
fontSize: 14,
marginTop: 4,
},
});

View File

@@ -0,0 +1,111 @@
import { StyleSheet } from 'react-native';
import { COLORS } from '../../constants/color';
export const styles = StyleSheet.create({
card: {
backgroundColor: COLORS.cardBg,
borderColor: COLORS.cardBorder,
borderWidth: 1,
borderRadius: 16,
marginBottom: 12,
flexDirection: 'row',
overflow: 'hidden',
},
statusIndicator: {
width: 5,
borderTopLeftRadius: 16,
borderBottomLeftRadius: 16,
},
cardContent: {
flex: 1,
padding: 16,
},
headerRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 8,
},
badge: {
paddingHorizontal: 8,
paddingVertical: 3,
borderRadius: 6,
},
badgeText: {
fontSize: 11,
fontWeight: '800',
letterSpacing: 0.5,
},
timeAgo: {
color: COLORS.textSecondary,
fontSize: 13,
},
title: {
color: COLORS.textPrimary,
fontSize: 17,
fontWeight: '700',
marginBottom: 6,
},
details: {
color: COLORS.textSecondary,
fontSize: 14,
lineHeight: 20,
},
actionRow: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 16,
gap: 10,
},
acknowledgeButton: {
backgroundColor: COLORS.tabActive,
paddingVertical: 10,
paddingHorizontal: 16,
borderRadius: 10,
flex: 1,
alignItems: 'center',
},
acknowledgeText: {
color: '#000',
fontWeight: '700',
fontSize: 14,
},
assignButton: {
backgroundColor: '#1E2D42',
borderColor: COLORS.cardBorder,
borderWidth: 1,
paddingVertical: 10,
paddingHorizontal: 16,
borderRadius: 10,
flex: 1,
alignItems: 'center',
},
assignText: {
color: COLORS.textPrimary,
fontWeight: '600',
fontSize: 14,
},
iconButton: {
backgroundColor: '#1E2D42',
borderColor: COLORS.cardBorder,
borderWidth: 1,
padding: 10,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
});

View File

@@ -1,5 +1,5 @@
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { COLORS } from "../constants/color"; import { COLORS } from "../../constants/color";
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
card: { card: {

View File

@@ -0,0 +1,25 @@
import { StyleSheet } from "react-native";
import { COLORS } from "../../constants/color";
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
content: {
flex: 1,
paddingHorizontal: 20,
paddingTop: 16,
},
title: {
color: COLORS.textPrimary,
fontSize: 28,
fontWeight: 'bold',
},
subtitle: {
color: COLORS.textSecondary,
fontSize: 14,
marginTop: 4,
marginBottom: 16,
},
});

View File

@@ -1,5 +1,5 @@
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import { COLORS } from '../constants/color'; import { COLORS } from '../../constants/color';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({

View File

@@ -1,5 +1,5 @@
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import { COLORS } from '../constants/color'; import { COLORS } from '../../constants/color';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({

View File

@@ -0,0 +1,53 @@
// HomeScreen.styles.js
import { StyleSheet } from 'react-native';
import { COLORS } from '../../constants/color';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
scrollContent: {
paddingHorizontal: 16,
paddingTop: 16,
paddingBottom: 20,
},
gridRow: {
flexDirection: 'row',
flexGrow: 1,
marginBottom: 8,
gap: 10,
},
card: {
borderColor: COLORS.orange,
marginHorizontal: 10,
marginTop: 10,
marginBottom: 20,
},
header: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
title: {
color: COLORS.orange,
fontSize: 18,
fontWeight: 'bold',
marginLeft: 8,
},
message: {
color: COLORS.textPrimary,
fontSize: 16,
lineHeight: 24,
marginLeft: 20,
},
});
export default styles;

View File

@@ -1,5 +1,5 @@
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { COLORS } from "../constants/color"; import { COLORS } from "../../constants/color";
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
container: { container: {

View File

@@ -1,5 +1,5 @@
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import { COLORS } from '../constants/color'; import { COLORS } from '../../constants/color';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({

View File

@@ -0,0 +1,38 @@
import { StyleSheet, Platform, StatusBar } from 'react-native';
import { COLORS } from '../../constants/color';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
scrollContent: {
paddingHorizontal: 16,
// Extra top padding ensures content clears notch and status bar
paddingTop: Platform.OS === 'android' ? (StatusBar.currentHeight || 20) + 16 : 24,
paddingBottom: 100, // Safe distance from bottom tab bar
},
header: {
marginTop: 12, // Pushes header down away from top screen edge/time
marginBottom: 20,
},
title: {
color: COLORS.textPrimary,
fontSize: 26,
fontWeight: '700',
letterSpacing: 0.3,
},
subtitle: {
color: COLORS.textSecondary,
fontSize: 14,
marginTop: 4,
},
gridContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start',
gap: 12,
},
});
export default styles;

View File

@@ -0,0 +1,50 @@
import { StyleSheet } from "react-native";
import { COLORS } from "../../constants/color";
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLORS.background,
},
headerRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 14,
},
backButton: {
width: 40,
height: 40,
borderRadius: 12,
backgroundColor: COLORS.cardBg,
borderColor: COLORS.cardBorder,
borderWidth: 1,
alignItems: 'center',
justifyContent: 'center',
},
headerTitle: {
color: COLORS.textPrimary,
fontSize: 22,
fontWeight: '700',
flex: 1,
marginLeft: 14,
},
markAllReadText: {
color: COLORS.orange,
fontSize: 14,
fontWeight: '600',
},
listContent: {
paddingHorizontal: 16,
paddingBottom: 24,
},
sectionHeader: {
color: COLORS.textSecondary,
fontSize: 12,
fontWeight: '700',
letterSpacing: 0.8,
marginTop: 18,
marginBottom: 12,
},
});

View File

@@ -0,0 +1,147 @@
import { StyleSheet } from "react-native";
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0A111E',
},
scrollContent: {
paddingHorizontal: 20,
paddingTop: 16,
paddingBottom: 40,
},
/* Header */
header: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 24,
},
backButton: {
width: 40,
height: 40,
borderRadius: 12,
backgroundColor: '#162235',
justifyContent: 'center',
alignItems: 'center',
marginRight: 16,
},
headerTitle: {
fontSize: 22,
fontWeight: '700',
color: '#FFFFFF',
},
/* User Profile Header */
profileContainer: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 24,
},
avatar: {
width: 64,
height: 64,
borderRadius: 18,
backgroundColor: '#D97706',
justifyContent: 'center',
alignItems: 'center',
marginRight: 16,
},
avatarText: {
fontSize: 22,
fontWeight: '700',
color: '#0F172A',
},
userInfo: {
flex: 1,
justifyContent: 'center',
},
userName: {
fontSize: 22,
fontWeight: '700',
color: '#FFFFFF',
marginBottom: 2,
},
userRole: {
fontSize: 14,
color: '#94A3B8',
marginBottom: 2,
},
userLocation: {
fontSize: 13,
color: '#64748B',
},
/* Stats Cards */
statsRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 24,
gap: 12,
},
statCard: {
flex: 1,
backgroundColor: '#162235',
borderRadius: 16,
paddingVertical: 18,
paddingHorizontal: 10,
alignItems: 'center',
},
statValue: {
fontSize: 24,
fontWeight: '700',
marginBottom: 4,
},
statLabel: {
fontSize: 12,
color: '#64748B',
textAlign: 'center',
},
/* Menu Items Section */
menuContainer: {
backgroundColor: '#162235',
borderRadius: 16,
paddingVertical: 6,
marginBottom: 24,
},
menuItem: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 14,
},
menuLeft: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
menuText: {
fontSize: 15,
fontWeight: '500',
color: '#FFFFFF',
},
menuSubtext: {
fontSize: 14,
color: '#64748B',
},
divider: {
height: 1,
backgroundColor: '#1E2D4A',
marginLeft: 48,
},
/* Sign Out Button */
signOutButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
borderWidth: 1,
borderColor: 'rgba(239, 68, 68, 0.3)',
borderRadius: 16,
paddingVertical: 16,
gap: 10,
},
signOutText: {
fontSize: 16,
fontWeight: '600',
color: '#EF4444',
},
});

View File

@@ -2,6 +2,7 @@ export interface HeaderProps {
userName: string; userName: string;
locationName: string; locationName: string;
badgeCount?: number; badgeCount?: number;
} }
export interface StatCardProps { export interface StatCardProps {
@@ -37,4 +38,40 @@ export interface SearchBarProps {
export interface AssetCardProps { export interface AssetCardProps {
asset: Asset; asset: Asset;
}
export type SeverityLevel = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
export interface AlarmItem {
id: string;
severity: SeverityLevel;
title: string;
details: string;
timeAgo: string;
isExpanded?: boolean;
}
export interface AlarmCardProps {
alarm: AlarmItem;
onAcknowledge?: (id: string) => void;
onAssign?: (id: string) => void;
onPressDetails?: (id: string) => void;
}
export type NotificationType = 'CRITICAL' | 'SETPOINT' | 'AIR_QUALITY' | 'SUCCESS';
export interface NotificationItem {
id: string;
type: NotificationType;
title: string;
subtitle: string;
time: string;
iconName: string;
iconColor: string;
iconBgColor: string;
section: 'TODAY' | 'EARLIER';
isUnread?: boolean;
}
export interface NotificationCardProps {
notification: NotificationItem;
onPress?: (id: string) => void;
} }