diff --git a/App.tsx b/App.tsx index 1a9796d..e2ac19e 100644 --- a/App.tsx +++ b/App.tsx @@ -3,13 +3,15 @@ import { StatusBar, StyleSheet, View } from 'react-native'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import HomeScreen from './src/screens/HomeScreen/homeScreen'; import { COLORS } from './src/constants/color'; +import { AssetCard } from './src/components/assetCard'; +import AssetScreen from './src/screens/AssetsScreen/assetScreen'; export default function App() { return ( - + ); diff --git a/src/components/assetCard.tsx b/src/components/assetCard.tsx new file mode 100644 index 0000000..9eeb635 --- /dev/null +++ b/src/components/assetCard.tsx @@ -0,0 +1,60 @@ +import React from "react"; +import { View, Text } from "react-native"; +import { Asset, AssetCardProps } from "../types/type"; +import { styles } from "../styles/AssetCard"; + + + +export const AssetCard = ({ asset }: AssetCardProps) => { + return ( + + + + + + + {asset.name} {asset.type ? `· ${asset.type}` : ""} + + + + + {asset.status} + + + + + {asset.location} + + {asset.metrics} + + + + + {asset.health} + + + health + + + ); +}; \ No newline at end of file diff --git a/src/components/searchbar.tsx b/src/components/searchbar.tsx new file mode 100644 index 0000000..a598ebd --- /dev/null +++ b/src/components/searchbar.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { View, TextInput } from "react-native"; +import { COLORS } from "../constants/color"; +import { styles } from "../styles/SearchbarStyles"; +import {SearchBarProps} from "../types/type" + + + +export const SearchBar = ({ value, onChangeText }: SearchBarProps) => { + return ( + + + + ); +}; \ No newline at end of file diff --git a/src/constants/data.ts b/src/constants/data.ts index 02fafff..2f80d16 100644 --- a/src/constants/data.ts +++ b/src/constants/data.ts @@ -1,3 +1,4 @@ +import { Asset } from "../types/type"; import { COLORS } from "./color"; export const actions = [ @@ -54,4 +55,57 @@ export const cards = [ color: "#47C3FF", icon: "pulse-outline", }, +]; + + +export const SAMPLE_ASSETS: Asset[] = [ + { + id: '1', + name: 'AHU-01', + location: 'Floor 3 · East Wing', + status: 'RUNNING', + statusColor: COLORS.green, + metrics: '18.2 °C · 12.3 kW', + health: 94, + }, + { + id: '2', + name: 'CH-02', + type: 'Chiller', + location: 'Plant Room B1', + status: 'FAULT', + statusColor: COLORS.red, + metrics: '21.4 bar · tripped', + health: 41, + }, + { + id: '3', + name: 'P-07', + type: 'CHW Pump', + location: 'Plant Room B1', + status: 'ATTENTION', + statusColor: COLORS.orange, + metrics: '52 Hz · vibration ↑', + health: 68, + }, + { + id: '4', + name: 'DG-01', + type: 'Genset', + location: 'Basement Yard', + status: 'STANDBY', + statusColor: COLORS.green, + metrics: 'fuel 82% · battery OK', + health: 91, + }, + { + id: '5', + name: 'LP-03', + type: 'LT Panel', + location: 'Ground . Utility', + status: 'RUNNING', + statusColor: COLORS.green, + metrics: '412 V · PF 0.97', + health: 96, + }, ]; \ No newline at end of file diff --git a/src/screens/AssetsScreen/assetScreen.tsx b/src/screens/AssetsScreen/assetScreen.tsx new file mode 100644 index 0000000..a5f5afa --- /dev/null +++ b/src/screens/AssetsScreen/assetScreen.tsx @@ -0,0 +1,77 @@ +import React, { useState } from 'react'; +import { + SafeAreaView, + View, + Text, + FlatList, + StyleSheet, + StatusBar, +} from 'react-native'; +import { SAMPLE_ASSETS } from '../../constants/data'; +import { COLORS } from '../../constants/color'; +import { } from '../../types/type'; +import { SearchBar } from '../../components/searchbar'; +import { AssetCard } from '../../components/assetCard'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; +import BottomTabBar from '../../navigation/bottonTabBar'; +import { ScrollView } from 'react-native'; + + + +export default function AssetsScreen() { + const [search, setSearch] = useState(''); + + const filteredAssets = SAMPLE_ASSETS.filter( + (item) => + item.name.toLowerCase().includes(search.toLowerCase()) || + item.location.toLowerCase().includes(search.toLowerCase()) + ); + + return ( + + + + + {/* Header Section */} + Assets + 251 assets · 242 online + + {/* Search */} + + + {/* Assets List */} + item.id} + renderItem={({ item }) => } + showsVerticalScrollIndicator={false} + /> + + + + + ); +} + +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, + }, +}); \ No newline at end of file diff --git a/src/styles/AssetCard.ts b/src/styles/AssetCard.ts new file mode 100644 index 0000000..29ef5d0 --- /dev/null +++ b/src/styles/AssetCard.ts @@ -0,0 +1,80 @@ +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, + padding: 16, + flexDirection: "row", + alignItems: "center", + marginBottom: 12, + }, + + statusIndicator: { + width: 6, + height: "100%", + borderRadius: 3, + marginRight: 12, + }, + + content: { + flex: 1, + }, + + headerRow: { + flexDirection: "row", + alignItems: "center", + flexWrap: "wrap", + }, + + title: { + color: COLORS.textPrimary, + fontSize: 18, + fontWeight: "700", + marginRight: 8, + }, + + badge: { + paddingHorizontal: 8, + paddingVertical: 2, + borderRadius: 6, + }, + + badgeText: { + fontSize: 11, + fontWeight: "700", + letterSpacing: 0.5, + }, + + location: { + color: COLORS.textSecondary, + fontSize: 14, + marginTop: 4, + }, + + metrics: { + color: COLORS.textSecondary, + fontSize: 14, + marginTop: 6, + fontFamily: "monospace", + }, + + healthContainer: { + alignItems: "center", + justifyContent: "center", + marginLeft: 8, + }, + + healthValue: { + fontSize: 22, + fontWeight: "bold", + }, + + healthLabel: { + color: COLORS.textSecondary, + fontSize: 12, + }, +}); \ No newline at end of file diff --git a/src/styles/SearchbarStyles.ts b/src/styles/SearchbarStyles.ts new file mode 100644 index 0000000..574ce3b --- /dev/null +++ b/src/styles/SearchbarStyles.ts @@ -0,0 +1,19 @@ +import { StyleSheet } from "react-native"; +import { COLORS } from "../constants/color"; + +export const styles = StyleSheet.create({ + container: { + backgroundColor: COLORS.cardBg, + borderColor: COLORS.cardBorder, + borderWidth: 1, + borderRadius: 12, + paddingHorizontal: 16, + height: 48, + justifyContent: "center", + marginBottom: 16, + }, + input: { + color: COLORS.textPrimary, + fontSize: 16, + }, +}); \ No newline at end of file diff --git a/src/types/type.ts b/src/types/type.ts index d930d1e..9246e4f 100644 --- a/src/types/type.ts +++ b/src/types/type.ts @@ -15,4 +15,26 @@ export interface StatCardProps { export interface CardProps { children: React.ReactNode; style?: object; +} + +export type AssetStatus = 'RUNNING' | 'FAULT' | 'ATTENTION' | 'STANDBY'; + +export interface Asset { + id: string; + name: string; + type?: string; + location: string; + status: AssetStatus; + statusColor: string; + metrics: string; + health: number; +} + +export interface SearchBarProps { + value: string; + onChangeText: (text: string) => void; +} + +export interface AssetCardProps { + asset: Asset; } \ No newline at end of file