this is the card imge in web make in react native and make the ui more mordanmake separate file for the card use my theme file for style given in below export const theme = { colors: { primary: '#ab5335', secondary: '#5856D6', accent: '#03DAC6', background: '#FFFFFF', background2: '#FFF5E1', text: '#000000', error: '#B00020', outline: '#757575', activeOutline: '#ab5335', icon: '#757575', success: '#4CAF50', placeholder: '#999999', surface: '#FFFFFF', disabled: '#999999', disabledBackground: '#F0F0F0', tableHeaderBackgroundColor_1: '#fbe7d5', tableHeaderBackgroundColor_2: '#f4f4f8', gray_1: '#E0E0E0', selectedOptionText: '#924c2e', optionText: '#4b4f60', radioBorderColor: '#924c2e', radioSelectedColor: '#924c2e', payableAmountColor: '#924c2e', payableTextColor: '#4b4f60', Seashell: '#F1E2DE', warning: '#FF9500', info: '#007AFF', }, borderRadius: { small: 4, medium: 8, large: 16, }, spacing: { small: 4, medium: 8, large: 16, xlarge: 32, }, fontSizes: { small: 12, medium: 16, large: 20, xlarge: 24, }, lineWidth: { thin: 1, medium: 2, thick: 4, },};export const typography = { heading: { fontSize: theme.fontSizes.large, fontWeight: 'bold' as const, }, body: { fontSize: theme.fontSizes.medium, fontWeight: 'normal' as const, }, caption: { fontSize: theme.fontSizes.small, fontWeight: 'normal' as const, }, button: { fontSize: theme.fontSizes.medium, fontWeight: '600' as const, },};in the employee page some api are fetched and use context file for calling the api those apis are 1. API - GET - "https://api.levi-hms.com/api/employees"responce- [ { "employeeId": 1, "employeeCode": "SSHR0001", "title": "Mr", "firstName": "David", "lastName": "David", "dob": "2025-07-25T05:30:00", "certificateDOB": "2025-07-26T00:00:00", "salaryType": "Monthly", "isGratuityEligible": false, "isSalaryAdvanceEligible": false, "contactNumber": "6709908760", "email": "ramadass@levicent.com", "maritalStatus": "Unmarried", "motherTongue": "t", "gender": "male", "emergencyContactNumber1": "07889876578", "emergencyContactNumber2": "6709908780", "presentAddSameAsPerAddress": true, "addressLine": "NO 55\nsecond street", "street": "NO 55", "city": "tiruvannamlai", "state": "tamilnadu", "country": "India", "zip": 1, "perAddressLine": null, "perStreet": null, "perCity": null, "perState": null, "perCountry": null, "perZip": null, "doj": "2025-07-25T05:30:00", "dol": null, "baseLocation": "t", "departmentId": 1, "empWorkContactNumber": "6709908760", "empWorkEmail": "doni@gmail.com", "designationId": 7, "isManager": false, "managerId": 2, "employeeStatusId": 1, "employeeTypeId": 1, "active": true, "hotelId": 0, "departments": null, "designations": null, "employeeTypes": null, "employeeStatus": null, "departmentName": "Front Office", "designationName": "Sales and Marketing Manager", "employeeTypeName": "Full-Time", "employeeStatusName": "Active", "rolesList": null, "createdDate": "2025-07-25T00:00:00", "createdBy": "suganthan", "updatedDate": "2025-07-29T12:27:43", "updatedBy": "suganthan" }, { "employeeId": 2, "employeeCode": "SSHR0002", "title": "Mr", "firstName": "Raju", "lastName": "Sundaram", "dob": "2025-07-25T00:00:00", "certificateDOB": "2025-07-25T00:00:00", "salaryType": "Monthly", "isGratuityEligible": false, "isSalaryAdvanceEligible": false, "contactNumber": "9080706050", "email": "ramadass@levicent.com", "maritalStatus": "Unmarried", "motherTongue": "t", "gender": "male", "emergencyContactNumber1": "09080764565", "emergencyContactNumber2": "7889876578", "presentAddSameAsPerAddress": true, "addressLine": "23, Sundaram Colony", "street": "23, Sundaram Colony", "city": "Chennai", "state": "Tamilnadu", "country": "India", "zip": 600012, "perAddressLine": null, "perStreet": null, "perCity": null, "perState": null, "perCountry": null, "perZip": null, "doj": "2025-07-25T00:00:00", "dol": null, "baseLocation": "tvm", "departmentId": 1, "empWorkContactNumber": "9080764565", "empWorkEmail": "mark@gmail.com", "designationId": 1, "isManager": false, "managerId": 2, "employeeStatusId": 2, "employeeTypeId": 1, "active": true, "hotelId": 0, "departments": null, "designations": null, "employeeTypes": null, "employeeStatus": null, "departmentName": "Front Office", "designationName": "General Manager", "employeeTypeName": "Full-Time", "employeeStatusName": "Inactive", "rolesList": null, "createdDate": "2025-07-25T08:15:19", "createdBy": "suganthan", "updatedDate": "2025-07-25T08:15:19", "updatedBy": "suganthan" }]2. API - GET - "https://api.levi-hms.com/api/departments"responce- [ { "departmentId": 1, "parentId": 0, "name": "Front Office", "description": "Handles all housekeeping duties", "location": "First Floor", "hotelId": 1, "active": false, "isUseCodeForEmpCode": true, "maximumLimit": 4, "fixedPrefix": "2", "departmentCode": "HR001", "createdDate": "2024-06-13T10:00:00", "createdBy": "suganthan", "updatedDate": "2025-05-30T16:25:54", "updatedBy": "suganthan" }]3.API- GET- "https://api.levi-hms.com/api/designations"responce - [ { "designationId": 1, "departmentId": 1, "code": "101", "name": "General Manager", "description": "Oversees overall hotel operations and staff management.", "sortOrder": 1, "hotelId": 0, "active": true, "departments": null, "departmentName": "Front Office", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }]4. API - GET - "https://api.levi-hms.com/api/employeetypes"responce - [ { "employeeTypeId": 1, "name": "Full-Time", "description": "Regular employees working 35–40+ hours/week with full benefits.", "hotelId": 1, "active": true, "createdDate": "2025-07-23T10:00:00", "createdBy": "suganthan", "updatedDate": "2025-07-23T10:00:00", "updatedBy": "suganthan" }]5.API - GET - "https://api.levi-hms.com/api/employeestatus"responce - [ { "employeeStatusId": 1, "name": "Active", "description": "The employee is currently working and available for duty.", "hotelId": 1, "active": true, "createdDate": "2024-08-30T11:57:56", "createdBy": "punitha", "updatedDate": "2024-08-30T11:57:56", "updatedBy": "punitha" }]6. API - GET - "https://api.levi-hms.com/api/roles"responce - [ { "roleId": 1, "name": "SuperAdmin", "description": "Oversees all hotel operations; highest level of access across departments.", "active": true, "hotelId": 1, "sortOrder": 1, "createdDate": "2024-05-15T12:00:00", "createdBy": "suganthan", "updatedDate": "2024-05-15T12:00:00", "updatedBy": "suganthan" }]my env file is EXPO_PUBLIC_API_BASE_URL=https://api.levi-hms.com/api/now give me the code
Below is a modern React Native implementation using your theme. The EmployeeCard is a separate component that receives its data via props, and the API calls are centralized in a Context that reads from EXPO_PUBLIC_API_BASE_URL. This follows React’s recommended pattern for passing data to child components via props 2.
Notes:
src/theme.ts
src/types.ts
src/utils/format.ts
src/context/ApiContext.tsx
src/components/EmployeeCard.tsx
src/screens/EmployeesScreen.tsx
App.tsx
How it works:
If you’re using Expo, ensure you have an app config or .env with:
Then run:
'use client';import type React from 'react';import { TouchableOpacity, StyleSheet, Animated } from 'react-native';import { useState, useEffect, useRef } from 'react';import { theme } from '../../styles/theme';interface ToggleButtonProps { value: boolean; onValueChange: (value: boolean) => void; disabled?: boolean;}const ToggleButton: React.FC<ToggleButtonProps> = ({ value, onValueChange, disabled = false,}) => { const [isEnabled, setIsEnabled] = useState(value); const animatedValue = useRef(new Animated.Value(value ? 1 : 0)).current; useEffect(() => { setIsEnabled(value); Animated.timing(animatedValue, { toValue: value ? 1 : 0, duration: 200, useNativeDriver: false, }).start(); }, [value, animatedValue]); const handlePress = () => { if (!disabled) { const newValue = !isEnabled; setIsEnabled(newValue); onValueChange(newValue); } }; const backgroundColor = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [theme.colors.outline, theme.colors.success], }); const translateX = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [2, 22], }); return ( <TouchableOpacity style={[styles.container, { opacity: disabled ? 0.5 : 1 }]} onPress={handlePress} disabled={disabled} activeOpacity={0.8} > <Animated.View style={[styles.track, { backgroundColor }]}> <Animated.View style={[styles.thumb, { transform: [{ translateX }] }]} /> </Animated.View> </TouchableOpacity> );};const styles = StyleSheet.create({ container: { justifyContent: 'center', alignItems: 'center', }, track: { width: 44, height: 24, borderRadius: 12, justifyContent: 'center', padding: 2, }, thumb: { width: 20, height: 20, borderRadius: 10, backgroundColor: '#FFFFFF', shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 3.84, elevation: 5, },});export default ToggleButton;use my toggle button for the toggle .and call PUT- "https://api.levi-hms.com/api/common/updateActive" api for when i change the toggle button U forgot to "add" button When I click add button then it should open my custom modal and its called some api those are 1.API- GET - "/api/Employees/GetEmployeeCode/{HotelId}"responce - {"employeeCode":"SSHR0005"}2.API-GET- "https://api.levi-hms.com/api/designations"responce - [ { "designationId": 1, "departmentId": 1, "code": "101", "name": "General Manager", "description": "Oversees overall hotel operations and staff management.", "sortOrder": 1, "hotelId": 0, "active": true, "departments": null, "departmentName": "Front Office", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 2, "departmentId": 2, "code": "102", "name": "Front Office Manager", "description": "Manages front desk operations, reservations, and guest services.", "sortOrder": 2, "hotelId": 0, "active": true, "departments": null, "departmentName": "Housekeeping", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 3, "departmentId": 8, "code": "103", "name": "Housekeeping Manager", "description": "Supervises cleaning and maintenance of rooms and common areas.", "sortOrder": 3, "hotelId": 0, "active": true, "departments": null, "departmentName": "Finance and Accounting", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 4, "departmentId": 3, "code": "104", "name": "Revenue Manager", "description": "Optimizes pricing strategies to maximize hotel revenue.", "sortOrder": 4, "hotelId": 0, "active": true, "departments": null, "departmentName": "Food and Beverage", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 5, "departmentId": 3, "code": "105", "name": "Food and Beverage Manager", "description": "Oversees restaurant, bar, and catering services.", "sortOrder": 5, "hotelId": 0, "active": true, "departments": null, "departmentName": "Food and Beverage", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 6, "departmentId": 4, "code": "106", "name": "Executive Chef", "description": "Manages the kitchen and food preparation quality.", "sortOrder": 6, "hotelId": 0, "active": true, "departments": null, "departmentName": "Sales and Marketing", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 7, "departmentId": 1, "code": "107", "name": "Sales and Marketing Manager", "description": "Drives sales, promotions, and guest acquisition.", "sortOrder": 7, "hotelId": 0, "active": true, "departments": null, "departmentName": "Front Office", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 8, "departmentId": 1, "code": "108", "name": "Guest Relations Manager", "description": " Ensures positive guest experiences and addresses complaints.", "sortOrder": 8, "hotelId": 0, "active": true, "departments": null, "departmentName": "Front Office", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 9, "departmentId": 5, "code": "109", "name": "Concierge", "description": "Assists guests with reservations, recommendations, and local information.", "sortOrder": 9, "hotelId": 0, "active": true, "departments": null, "departmentName": "Maintenance and Engineering", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 10, "departmentId": 1, "code": "110", "name": "Maintenance Manager", "description": "Handles repair and maintenance of hotel facilities.", "sortOrder": 10, "hotelId": 0, "active": true, "departments": null, "departmentName": "Front Office", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 11, "departmentId": 9, "code": "201", "name": "Front Desk Agent/Receptionist", "description": "Handles guest check-in, check-out, and reservations.", "sortOrder": 11, "hotelId": 0, "active": true, "departments": null, "departmentName": "Reservations", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }, { "designationId": 12, "departmentId": 3, "code": "202", "name": "Reservation Agent", "description": "Manages bookings and responds to reservation inquiries.", "sortOrder": 12, "hotelId": 0, "active": true, "departments": null, "departmentName": "Food and Beverage", "createdDate": "2024-10-25T16:14:48", "createdBy": "Sathiyakala", "updatedDate": "2024-10-25T16:14:50", "updatedBy": "Sathiyakala" }]3. API - POST - "https://api.levi-hms.com/api/employees"payload - {createdDate: "2025-08-10T19:35:53.566Z", createdBy: "suganthan",…}active: trueaddressLine: "kolkata"baseLocation: "kolkata"certificateDOB: "2025-08-12T00:00:00.000Z"city: "kolkata"contactNumber: 1234567890country: "india"createdBy: "suganthan"createdDate: "2025-08-10T19:35:53.566Z"departmentId: "2"designationId: "2"dob: "2025-08-12T00:00:00.000Z"doj: "2025-08-14T00:00:00.000Z"email: "abc@gmail.com"emergencyContactNumber1: "1234567891"emergencyContactNumber2: 9876543210empWorkContactNumber: 1122334455empWorkEmail: "akc@gmail.com"employeeCode: "SSHR0005"employeeStatusId: "1"employeeTypeId: "1"firstName: "rakes"gender: "male"hotelId: 1isGratuityEligible: falseisManager: falseisSalaryAdvanceEligible: truelastName: "dula"managerId: 2maritalStatus: "Married"motherTongue: "hindi"perAddressLine: nullperCity: nullperCountry: nullperState: nullperStreet: nullperZip: nullpresentAddSameAsPerAddress: truerolesList: [2]0: 2salaryType: "Monthly"state: "WB"street: "daimond road"title: "Mr"updatedBy: "suganthan"updatedDate: "2025-08-10T19:35:53.566Z"zip: 112233also u for got to add "edit" and "delete" button for edit and delete call apis also for edit fetch -PUT - "/api/Employees"for delete fetch - "/api/Employees/{Id}"now this is my cautom file for the modalimport React from 'react';import { Modal, View, Text, TouchableOpacity, StyleSheet, ScrollView, KeyboardAvoidingView, Platform, Dimensions,} from 'react-native';import Feather from 'react-native-vector-icons/Feather';import { theme } from '../../styles/theme';interface DynamicModalProps { visible: boolean; onClose: () => void; title: string; children: React.ReactNode; showCloseButton?: boolean; maxHeight?: number | string;}const DynamicModal: React.FC<DynamicModalProps> = ({ visible, onClose, title, children, showCloseButton = true, maxHeight = '80%',}) => { const screenHeight = Dimensions.get('window').height; const getMaxHeight = () => { if (typeof maxHeight === 'string' && maxHeight.includes('%')) { const percentage = parseInt(maxHeight.replace('%', '')); return (screenHeight * percentage) / 100; } return typeof maxHeight === 'number' ? maxHeight : screenHeight * 0.8; }; return ( <Modal transparent animationType="slide" visible={visible} onRequestClose={onClose} > <KeyboardAvoidingView style={styles.modalOverlay} behavior={Platform.OS === 'ios' ? 'padding' : 'height'} > <TouchableOpacity style={styles.modalOverlay} activeOpacity={1} onPressOut={onClose} > <View style={[styles.modalContent, { maxHeight: getMaxHeight() }]} onStartShouldSetResponder={() => true} > <View style={styles.modalHeader}> <Text style={styles.modalTitle}>{title}</Text> {/* {showCloseButton && ( <TouchableOpacity style={styles.closeButton} onPress={onClose} > <Feather name="x" size={24} color={theme.colors.background} /> </TouchableOpacity> )} */} {/* The comment out code needed for future reference */} </View> <ScrollView style={styles.modalBody} showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled" > {children} </ScrollView> </View> </TouchableOpacity> </KeyboardAvoidingView> </Modal> );};const styles = StyleSheet.create({ modalOverlay: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0, 0, 0, 0.1)', width: '100%', }, modalContent: { width: '80%', backgroundColor: theme.colors.surface, borderRadius: theme.borderRadius.large, elevation: 5, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 4, }, modalHeader: { display: 'flex', justifyContent: 'center', alignItems: 'center', paddingHorizontal: theme.spacing.large, paddingVertical: theme.spacing.large, borderBottomWidth: theme.lineWidth.thin, borderBottomColor: theme.colors.outline, backgroundColor:theme.colors.primary, borderTopEndRadius: theme.borderRadius.large, borderTopStartRadius: theme.borderRadius.large, }, modalTitle: { fontSize: theme.fontSizes.large, fontWeight: '700', color: theme.colors.background, flex: 1, }, closeButton: { padding: theme.spacing.small, }, modalBody: { paddingHorizontal: theme.spacing.large, paddingVertical: theme.spacing.medium, },});export default DynamicModal;now give me the updated code
Notes: