Skip to content

KennyWestKhan/Queue-Management-Client

Repository files navigation

Medp Queue Management - Mobile App

A modern React Native mobile application built with Expo for real-time patient queue management and online consultations.

πŸ“± Features

  • Real-time Queue Tracking: Live position updates and wait time estimates
  • Role-based Interface: Separate experiences for patients and doctors
  • WebSocket Integration: Instant updates for queue changes and status
  • Mobile-first Design: Optimized for iOS and Android devices
  • Offline Resilience: Graceful handling of network connectivity issues
  • Cross-platform: Single codebase for iOS, Android, and web
  • TypeScript: Full type safety and better developer experience

🎯 User Experiences

For Patients

  • Queue Status Dashboard: Real-time position and estimated wait time
  • Doctor Selection: Choose from available healthcare providers
  • Doctor Information: View specializations, fees, and availability

For Doctors

  • Queue Management: Complete control over patient consultations
  • Availability Toggle: Easy online/offline status management
  • Real-time Updates: Instant notifications for queue changes

πŸ› οΈ Prerequisites

  • Node.js (v16.0.0 or higher)
  • Expo CLI (npm install -g @expo/cli)
  • iOS Simulator (Mac) or Android Studio (Windows/Mac/Linux)
  • Physical device (optional, for testing)
  • ngrok (for local development with WebSocket support)

πŸš€ Installation

1. Install Dependencies

# Navigate to mobile app directory
cd medp-frontend

# Install dependencies
npm install

# Install Expo dependencies
npx expo install

2. Configuration

