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