added patient detail screen

This commit is contained in:
yashwin-foxy 2025-08-12 18:50:19 +05:30
parent 80a1688e19
commit 413a1d74de
55 changed files with 2512 additions and 425 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,36 +2,36 @@
"migIndex": 1, "migIndex": 1,
"data": [ "data": [
{ {
"path": "app/assets/fonts/Roboto-Black.ttf", "path": "app/assets/fonts/WorkSans-Bold.ttf",
"sha1": "d1678489a8d5645f16486ec52d77b651ff0bf327" "sha1": "ec84061651ead3c3c5cbb61c2d338aca0bacdc1e"
}, },
{ {
"path": "app/assets/fonts/Roboto-Bold.ttf", "path": "app/assets/fonts/WorkSans-ExtraBold.ttf",
"sha1": "508c35dee818addce6cc6d1fb6e42f039da5a7cf" "sha1": "0b371d1dbfbdd15db880bbd129b239530c71accb"
}, },
{ {
"path": "app/assets/fonts/Roboto-ExtraBold.ttf", "path": "app/assets/fonts/WorkSans-ExtraLight.ttf",
"sha1": "3dbfd71b6fbcfbd8e7ee8a8dd033dc5aaad63249" "sha1": "74596e55487e2961b6c43993698d658e2ceee77b"
}, },
{ {
"path": "app/assets/fonts/Roboto-ExtraLight.ttf", "path": "app/assets/fonts/WorkSans-Light.ttf",
"sha1": "df556e64732e5c272349e13cb5f87591a1ae779b" "sha1": "293e11dae7e8b930bf5eea0b06ca979531f22189"
}, },
{ {
"path": "app/assets/fonts/Roboto-Light.ttf", "path": "app/assets/fonts/WorkSans-Medium.ttf",
"sha1": "318b44c0a32848f78bf11d4fbf3355d00647a796" "sha1": "c281f8454dd193c2260e43ae2de171c5dd4086e4"
}, },
{ {
"path": "app/assets/fonts/Roboto-Medium.ttf", "path": "app/assets/fonts/WorkSans-Regular.ttf",
"sha1": "fa5192203f85ddb667579e1bdf26f12098bb873b" "sha1": "5e0183b29b57c54595c62ac6bc223b21f1434226"
}, },
{ {
"path": "app/assets/fonts/Roboto-Regular.ttf", "path": "app/assets/fonts/WorkSans-SemiBold.ttf",
"sha1": "3bff51436aa7eb995d84cfc592cc63e1316bb400" "sha1": "64b8fe156fafce221a0f66504255257053fc6062"
}, },
{ {
"path": "app/assets/fonts/Roboto-SemiBold.ttf", "path": "app/assets/fonts/WorkSans-Thin.ttf",
"sha1": "9ca139684fe902c8310dd82991648376ac9838db" "sha1": "a62251331038fdd079c47bc413a350efbf702db8"
} }
] ]
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -365,7 +365,7 @@ const styles = StyleSheet.create({
// Header section // Header section
header: { header: {
marginBottom: theme.spacing.lg, // marginBottom: theme.spacing.lg,
}, },
// Main title // Main title
@ -465,10 +465,8 @@ const styles = StyleSheet.create({
// Pie chart container // Pie chart container
pieChartContainer: { pieChartContainer: {
alignItems: 'center', alignItems: 'center',
marginBottom: theme.spacing.lg,
backgroundColor: theme.colors.background, backgroundColor: theme.colors.background,
borderRadius: theme.borderRadius.medium, borderRadius: theme.borderRadius.medium,
padding: theme.spacing.md,
}, },
// Legend container // Legend container
@ -478,7 +476,6 @@ const styles = StyleSheet.create({
backgroundColor: theme.colors.backgroundAlt, backgroundColor: theme.colors.backgroundAlt,
borderRadius: theme.borderRadius.medium, borderRadius: theme.borderRadius.medium,
padding: theme.spacing.md, padding: theme.spacing.md,
marginTop: theme.spacing.md,
}, },
// Legend title // Legend title

View File

@ -0,0 +1,503 @@
/*
* File: ImageViewer.tsx
* Description: Full-screen DICOM image viewer with zoom, pan, and navigation
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import React, { useState, useCallback } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Dimensions,
Image,
ScrollView,
StatusBar,
SafeAreaView,
} from 'react-native';
import { theme } from '../../../theme/theme';
import Icon from 'react-native-vector-icons/Feather';
import { API_CONFIG } from '../../../shared/utils';
// Get screen dimensions
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
// ============================================================================
// INTERFACES
// ============================================================================
interface ImageViewerProps {
visible: boolean;
images: string[];
initialIndex: number;
onClose: () => void;
patientName?: string;
seriesInfo?: string;
}
// ============================================================================
// IMAGE VIEWER COMPONENT
// ============================================================================
/**
* ImageViewer Component
*
* Purpose: Full-screen DICOM image viewer with advanced viewing capabilities
*
* Features:
* - Full-screen image display
* - Image navigation (previous/next)
* - Zoom and pan functionality
* - Patient information display
* - Series information
* - Touch gestures for navigation
* - Professional medical imaging interface
*/
const ImageViewer: React.FC<ImageViewerProps> = ({
visible,
images,
initialIndex,
onClose,
patientName = 'Unknown Patient',
seriesInfo = 'DICOM Series',
}) => {
// ============================================================================
// STATE MANAGEMENT
// ============================================================================
const [currentIndex, setCurrentIndex] = useState(initialIndex);
const [scale, setScale] = useState(1);
const [isZoomed, setIsZoomed] = useState(false);
// ============================================================================
// EVENT HANDLERS
// ============================================================================
/**
* Handle Previous Image
*
* Purpose: Navigate to previous image in series
*/
const handlePrevious = useCallback(() => {
if (currentIndex > 0) {
setCurrentIndex(currentIndex - 1);
setScale(1);
setIsZoomed(false);
}
}, [currentIndex]);
/**
* Handle Next Image
*
* Purpose: Navigate to next image in series
*/
const handleNext = useCallback(() => {
if (currentIndex < images.length - 1) {
setCurrentIndex(currentIndex + 1);
setScale(1);
setIsZoomed(false);
}
}, [currentIndex, images.length]);
/**
* Handle Zoom In
*
* Purpose: Increase image zoom level
*/
const handleZoomIn = useCallback(() => {
const newScale = Math.min(scale * 1.5, 3);
setScale(newScale);
setIsZoomed(newScale > 1);
}, [scale]);
/**
* Handle Zoom Out
*
* Purpose: Decrease image zoom level
*/
const handleZoomOut = useCallback(() => {
const newScale = Math.max(scale / 1.5, 0.5);
setScale(newScale);
setIsZoomed(newScale > 1);
}, [scale]);
/**
* Handle Reset Zoom
*
* Purpose: Reset image to original size
*/
const handleResetZoom = useCallback(() => {
setScale(1);
setIsZoomed(false);
}, []);
/**
* Handle Close
*
* Purpose: Close image viewer and return to previous screen
*/
const handleClose = useCallback(() => {
setScale(1);
setIsZoomed(false);
setCurrentIndex(initialIndex);
onClose();
}, [initialIndex, onClose]);
// ============================================================================
// RENDER HELPERS
// ============================================================================
/**
* Render Header
*
* Purpose: Render image viewer header with patient info and controls
*/
const renderHeader = () => (
<View style={styles.header}>
<View style={styles.headerLeft}>
<TouchableOpacity
style={styles.closeButton}
onPress={handleClose}
>
<Icon name="x" size={24} color={theme.colors.background} />
</TouchableOpacity>
<View style={styles.patientInfo}>
<Text style={styles.patientName}>{patientName}</Text>
<Text style={styles.seriesInfo}>{seriesInfo}</Text>
</View>
</View>
<View style={styles.headerRight}>
<Text style={styles.imageCounter}>
{currentIndex + 1} of {images.length}
</Text>
</View>
</View>
);
/**
* Render Navigation Controls
*
* Purpose: Render image navigation controls
*/
const renderNavigationControls = () => (
<View style={styles.navigationControls}>
<TouchableOpacity
style={[
styles.navButton,
currentIndex === 0 && styles.navButtonDisabled
]}
onPress={handlePrevious}
disabled={currentIndex === 0}
>
<Icon
name="chevron-left"
size={24}
color={currentIndex === 0 ? theme.colors.textMuted : theme.colors.background}
/>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.navButton,
currentIndex === images.length - 1 && styles.navButtonDisabled
]}
onPress={handleNext}
disabled={currentIndex === images.length - 1}
>
<Icon
name="chevron-right"
size={24}
color={currentIndex === images.length - 1 ? theme.colors.textMuted : theme.colors.background}
/>
</TouchableOpacity>
</View>
);
/**
* Render Zoom Controls
*
* Purpose: Render zoom control buttons
*/
const renderZoomControls = () => (
<View style={styles.zoomControls}>
<TouchableOpacity
style={styles.zoomButton}
onPress={handleZoomOut}
>
<Icon name="minus" size={20} color={theme.colors.background} />
</TouchableOpacity>
<TouchableOpacity
style={styles.zoomButton}
onPress={handleResetZoom}
>
<Text style={styles.zoomText}>{Math.round(scale * 100)}%</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.zoomButton}
onPress={handleZoomIn}
>
<Icon name="plus" size={20} color={theme.colors.background} />
</TouchableOpacity>
</View>
);
// ============================================================================
// MAIN RENDER
// ============================================================================
if (!visible || images.length === 0) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="light-content" backgroundColor="#000000" />
{/* Header */}
{renderHeader()}
{/* Main Image Area */}
<View style={styles.imageContainer}>
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.scrollContent}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
maximumZoomScale={3}
minimumZoomScale={0.5}
bounces={false}
>
<Image
source={{ uri: API_CONFIG.DICOM_BASE_URL + images[currentIndex] }}
style={[
styles.image,
{
transform: [{ scale }],
},
]}
resizeMode="contain"
/>
</ScrollView>
</View>
{/* Navigation Controls */}
{renderNavigationControls()}
{/* Zoom Controls */}
{renderZoomControls()}
{/* Thumbnail Strip */}
<View style={styles.thumbnailStrip}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.thumbnailContent}
>
{images.map((image, index) => (
<TouchableOpacity
key={index}
style={[
styles.thumbnail,
index === currentIndex && styles.activeThumbnail
]}
onPress={() => setCurrentIndex(index)}
>
<Image
source={{ uri: API_CONFIG.DICOM_BASE_URL + image }}
style={styles.thumbnailImage}
resizeMode="cover"
/>
{index === currentIndex && (
<View style={styles.activeIndicator}>
<Icon name="check" size={12} color={theme.colors.background} />
</View>
)}
</TouchableOpacity>
))}
</ScrollView>
</View>
</SafeAreaView>
);
};
// ============================================================================
// STYLES
// ============================================================================
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000000',
},
// Header Styles
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: theme.spacing.md,
paddingVertical: theme.spacing.sm,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
},
headerLeft: {
flexDirection: 'row',
alignItems: 'center',
flex: 1,
},
closeButton: {
padding: theme.spacing.sm,
marginRight: theme.spacing.md,
},
patientInfo: {
flex: 1,
},
patientName: {
fontSize: 16,
fontWeight: 'bold',
color: theme.colors.background,
fontFamily: theme.typography.fontFamily.bold,
},
seriesInfo: {
fontSize: 12,
color: theme.colors.background,
opacity: 0.8,
fontFamily: theme.typography.fontFamily.regular,
},
headerRight: {
alignItems: 'flex-end',
},
imageCounter: {
fontSize: 14,
color: theme.colors.background,
fontFamily: theme.typography.fontFamily.medium,
},
// Image Container Styles
imageContainer: {
flex: 1,
// backgroundColor: '#000000',
},
scrollView: {
flex: 1,
},
scrollContent: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: screenWidth,
height: screenHeight * 0.7,
},
// Navigation Controls Styles
navigationControls: {
position: 'absolute',
top: '50%',
left: 0,
right: 0,
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: theme.spacing.md,
transform: [{ translateY: -20 }],
},
navButton: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: 'rgba(0, 0, 0, 0.6)',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 4,
elevation: 4,
},
navButtonDisabled: {
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
// Zoom Controls Styles
zoomControls: {
position: 'absolute',
bottom: 100,
right: theme.spacing.md,
flexDirection: 'column',
alignItems: 'center',
},
zoomButton: {
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: 'rgba(0, 0, 0, 0.6)',
justifyContent: 'center',
alignItems: 'center',
marginBottom: theme.spacing.sm,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 4,
elevation: 4,
},
zoomText: {
color: theme.colors.background,
fontSize: 12,
fontWeight: 'bold',
fontFamily: theme.typography.fontFamily.bold,
},
// Thumbnail Strip Styles
thumbnailStrip: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
paddingVertical: theme.spacing.sm,
},
thumbnailContent: {
paddingHorizontal: theme.spacing.md,
},
thumbnail: {
width: 60,
height: 60,
borderRadius: 8,
marginRight: theme.spacing.sm,
position: 'relative',
borderWidth: 2,
borderColor: 'transparent',
},
activeThumbnail: {
borderColor: theme.colors.primary,
},
thumbnailImage: {
width: '100%',
height: '100%',
borderRadius: 6,
},
activeIndicator: {
position: 'absolute',
top: -4,
right: -4,
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: theme.colors.primary,
justifyContent: 'center',
alignItems: 'center',
},
});
export default ImageViewer;
/*
* End of File: ImageViewer.tsx
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/

View File

@ -158,7 +158,7 @@ const PatientCard: React.FC<PatientCardProps> = ({
const patientDetails = parseJsonSafely(patient.patientdetails); const patientDetails = parseJsonSafely(patient.patientdetails);
const patientData = patientDetails.patientdetails || patientDetails; const patientData = patientDetails.patientdetails || patientDetails;
const series = parseJsonSafely(patient.series); const series = parseJsonSafely(patientDetails.series);
const typeConfig = getCaseTypeConfig(patient.type); const typeConfig = getCaseTypeConfig(patient.type);
// ============================================================================ // ============================================================================
@ -207,7 +207,7 @@ const PatientCard: React.FC<PatientCardProps> = ({
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.container, styles.container,
patient.type === 'Critical' && styles.containerCritical, // patient.type === 'Critical' && styles.containerCritical,
{ borderLeftColor: typeConfig.color } { borderLeftColor: typeConfig.color }
]} ]}
onPress={onPress} onPress={onPress}

View File

@ -10,6 +10,7 @@ export { default as SearchBar } from './SearchBar';
export { default as FilterTabs } from './FilterTabs'; export { default as FilterTabs } from './FilterTabs';
export { default as EmptyState } from './EmptyState'; export { default as EmptyState } from './EmptyState';
export { default as LoadingState } from './LoadingState'; export { default as LoadingState } from './LoadingState';
export { default as ImageViewer } from './ImageViewer';
/* /*
* End of File: index.ts * End of File: index.ts

View File

@ -0,0 +1,76 @@
/*
* File: PatientCareStackNavigator.tsx
* Description: Stack navigator for PatientCare module navigation
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
// Import screens
import { PatientsScreen, PatientDetailsScreen } from '../screens';
// Import types
import { PatientCareStackParamList } from './navigationTypes';
// ============================================================================
// STACK NAVIGATOR
// ============================================================================
const Stack = createStackNavigator<PatientCareStackParamList>();
/**
* PatientCareStackNavigator Component
*
* Purpose: Provides stack navigation for PatientCare module
*
* Screens:
* - PatientsScreen: Main patient list screen
* - PatientDetailsScreen: Detailed patient information and DICOM images
*
* Navigation Flow:
* PatientsScreen PatientDetailsScreen (with patient data)
*/
const PatientCareStackNavigator: React.FC = () => {
return (
<Stack.Navigator
initialRouteName="PatientsScreen"
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: 'transparent' },
cardOverlayEnabled: false,
gestureEnabled: true,
gestureDirection: 'horizontal',
}}
>
{/* Patients Screen - Main patient list */}
<Stack.Screen
name="PatientsScreen"
component={PatientsScreen}
options={{
title: 'Patients',
}}
/>
{/* Patient Details Screen - Comprehensive patient information */}
<Stack.Screen
name="PatientDetails"
component={PatientDetailsScreen}
options={{
title: 'Patient Details',
gestureEnabled: true,
gestureDirection: 'horizontal',
}}
/>
</Stack.Navigator>
);
};
export default PatientCareStackNavigator;
/*
* End of File: PatientCareStackNavigator.tsx
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/

View File

@ -0,0 +1,15 @@
/*
* File: index.ts
* Description: Barrel export for PatientCare navigation components
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
export { default as PatientCareStackNavigator } from './PatientCareStackNavigator';
export * from './navigationTypes';
/*
* End of File: index.ts
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/

View File

@ -0,0 +1,118 @@
/*
* File: navigationTypes.ts
* Description: TypeScript types for PatientCare module navigation
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import { StackNavigationProp } from '@react-navigation/stack';
import { MedicalCase } from '../../../shared/types';
// ============================================================================
// NAVIGATION PARAMETER LISTS
// ============================================================================
/**
* PatientCareStackParamList - Defines the parameter list for PatientCare stack navigator
*
* This interface defines all the screens available in the PatientCare module
* and their associated navigation parameters.
*/
export type PatientCareStackParamList = {
// Patients Screen - Main patient list with search and filtering
PatientsScreen: PatientsScreenParams;
// Patient Details Screen - Comprehensive patient information and DICOM images
PatientDetails: PatientDetailsScreenParams;
};
// ============================================================================
// SCREEN PARAMETER INTERFACES
// ============================================================================
/**
* PatientsScreenParams
*
* Purpose: Parameters for the patients list screen
*
* Parameters:
* - None required - this is the main entry point
*/
export interface PatientsScreenParams {
// No parameters required for main patients screen
}
/**
* PatientDetailsScreenParams
*
* Purpose: Parameters for the patient details screen
*
* Parameters:
* - patientId: Required patient ID to display details
* - patientName: Required patient name for display
* - medicalCase: Required medical case data with full patient information
*/
export interface PatientDetailsScreenParams {
patientId: string;
patientName: string;
medicalCase: MedicalCase;
}
// ============================================================================
// NAVIGATION PROP TYPES
// ============================================================================
/**
* PatientCareNavigationProp - Navigation prop type for PatientCare screens
*
* Purpose: Provides type-safe navigation methods for PatientCare module screens
*/
export type PatientCareNavigationProp = StackNavigationProp<PatientCareStackParamList>;
// ============================================================================
// SCREEN PROP TYPES
// ============================================================================
/**
* PatientsScreenProps - Props for PatientsScreen component
*/
export interface PatientsScreenProps {
navigation: PatientCareNavigationProp;
route: {
params: PatientsScreenParams;
};
}
/**
* PatientDetailsScreenProps - Props for PatientDetailsScreen component
*/
export interface PatientDetailsScreenProps {
navigation: PatientCareNavigationProp;
route: {
params: PatientDetailsScreenParams;
};
}
// ============================================================================
// NAVIGATION UTILITY TYPES
// ============================================================================
/**
* NavigationHelper - Helper type for navigation functions
*
* Purpose: Provides type-safe navigation helper functions
*/
export type NavigationHelper = {
navigateToPatientDetails: (
patientId: string,
patientName: string,
medicalCase: MedicalCase
) => void;
navigateBack: () => void;
};
/*
* End of File: navigationTypes.ts
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/

View File

@ -26,7 +26,6 @@ export const fetchPatients = createAsyncThunk(
try { try {
// Make actual API call to fetch medical cases // Make actual API call to fetch medical cases
const response :any = await patientAPI.getPatients(token); const response :any = await patientAPI.getPatients(token);
console.log('patients response',response)
if (response.ok && response.data&&response.data.success) { if (response.ok && response.data&&response.data.success) {
// Add random case types to each patient record // Add random case types to each patient record
const caseTypes: Array<'Critical' | 'Emergency' | 'Routine'> = ['Critical', 'Emergency', 'Routine']; const caseTypes: Array<'Critical' | 'Emergency' | 'Routine'> = ['Critical', 'Emergency', 'Routine'];
@ -36,7 +35,6 @@ export const fetchPatients = createAsyncThunk(
type: caseTypes[Math.floor(Math.random() * caseTypes.length)] type: caseTypes[Math.floor(Math.random() * caseTypes.length)]
})); }));
console.log('patients with random types', patientsWithTypes);
return patientsWithTypes as MedicalCase[]; return patientsWithTypes as MedicalCase[];
} else { } else {
// Fallback to mock data for development // Fallback to mock data for development
@ -125,7 +123,7 @@ export const fetchPatientDetails = createAsyncThunk(
async (patientId: string, { rejectWithValue }) => { async (patientId: string, { rejectWithValue }) => {
try { try {
// TODO: Replace with actual API call // TODO: Replace with actual API call
await new Promise((resolve) => setTimeout(resolve, 1000)); await new Promise((resolve) => setTimeout(resolve as any, 1000));
// Mock patient details for specific patient // Mock patient details for specific patient
const mockPatient: MedicalCase = { const mockPatient: MedicalCase = {
@ -179,7 +177,7 @@ export const updatePatient = createAsyncThunk(
async (patientData: Partial<MedicalCase> & { id: number }, { rejectWithValue }) => { async (patientData: Partial<MedicalCase> & { id: number }, { rejectWithValue }) => {
try { try {
// TODO: Replace with actual API call // TODO: Replace with actual API call
await new Promise((resolve) => setTimeout(resolve, 800)); await new Promise((resolve) => setTimeout(resolve as any, 800));
return patientData; return patientData;
} catch (error) { } catch (error) {
return rejectWithValue('Failed to update patient.'); return rejectWithValue('Failed to update patient.');
@ -388,8 +386,8 @@ const patientCareSlice = createSlice({
state.isLoading = false; state.isLoading = false;
state.patients = action.payload; state.patients = action.payload;
state.totalItems = action.payload.length; state.totalItems = action.payload.length;
state.lastUpdated = new Date(); state.lastUpdated = new Date().toLocaleDateString();
state.cacheExpiry = new Date(Date.now() + 5 * 60 * 1000); // 5 minutes state.cacheExpiry = new Date(Date.now() + 5 * 60 * 1000).toLocaleDateString(); // 5 minutes
state.error = null; state.error = null;
}) })
.addCase(fetchPatients.rejected, (state, action) => { .addCase(fetchPatients.rejected, (state, action) => {

File diff suppressed because it is too large Load Diff

View File

@ -56,6 +56,7 @@ import LoadingState from '../components/LoadingState';
// Import types // Import types
import { MedicalCase, PatientDetails, Series } from '../../../shared/types'; import { MedicalCase, PatientDetails, Series } from '../../../shared/types';
import { PatientsScreenProps } from '../navigation/navigationTypes';
// Get screen dimensions // Get screen dimensions
const { width: screenWidth } = Dimensions.get('window'); const { width: screenWidth } = Dimensions.get('window');
@ -64,10 +65,6 @@ const { width: screenWidth } = Dimensions.get('window');
// INTERFACES // INTERFACES
// ============================================================================ // ============================================================================
interface PatientsScreenProps {
navigation: any;
}
// ============================================================================ // ============================================================================
// PATIENTS SCREEN COMPONENT // PATIENTS SCREEN COMPONENT
// ============================================================================ // ============================================================================
@ -241,7 +238,7 @@ const PatientsScreen: React.FC<PatientsScreenProps> = ({ navigation }) => {
const patientData = patientDetails.patientdetails || patientDetails; const patientData = patientDetails.patientdetails || patientDetails;
navigation.navigate('PatientDetails', { navigation.navigate('PatientDetails', {
patientId: patient.id, patientId:'1',
patientName: patientData.Name || 'Unknown Patient', patientName: patientData.Name || 'Unknown Patient',
medicalCase: patient, medicalCase: patient,
}); });
@ -397,7 +394,7 @@ const PatientsScreen: React.FC<PatientsScreenProps> = ({ navigation }) => {
style={styles.headerButton} style={styles.headerButton}
onPress={() => { onPress={() => {
// TODO: Implement notifications screen // TODO: Implement notifications screen
navigation.navigate('Notifications'); Alert.alert('Notifications', 'Notifications feature coming soon');
}} }}
> >
<Icon name="bell" size={20} color={theme.colors.textSecondary} /> <Icon name="bell" size={20} color={theme.colors.textSecondary} />

View File

@ -6,6 +6,7 @@
*/ */
export { default as PatientsScreen } from './PatientsScreen'; export { default as PatientsScreen } from './PatientsScreen';
export { default as PatientDetailsScreen } from './PatientDetailsScreen';
/* /*
* End of File: index.ts * End of File: index.ts

View File

@ -34,7 +34,7 @@ const Stack = createStackNavigator<SettingsStackParamList>();
const SettingsStackNavigator: React.FC = () => { const SettingsStackNavigator: React.FC = () => {
return ( return (
<Stack.Navigator <Stack.Navigator
initialRouteName="Settings" initialRouteName="SettingScreen"
screenOptions={{ screenOptions={{
// Header styling for settings screens // Header styling for settings screens
headerStyle: { headerStyle: {
@ -71,7 +71,7 @@ const SettingsStackNavigator: React.FC = () => {
> >
{/* Settings Screen - Main settings entry point */} {/* Settings Screen - Main settings entry point */}
<Stack.Screen <Stack.Screen
name="Settings" name="SettingScreen"
component={SettingsScreen} component={SettingsScreen}
options={{ options={{
title: 'Settings', title: 'Settings',

View File

@ -16,7 +16,7 @@ import { UserProfile, UserPreferences } from '../../../shared/types';
*/ */
export type SettingsStackParamList = { export type SettingsStackParamList = {
// Settings screen - Main settings with profile and preferences // Settings screen - Main settings with profile and preferences
Settings: SettingsScreenParams; SettingScreen: SettingsScreenParams;
// Profile Edit screen - Edit user profile information // Profile Edit screen - Edit user profile information
ProfileEdit: ProfileEditScreenParams; ProfileEdit: ProfileEditScreenParams;

View File

@ -108,7 +108,7 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
const userProfilePhoto = useAppSelector(selectUserProfilePhoto); const userProfilePhoto = useAppSelector(selectUserProfilePhoto);
const notificationPreferences = useAppSelector(selectNotificationPreferences); const notificationPreferences = useAppSelector(selectNotificationPreferences);
const dashboardSettings = useAppSelector(selectDashboardSettings); const dashboardSettings = useAppSelector(selectDashboardSettings);
console.log('user details i got', user);
// ============================================================================ // ============================================================================
// SETTINGS SECTIONS GENERATION // SETTINGS SECTIONS GENERATION

View File

@ -14,7 +14,7 @@ import { AIPredictionStackNavigator } from '../modules/AIPrediction/navigation';
import { MainTabParamList } from './navigationTypes'; import { MainTabParamList } from './navigationTypes';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { ComingSoonScreen } from '../shared/components'; import { ComingSoonScreen } from '../shared/components';
import { PatientsScreen } from '../modules/PatientCare'; import { PatientCareStackNavigator } from '../modules/PatientCare/navigation';
// Create the bottom tab navigator // Create the bottom tab navigator
const Tab = createBottomTabNavigator<MainTabParamList>(); const Tab = createBottomTabNavigator<MainTabParamList>();
@ -86,7 +86,7 @@ export const MainTabNavigator: React.FC = () => {
{/* Patients Tab - Patient list and management */} {/* Patients Tab - Patient list and management */}
<Tab.Screen <Tab.Screen
name="Patients" name="Patients"
component={PatientsScreen} // TODO: Replace with actual PatientsScreen component={PatientCareStackNavigator}
options={{ options={{
title: 'Patient List', title: 'Patient List',
tabBarLabel: 'Patients', tabBarLabel: 'Patients',

View File

@ -150,8 +150,8 @@ export interface PatientCareState {
totalItems: number; totalItems: number;
// Cache // Cache
lastUpdated: Date | null; lastUpdated: string | null;
cacheExpiry: Date | null; cacheExpiry: string | null;
} }
/* /*

View File

@ -9,6 +9,7 @@ import Config from 'react-native-config';
// API Configuration // API Configuration
export const API_CONFIG = { export const API_CONFIG = {
BASE_URL:Config.BASE_URL, BASE_URL:Config.BASE_URL,
DICOM_BASE_URL:'https://demo.medpacsystems.com',
TIMEOUT: 30000, TIMEOUT: 30000,
RETRY_ATTEMPTS: 3, RETRY_ATTEMPTS: 3,
RETRY_DELAY: 1000, RETRY_DELAY: 1000,

View File

@ -8,12 +8,12 @@
export const typography = { export const typography = {
// Font Families // Font Families
fontFamily: { fontFamily: {
bold: 'Roboto-Bold', bold: 'WorkSans-Bold',
medium: 'Roboto-Medium', medium: 'WorkSans-Medium',
regular: 'Roboto-Regular', regular: 'WorkSans-Regular',
light: 'Roboto-Light', light: 'WorkSans-Light',
semibold: 'Roboto-SemiBold', semibold: 'WorkSans-SemiBold',
extrabold: 'Roboto-ExtraBold', extrabold: 'WorkSans-ExtraBold',
}, },
// Font Weights // Font Weights

View File

@ -11,14 +11,14 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; }; 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
9BFF7E8F967043379EA34EF5 /* Roboto-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C93B020BF2D44311BFAF317D /* Roboto-Black.ttf */; }; 90EC1A731F2F480594C0F9D1 /* WorkSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6606F41B1382422DA695F61C /* WorkSans-Bold.ttf */; };
64ADC498A16B4DD2979F9EC6 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E8DE31AC3A3B46AFBAB8E623 /* Roboto-Bold.ttf */; }; 7E1975A765074059A27FA6F1 /* WorkSans-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1569DC7537534ED39A79EE9E /* WorkSans-ExtraBold.ttf */; };
9A05BCBBB57F42CF891B4E76 /* Roboto-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6D158A6D27784CB3AAFC4572 /* Roboto-ExtraBold.ttf */; }; E09CC0AFCD63425FABA5714F /* WorkSans-ExtraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FF48E43749B74116A2C4083C /* WorkSans-ExtraLight.ttf */; };
E9AB985237534D1A92E3A5C8 /* Roboto-ExtraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6787284EF58F40B4A29BE810 /* Roboto-ExtraLight.ttf */; }; 6A06861DDC314E49B482B4EB /* WorkSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B8C4C96FCA144E859DC2AFDA /* WorkSans-Light.ttf */; };
A345282A09764F4B8935E1CE /* Roboto-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F3B7B24AB39048E28AA013C6 /* Roboto-Light.ttf */; }; 3BEFE3BEC3334662878A37D5 /* WorkSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 55E647ABF16B47F6A83403C0 /* WorkSans-Medium.ttf */; };
6C3A045CF24641D79616809F /* Roboto-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 57615910A7564380B1D23731 /* Roboto-Medium.ttf */; }; 6E9607F0F9DE4649802D618B /* WorkSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 589149FBA9F64E9F94AA50AF /* WorkSans-Regular.ttf */; };
A79B0AFEC3DA42AAAA56DC75 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B9D41D27862846A8A6563185 /* Roboto-Regular.ttf */; }; DCDB35B731E1422DBD1481D1 /* WorkSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A58733FB00504503BFBF4295 /* WorkSans-SemiBold.ttf */; };
264B0BD7896E430EB2761212 /* Roboto-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7539BBD08F0743178F5517A3 /* Roboto-SemiBold.ttf */; }; 25B52D1C5AB64F039BEF062F /* WorkSans-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C3614D19A4004E3E858E4CEC /* WorkSans-Thin.ttf */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -43,14 +43,14 @@
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = NeoScan_Physician/AppDelegate.swift; sourceTree = "<group>"; }; 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = NeoScan_Physician/AppDelegate.swift; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = NeoScan_Physician/LaunchScreen.storyboard; sourceTree = "<group>"; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = NeoScan_Physician/LaunchScreen.storyboard; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
C93B020BF2D44311BFAF317D /* Roboto-Black.ttf */ = {isa = PBXFileReference; name = "Roboto-Black.ttf"; path = "../app/assets/fonts/Roboto-Black.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 6606F41B1382422DA695F61C /* WorkSans-Bold.ttf */ = {isa = PBXFileReference; name = "WorkSans-Bold.ttf"; path = "../app/assets/fonts/WorkSans-Bold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
E8DE31AC3A3B46AFBAB8E623 /* Roboto-Bold.ttf */ = {isa = PBXFileReference; name = "Roboto-Bold.ttf"; path = "../app/assets/fonts/Roboto-Bold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 1569DC7537534ED39A79EE9E /* WorkSans-ExtraBold.ttf */ = {isa = PBXFileReference; name = "WorkSans-ExtraBold.ttf"; path = "../app/assets/fonts/WorkSans-ExtraBold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
6D158A6D27784CB3AAFC4572 /* Roboto-ExtraBold.ttf */ = {isa = PBXFileReference; name = "Roboto-ExtraBold.ttf"; path = "../app/assets/fonts/Roboto-ExtraBold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; FF48E43749B74116A2C4083C /* WorkSans-ExtraLight.ttf */ = {isa = PBXFileReference; name = "WorkSans-ExtraLight.ttf"; path = "../app/assets/fonts/WorkSans-ExtraLight.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
6787284EF58F40B4A29BE810 /* Roboto-ExtraLight.ttf */ = {isa = PBXFileReference; name = "Roboto-ExtraLight.ttf"; path = "../app/assets/fonts/Roboto-ExtraLight.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; B8C4C96FCA144E859DC2AFDA /* WorkSans-Light.ttf */ = {isa = PBXFileReference; name = "WorkSans-Light.ttf"; path = "../app/assets/fonts/WorkSans-Light.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
F3B7B24AB39048E28AA013C6 /* Roboto-Light.ttf */ = {isa = PBXFileReference; name = "Roboto-Light.ttf"; path = "../app/assets/fonts/Roboto-Light.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 55E647ABF16B47F6A83403C0 /* WorkSans-Medium.ttf */ = {isa = PBXFileReference; name = "WorkSans-Medium.ttf"; path = "../app/assets/fonts/WorkSans-Medium.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
57615910A7564380B1D23731 /* Roboto-Medium.ttf */ = {isa = PBXFileReference; name = "Roboto-Medium.ttf"; path = "../app/assets/fonts/Roboto-Medium.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 589149FBA9F64E9F94AA50AF /* WorkSans-Regular.ttf */ = {isa = PBXFileReference; name = "WorkSans-Regular.ttf"; path = "../app/assets/fonts/WorkSans-Regular.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
B9D41D27862846A8A6563185 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; name = "Roboto-Regular.ttf"; path = "../app/assets/fonts/Roboto-Regular.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; A58733FB00504503BFBF4295 /* WorkSans-SemiBold.ttf */ = {isa = PBXFileReference; name = "WorkSans-SemiBold.ttf"; path = "../app/assets/fonts/WorkSans-SemiBold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
7539BBD08F0743178F5517A3 /* Roboto-SemiBold.ttf */ = {isa = PBXFileReference; name = "Roboto-SemiBold.ttf"; path = "../app/assets/fonts/Roboto-SemiBold.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; C3614D19A4004E3E858E4CEC /* WorkSans-Thin.ttf */ = {isa = PBXFileReference; name = "WorkSans-Thin.ttf"; path = "../app/assets/fonts/WorkSans-Thin.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -136,14 +136,14 @@
C38CA987921A4CA4AEDBB3E5 /* Resources */ = { C38CA987921A4CA4AEDBB3E5 /* Resources */ = {
isa = "PBXGroup"; isa = "PBXGroup";
children = ( children = (
C93B020BF2D44311BFAF317D /* Roboto-Black.ttf */, 6606F41B1382422DA695F61C /* WorkSans-Bold.ttf */,
E8DE31AC3A3B46AFBAB8E623 /* Roboto-Bold.ttf */, 1569DC7537534ED39A79EE9E /* WorkSans-ExtraBold.ttf */,
6D158A6D27784CB3AAFC4572 /* Roboto-ExtraBold.ttf */, FF48E43749B74116A2C4083C /* WorkSans-ExtraLight.ttf */,
6787284EF58F40B4A29BE810 /* Roboto-ExtraLight.ttf */, B8C4C96FCA144E859DC2AFDA /* WorkSans-Light.ttf */,
F3B7B24AB39048E28AA013C6 /* Roboto-Light.ttf */, 55E647ABF16B47F6A83403C0 /* WorkSans-Medium.ttf */,
57615910A7564380B1D23731 /* Roboto-Medium.ttf */, 589149FBA9F64E9F94AA50AF /* WorkSans-Regular.ttf */,
B9D41D27862846A8A6563185 /* Roboto-Regular.ttf */, A58733FB00504503BFBF4295 /* WorkSans-SemiBold.ttf */,
7539BBD08F0743178F5517A3 /* Roboto-SemiBold.ttf */, C3614D19A4004E3E858E4CEC /* WorkSans-Thin.ttf */,
); );
name = Resources; name = Resources;
sourceTree = "<group>"; sourceTree = "<group>";
@ -218,14 +218,14 @@
files = ( files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
9BFF7E8F967043379EA34EF5 /* Roboto-Black.ttf in Resources */, 90EC1A731F2F480594C0F9D1 /* WorkSans-Bold.ttf in Resources */,
64ADC498A16B4DD2979F9EC6 /* Roboto-Bold.ttf in Resources */, 7E1975A765074059A27FA6F1 /* WorkSans-ExtraBold.ttf in Resources */,
9A05BCBBB57F42CF891B4E76 /* Roboto-ExtraBold.ttf in Resources */, E09CC0AFCD63425FABA5714F /* WorkSans-ExtraLight.ttf in Resources */,
E9AB985237534D1A92E3A5C8 /* Roboto-ExtraLight.ttf in Resources */, 6A06861DDC314E49B482B4EB /* WorkSans-Light.ttf in Resources */,
A345282A09764F4B8935E1CE /* Roboto-Light.ttf in Resources */, 3BEFE3BEC3334662878A37D5 /* WorkSans-Medium.ttf in Resources */,
6C3A045CF24641D79616809F /* Roboto-Medium.ttf in Resources */, 6E9607F0F9DE4649802D618B /* WorkSans-Regular.ttf in Resources */,
A79B0AFEC3DA42AAAA56DC75 /* Roboto-Regular.ttf in Resources */, DCDB35B731E1422DBD1481D1 /* WorkSans-SemiBold.ttf in Resources */,
264B0BD7896E430EB2761212 /* Roboto-SemiBold.ttf in Resources */, 25B52D1C5AB64F039BEF062F /* WorkSans-Thin.ttf in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -49,17 +49,16 @@
<false/> <false/>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>Roboto-Black.ttf</string> <string>WorkSans-Bold.ttf</string>
<string>Roboto-Bold.ttf</string> <string>WorkSans-ExtraBold.ttf</string>
<string>Roboto-ExtraBold.ttf</string> <string>WorkSans-ExtraLight.ttf</string>
<string>Roboto-ExtraLight.ttf</string> <string>WorkSans-Light.ttf</string>
<string>Roboto-Light.ttf</string> <string>WorkSans-Medium.ttf</string>
<string>Roboto-Medium.ttf</string> <string>WorkSans-Regular.ttf</string>
<string>Roboto-Regular.ttf</string> <string>WorkSans-SemiBold.ttf</string>
<string>Roboto-SemiBold.ttf</string> <string>WorkSans-Thin.ttf</string>
</array> </array>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos and videos.</string> <string>This app needs access to the camera to take photos and videos.</string>
</dict> </dict>
</plist> </plist>

View File

@ -2,36 +2,36 @@
"migIndex": 1, "migIndex": 1,
"data": [ "data": [
{ {
"path": "app/assets/fonts/Roboto-Black.ttf", "path": "app/assets/fonts/WorkSans-Bold.ttf",
"sha1": "d1678489a8d5645f16486ec52d77b651ff0bf327" "sha1": "ec84061651ead3c3c5cbb61c2d338aca0bacdc1e"
}, },
{ {
"path": "app/assets/fonts/Roboto-Bold.ttf", "path": "app/assets/fonts/WorkSans-ExtraBold.ttf",
"sha1": "508c35dee818addce6cc6d1fb6e42f039da5a7cf" "sha1": "0b371d1dbfbdd15db880bbd129b239530c71accb"
}, },
{ {
"path": "app/assets/fonts/Roboto-ExtraBold.ttf", "path": "app/assets/fonts/WorkSans-ExtraLight.ttf",
"sha1": "3dbfd71b6fbcfbd8e7ee8a8dd033dc5aaad63249" "sha1": "74596e55487e2961b6c43993698d658e2ceee77b"
}, },
{ {
"path": "app/assets/fonts/Roboto-ExtraLight.ttf", "path": "app/assets/fonts/WorkSans-Light.ttf",
"sha1": "df556e64732e5c272349e13cb5f87591a1ae779b" "sha1": "293e11dae7e8b930bf5eea0b06ca979531f22189"
}, },
{ {
"path": "app/assets/fonts/Roboto-Light.ttf", "path": "app/assets/fonts/WorkSans-Medium.ttf",
"sha1": "318b44c0a32848f78bf11d4fbf3355d00647a796" "sha1": "c281f8454dd193c2260e43ae2de171c5dd4086e4"
}, },
{ {
"path": "app/assets/fonts/Roboto-Medium.ttf", "path": "app/assets/fonts/WorkSans-Regular.ttf",
"sha1": "fa5192203f85ddb667579e1bdf26f12098bb873b" "sha1": "5e0183b29b57c54595c62ac6bc223b21f1434226"
}, },
{ {
"path": "app/assets/fonts/Roboto-Regular.ttf", "path": "app/assets/fonts/WorkSans-SemiBold.ttf",
"sha1": "3bff51436aa7eb995d84cfc592cc63e1316bb400" "sha1": "64b8fe156fafce221a0f66504255257053fc6062"
}, },
{ {
"path": "app/assets/fonts/Roboto-SemiBold.ttf", "path": "app/assets/fonts/WorkSans-Thin.ttf",
"sha1": "9ca139684fe902c8310dd82991648376ac9838db" "sha1": "a62251331038fdd079c47bc413a350efbf702db8"
} }
] ]
} }