Set Up ngrok for Local Development

  1. Install ngrok:

    # Using npm
    npm install -g ngrok
    
    # Or download from https://ngrok.com/download
  2. Start ngrok tunnel (after starting your backend server):

    # If your backend runs on port 3001
    ngrok http 3001
  3. Copy the generated HTTPS URL (e.g., https://xxxx-xx-xx-xxx-xx.ngrok-free.app)

Update API Endpoint

Edit src\config\config.ts:

export const config = {
  development: {
    baseURL: "https://your-ngrok-url.ngrok-free.app", // Replace with your ngrok URL
    wsURL: "wss://your-ngrok-url.ngrok-free.app",
  },
  production: {
    baseURL: "https://your-production-api.com",
    wsURL: "wss://your-production-api.com",
  },
};

<!-- **Find Your IP Address:** -->

<!-- ```bash -->
<!-- # Windows
ipconfig | findstr "IPv4"

# Mac/Linux
ifconfig | grep inet -->

<!-- # Example: http://192.168.1.105:3001 -->
<!-- ``` -->

#### Expo Configuration

Update `app.json` if needed:

```json
{
  "expo": {
    "name": "MedPharma Queue",
    "slug": "medp-queue",
    "version": "1.0.0",
    "platforms": ["ios", "android", "web"],
    "ios": {
      "bundleIdentifier": "com.yourcompany.medpqueue"
    },
    "android": {
      "package": "com.yourcompany.medpqueue"
    }
  }
}

WebSocket Testing

The project includes a WebSocket testing tool (test-websocket.html) that allows you to:

  • Test real-time queue management features
  • Simulate patient and doctor interactions
  • Monitor WebSocket events
  • Debug connection issues

To use the WebSocket tester:

  1. Open test-websocket.html in your browser
  2. Enter your ngrok URL in the server URL field
  3. Click "Connect" to establish WebSocket connection
  4. Use the patient and doctor testing panels to simulate various scenarios

πŸƒβ€β™‚οΈ Running the Application

  1. Start the backend server first (follow backend README)

  2. Start ngrok tunnel:

    ngrok http 3001
  3. Update config with ngrok URL

  4. Start the Expo development server:

πŸ§ͺ Testing WebSocket Features

  1. Open test-websocket.html in your browser
  2. Use the testing panels to:
    • Simulate patient queue interactions
    • Test doctor availability updates
    • Monitor real-time events
    • Debug connection issues

Key testing scenarios:

  • Patient joining/leaving queue
  • Doctor toggling availability
  • Queue position updates
  • Consultation status changes
  • Connection error handling

πŸ”Œ WebSocket Events Reference

Patient Events

  • queueUpdate: Position and wait time updates
  • consultationStarted: Doctor ready to see patient
  • consultationCompleted: Consultation finished
  • patientRemoved: Removed from queue

Doctor Events

  • patientAdded: New patient joined queue
  • queueChanged: Queue status changes
  • doctorAvailabilityUpdate: Availability status changes

🚦 Error Handling

The application includes robust error handling for:

  • WebSocket connection issues
  • Network connectivity problems
  • Server errors
  • Invalid queue operations

Error recovery strategies:

  • Automatic reconnection attempts
  • Offline mode support
  • Graceful degradation
  • User-friendly error messages

πŸ“ Development Notes

  • Always test WebSocket features using the provided tester
  • Monitor ngrok status for connection issues
  • Check browser console for detailed error messages
  • Use mock data for testing edge cases
  • Remember to update ngrok URL after tunnel restarts

Development Mode

# Start Expo development server
npm start

# Or with specific platform
npm run android  # Android emulator/device
npm run ios      # iOS simulator (Mac only)
npm run web      # Web browser

Using Expo Go App

  1. Install Expo Go on your mobile device:

  2. Scan QR Code from the terminal or Expo DevTools

  3. Ensure same network: Device and development computer on same WiFi

Using Simulators/Emulators

iOS Simulator (Mac)

# Install Xcode from Mac App Store
# Start iOS simulator
npm run ios

# Or manually open simulator
open -a Simulator

Android Emulator

# Install Android Studio
# Create and start AVD (Android Virtual Device)
npm run android

# Or start emulator manually
~/Android/Sdk/emulator/emulator -avd YOUR_AVD_NAME

πŸ“± App Structure

Screen Navigation Flow

RoleSelectionScreen
    ↓
BookingScreen (Patient/Doctor)
    ↓
PatientQueueScreen OR DoctorDashboard

Key Components

Screens

  • RoleSelectionScreen: Choose patient or doctor role
  • BookingScreen: Doctor selection and queue joining
  • PatientQueueScreen: Real-time queue status for patients
  • DoctorDashboard: Queue management for doctors

Context Providers

  • QueueContext: Global queue state management
  • SocketContext: WebSocket connection and events

Services

  • Real-time WebSocket communication
  • API calls for queue operations
  • Local state persistence

πŸ”§ Development

Project Structure

src/
β”œβ”€β”€ screens/              # Main app screens
β”‚   β”œβ”€β”€ RoleSelectionScreen.tsx
β”‚   β”œβ”€β”€ BookingScreen.tsx
β”‚   β”œβ”€β”€ PatientQueueScreen.tsx
β”‚   └── DoctorDashboard.tsx
β”œβ”€β”€ components/           # Reusable components
β”‚   β”œβ”€β”€ common/          # Shared components
β”‚   β”œβ”€β”€ patient/         # Patient-specific components
β”‚   └── doctor/          # Doctor-specific components
β”œβ”€β”€ context/             # React Context providers
β”‚   β”œβ”€β”€ QueueContext.tsx
β”‚   └── SocketContext.tsx
β”œβ”€β”€ hooks/               # Custom React hooks
β”œβ”€β”€ services/            # API and external services
β”œβ”€β”€ utils/               # Utility functions
β”œβ”€β”€ types/               # TypeScript definitions
└── styles/              # Styling and themes

Adding New Features

1. Create Component

// src/components/common/NewComponent.tsx
import React from "react";
import { View, Text, StyleSheet } from "react-native";

interface NewComponentProps {
  title: string;
  onPress: () => void;
}

const NewComponent: React.FC<NewComponentProps> = ({ title, onPress }) => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>{title}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 16,
    backgroundColor: "#ffffff",
    borderRadius: 8,
  },
  title: {
    fontSize: 18,
    fontWeight: "bold",
    color: "#1e293b",
  },
});

export default NewComponent;

2. Add to Screen

import NewComponent from "../components/common/NewComponent";

// Inside your screen component
<NewComponent title="Hello World" onPress={() => console.log("Pressed!")} />;

State Management

Using Queue Context

import { useQueue } from '../context/QueueContext';

const MyComponent = () => {
  const { state, addPatientToQueue, getPatientPosition } = useQueue();

  const handleAddPatient = () => {
    const patientId = addPatientToQueue({
      name: 'John Doe',
      doctorId: 'doc1',
      estimatedDuration: 15,
    });
  };

  return (
    // Your component JSX
  );
};

Using Socket Context

import { useSocket } from '../context/SocketContext';

const MyComponent = () => {
  const { socket, isConnected, joinPatientRoom } = useSocket();

  useEffect(() => {
    if (isConnected) {
      joinPatientRoom(patientId, doctorId);
    }
  }, [isConnected]);

  return (
    // Your component JSX
  );
};

🎨 Styling & Theming

Style Guidelines

// Use consistent spacing
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20, // Standard padding
    backgroundColor: "#f8fafc",
  },
  card: {
    backgroundColor: "#ffffff",
    borderRadius: 16, // Rounded corners
    padding: 20,
    marginBottom: 16, // Consistent spacing
    shadowColor: "#000", // Subtle shadows
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 8,
    elevation: 4, // Android shadow
  },
  title: {
    fontSize: 24, // Large titles
    fontWeight: "bold",
    color: "#1e293b", // Dark text
    marginBottom: 8,
  },
  subtitle: {
    fontSize: 16, // Regular text
    color: "#64748b", // Muted text
    lineHeight: 22,
  },
});

Color Palette

// Define colors for consistency
const colors = {
  primary: "#3b82f6", // Blue
  success: "#10b981", // Green
  warning: "#f59e0b", // Orange
  error: "#ef4444", // Red
  text: {
    primary: "#1e293b", // Dark gray
    secondary: "#64748b", // Medium gray
    muted: "#9ca3af", // Light gray
  },
  background: {
    primary: "#ffffff", // White
    secondary: "#f8fafc", // Light gray
    accent: "#eff6ff", // Light blue
  },
};

πŸ§ͺ Testing

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Test Structure

// __tests__/components/PatientCard.test.tsx
import React from "react";
import { render, fireEvent } from "@testing-library/react-native";
import PatientCard from "../src/components/doctor/PatientCard";

describe("PatientCard", () => {
  const mockPatient = {
    id: "123",
    name: "John Doe",
    status: "waiting",
    joinedAt: new Date(),
  };

  it("renders patient information correctly", () => {
    const { getByText } = render(
      <PatientCard patient={mockPatient} onStatusChange={() => {}} />
    );

    expect(getByText("John Doe")).toBeTruthy();
    expect(getByText("waiting")).toBeTruthy();
  });

  it("calls onStatusChange when button pressed", () => {
    const mockOnStatusChange = jest.fn();
    const { getByText } = render(
      <PatientCard patient={mockPatient} onStatusChange={mockOnStatusChange} />
    );

    fireEvent.press(getByText("Start Consultation"));
    expect(mockOnStatusChange).toHaveBeenCalledWith("123", "consulting");
  });
});

Manual Testing

  1. Patient Flow Testing

    • Select patient role
    • Choose doctor and join queue
    • Verify real-time position updates
    • Test status transitions
  2. Doctor Flow Testing

    • Select doctor role
    • Access dashboard
    • Manage patient queue
    • Test availability toggle
  3. WebSocket Testing

    • Test connection/disconnection
    • Verify real-time updates
    • Test network interruption recovery

πŸ“¦ Building & Deployment

Development Build

# Create development build
eas build --profile development --platform all

# Create development build for specific platform
eas build --profile development --platform android
eas build --profile development --platform ios

Production Build

1. Configure EAS Build

# Install EAS CLI
npm install -g @expo/eas-cli

# Login to Expo
eas login

# Configure build
eas build:configure

2. Build for App Stores

# Build for both platforms
eas build --platform all

# Build for specific platform
eas build --platform android  # Google Play Store
eas build --platform ios      # Apple App Store

3. Submit to Stores

# Submit to stores
eas submit --platform all

# Submit to specific store
eas submit --platform android  # Google Play
eas submit --platform ios      # Apple App Store

Over-the-Air Updates

# Create update
eas update --branch production --message "Bug fixes and improvements"

# Create update for specific channel
eas update --channel preview --message "Preview features"

πŸ”§ Configuration

Environment Configuration

// app.config.js
export default {
  expo: {
    name: "MedPharma Queue",
    slug: "medp-queue",
    extra: {
      apiUrl: process.env.API_URL || "http://localhost:3001", //or ngrok link
      socketUrl: process.env.SOCKET_URL || "http://localhost:3001",
    },
  },
};

// Access in app
import Constants from "expo-constants";
const apiUrl = Constants.expoConfig?.extra?.apiUrl;

Platform-Specific Configuration

// Platform-specific code
import { Platform } from "react-native";

const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS === "ios" ? 44 : 20, // iOS status bar
  },
});

// Platform-specific components
const HeaderComponent = Platform.select({
  ios: () => <IOSHeader />,
  android: () => <AndroidHeader />,
  default: () => <DefaultHeader />,
});

πŸ” Debugging

Debug Tools

# Enable React Native debugger
# Install React Native Debugger app
# Shake device or Cmd+D (iOS) / Cmd+M (Android)

# Enable remote debugging
# Access: http://localhost:8081/debugger-ui

# Flipper integration (advanced)
# Install Flipper desktop app
# Enable Flipper in your app

Common Issues

Metro bundler cache issues:

# Clear Expo cache
expo start --clear

# Clear npm cache
npm start -- --reset-cache

iOS Simulator issues:

# Reset iOS Simulator
Device β†’ Erase All Content and Settings

# Rebuild app
rm -rf node_modules
npm install
npm run ios

Android emulator issues:

# Wipe emulator data
# In Android Studio: AVD Manager β†’ Actions β†’ Wipe Data

# Restart ADB
adb kill-server
adb start-server

WebSocket connection issues:

  • Verify backend server is running
  • Check IP address in src\config\config.ts
  • Ensure firewall allows connections
  • Test with device on same network

πŸ“Š Performance Optimization

Best Practices

  1. Image Optimization

    // Use optimized image component
    import { Image } from "expo-image";
    
    <Image
      source={{ uri: "https://example.com/image.jpg" }}
      style={{ width: 200, height: 200 }}
      placeholder="Loading..."
      contentFit="cover"
      transition={1000}
    />;
  2. List Performance

    // Use FlatList for large datasets
    <FlatList
      data={patients}
      renderItem={({ item }) => <PatientCard patient={item} />}
      keyExtractor={(item) => item.id}
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      windowSize={10}
    />
  3. State Management

    // Use React.memo to prevent unnecessary re-renders
    const PatientCard = React.memo<PatientCardProps>(({ patient }) => {
      return (
        // Component JSX
      );
    });
    
    // Use useCallback for event handlers
    const handleStatusUpdate = useCallback((patientId: string, status: string) => {
      updatePatientStatus(patientId, status);
    }, [updatePatientStatus]);

πŸ“± Device Testing

iOS Testing

  1. Physical Device

    • Enable Developer Mode in Settings
    • Trust computer in device settings
    • Run: npm run ios --device
  2. TestFlight (Beta Testing)

    • Upload build to App Store Connect
    • Add beta testers
    • Send TestFlight invitations

Android Testing

  1. Physical Device

    • Enable Developer Options
    • Enable USB Debugging
    • Run: npm run android --device
  2. Google Play Console (Beta Testing)

    • Upload AAB to Play Console
    • Create internal/closed testing track
    • Add beta testers

πŸ“ž Support & Troubleshooting

Getting Help

Common Troubleshooting

App won't start:

  1. Clear cache: expo start --clear
  2. Restart Metro: npx react-native start --reset-cache
  3. Reinstall dependencies: rm -rf node_modules && npm install

Real-time updates not working:

  1. Check backend server is running
  2. Verify WebSocket URL in SocketContext
  3. Test network connectivity
  4. Check console for connection errors

Build failures:

  1. Check Expo CLI version: expo --version
  2. Update dependencies: npx expo install --fix
  3. Check platform compatibility
  4. Review error logs in EAS Build

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published