From a5fb65f93211cb8dea3413d14b141bed22ef4c9c Mon Sep 17 00:00:00 2001 From: TJP <69581225+JavaProgswing@users.noreply.github.com> Date: Tue, 26 May 2026 21:05:52 +0530 Subject: [PATCH] feat(mobile): implement NFC tag writing support to share DevCards --- .../android/app/src/main/AndroidManifest.xml | 27 ++++++++ apps/mobile/ios/DevCard/Info.plist | 2 + apps/mobile/package.json | 1 + apps/mobile/src/screens/SettingsScreen.tsx | 65 ++++++++++++++++++- 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/apps/mobile/android/app/src/main/AndroidManifest.xml b/apps/mobile/android/app/src/main/AndroidManifest.xml index e69de29..cb3ee7b 100644 --- a/apps/mobile/android/app/src/main/AndroidManifest.xml +++ b/apps/mobile/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/apps/mobile/ios/DevCard/Info.plist b/apps/mobile/ios/DevCard/Info.plist index 6fce294..abc9042 100644 --- a/apps/mobile/ios/DevCard/Info.plist +++ b/apps/mobile/ios/DevCard/Info.plist @@ -36,6 +36,8 @@ NSLocationWhenInUseUsageDescription + NFCReaderUsageDescription + DevCard needs NFC to write your profile link to your physical card. UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 8bb6ccf..23de762 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -25,6 +25,7 @@ "react-dom": "^19.1.0", "react-native": "0.81.5", "react-native-gesture-handler": "^2.28.0", + "react-native-nfc-manager": "^3.14.12", "react-native-qrcode-svg": "^6.3.0", "react-native-reanimated": "^4.1.7", "react-native-safe-area-context": "^5.6.2", diff --git a/apps/mobile/src/screens/SettingsScreen.tsx b/apps/mobile/src/screens/SettingsScreen.tsx index 58f952f..f5ed90f 100644 --- a/apps/mobile/src/screens/SettingsScreen.tsx +++ b/apps/mobile/src/screens/SettingsScreen.tsx @@ -15,8 +15,7 @@ import { useNavigation } from '@react-navigation/native'; import { COLORS, SPACING, FONT_SIZE, BORDER_RADIUS } from '../theme/tokens'; import { useAuth } from '../context/AuthContext'; import { API_BASE_URL } from '../config'; - -import { useNavigation } from '@react-navigation/native'; +import NfcManager, { Ndef, NfcTech } from 'react-native-nfc-manager'; export default function SettingsScreen() { const navigation = useNavigation(); @@ -27,6 +26,51 @@ export default function SettingsScreen() { const [role, setRole] = useState(user?.role || ''); const [company, setCompany] = useState(user?.company || ''); const [saving, setSaving] = useState(false); + const [writingNfc, setWritingNfc] = useState(false); + + const writeNfcTag = async () => { + try { + const supported = await NfcManager.isSupported(); + if (!supported) { + Alert.alert('Error', 'NFC is not supported on this device'); + return; + } + + setWritingNfc(true); + await NfcManager.start(); + + const res = await fetch(`${API_BASE_URL}/api/nfc/payload`, { + headers: { Authorization: `Bearer ${token}` }, + }); + + if (!res.ok) { + throw new Error('Failed to fetch NFC payload'); + } + + const data = await res.json(); + if (!data.payload) { + throw new Error('Invalid payload received'); + } + + Alert.alert('NFC', 'Hold your phone near an NFC tag'); + await NfcManager.requestTechnology(NfcTech.Ndef); + + const bytes = Ndef.encodeMessage([ + Ndef.uriRecord(data.payload), + ]); + + if (bytes) { + await NfcManager.ndefHandler.writeNdefMessage(bytes); + Alert.alert('Success', 'Successfully wrote DevCard to NFC tag!'); + } + } catch (ex: any) { + console.warn(ex); + Alert.alert('Error', ex.message || 'Failed to write NFC tag. Please try again.'); + } finally { + NfcManager.cancelTechnologyRequest(); + setWritingNfc(false); + } + }; const handleSave = async () => { setSaving(true); @@ -118,6 +162,23 @@ export default function SettingsScreen() { + {/* Physical Cards */} + + Physical Cards + + + 💳 + + {writingNfc ? 'Writing to NFC...' : 'Write to NFC Card'} + + + → + + + Log Out