diff --git a/app.config.js b/app.config.js
index f3ca81a..372599a 100644
--- a/app.config.js
+++ b/app.config.js
@@ -1,6 +1,17 @@
// app.config.js
require("dotenv").config();
+// const isDev = process.env.NODE_ENV === "development";
+// const isStaging = process.env.NEXT_PUBLIC_ENV === "staging";
+// const isProd = process.env.NEXT_PUBLIC_ENV === "production";
+
+// Domain berdasarkan environment
+// const domain = isDev
+// ? "localhost:3000"
+// : isStaging
+// ? "cld-dkr-hipmi-stg.wibudev.com"
+// : "hipmi.muku.id"; // Production domain
+
export default {
name: "HIPMI Badung Connect",
slug: "hipmi-mobile",
@@ -20,7 +31,9 @@ export default {
NSLocationWhenInUseUsageDescription:
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
},
- associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
+ associatedDomains: [
+ "applinks:cld-dkr-hipmi-stg.wibudev.com",
+ ],
buildNumber: "3",
},
@@ -41,7 +54,7 @@ export default {
data: [
{
scheme: "https",
- host: "cld-dkr-staging-hipmi.wibudev.com",
+ host: "cld-dkr-hipmi-stg.wibudev.com",
pathPrefix: "/",
},
],
diff --git a/docs/QR_CODE_TESTING.md b/docs/QR_CODE_TESTING.md
new file mode 100644
index 0000000..57b86ad
--- /dev/null
+++ b/docs/QR_CODE_TESTING.md
@@ -0,0 +1,253 @@
+# QR Code Testing Guide - HIPMI Mobile
+
+## 📋 Overview
+
+Dokumentasi ini menjelaskan cara testing QR Code untuk Universal Links (iOS) dan App Links (Android) pada fitur Event Confirmation.
+
+## 🔧 Update Terbaru
+
+File `screens/Admin/Event/EventDetailQRCode.tsx` telah diupdate dengan fitur:
+- **Toggle Button**: Switch antara HTTPS link dan Custom Scheme link
+- **HTTPS Link**: Untuk testing Universal Links/App Links dengan domain staging
+- **Custom Scheme**: Untuk testing langsung tanpa domain verification
+
+## 🎯 Cara Testing QR Code
+
+### Opsi 1: HTTPS Link (Recommended untuk Production)
+
+**Gunakan tombol "HTTPS"** di component QR Code.
+
+**Link yang di-generate:**
+```
+https://cld-dkr-staging-hipmi.wibudev.com/event/{id}/confirmation?userId={userId}
+```
+
+**Cara kerja:**
+1. User scan QR code dengan kamera
+2. Safari/Chrome terbuka dengan URL HTTPS
+3. iOS/Android mendeteksi domain terverifikasi
+4. App terbuka otomatis dan menuju halaman confirmation
+
+**Prerequisites:**
+- ✅ File `apple-app-site-association` harus accessible di Next.js server
+- ✅ File `assetlinks.json` harus accessible di Next.js server
+- ✅ Domain harus terverifikasi di app.config.js
+- ✅ App harus di-build ulang setelah perubahan domain
+
+**Testing Steps:**
+```bash
+# 1. Pastikan .well-known files accessible
+curl https://cld-dkr-staging-hipmi.wibudev.com/.well-known/apple-app-site-association
+curl https://cld-dkr-staging-hipmi.wibudev.com/.well-known/assetlinks.json
+
+# 2. Rebuild app
+bunx expo prebuild --clean
+
+# 3. Run di physical device (bukan simulator)
+bun run android # untuk Android
+bun run ios # untuk iOS
+```
+
+### Opsi 2: Custom Scheme Link (Untuk Development/Testing Cepat)
+
+**Gunakan tombol "Custom Scheme"** di component QR Code.
+
+**Link yang di-generate:**
+```
+hipmimobile://event/{id}/confirmation?userId={userId}
+```
+
+**Cara kerja:**
+1. User scan QR code dengan kamera
+2. iOS: Pilih "Open in HIPMI Badung Connect"
+3. Android: Langsung buka app
+4. App terbuka dan menuju halaman confirmation
+
+**Keuntungan:**
+- ✅ Tidak butuh domain verification
+- ✅ Bisa testing langsung tanpa rebuild
+- ✅ Cocok untuk development
+
+**Kekurangan:**
+- ❌ Tidak bisa dibuka dari web browser
+- ❌ Tidak support universal linking dari website lain
+
+## 📱 Testing Checklist
+
+### iOS (Universal Links)
+
+- [ ] File `apple-app-site-association` valid dan accessible
+- [ ] Domain terdaftar di `app.config.js` → `ios.associatedDomains`
+- [ ] Bundle ID match dengan konfigurasi
+- [ ] Team ID benar di apple-app-site-association
+- [ ] Test dengan **physical device** (simulator tidak support)
+- [ ] Test dengan **Safari** (bukan Chrome)
+- [ ] Long press link → ada opsi "Open"
+
+**Debug iOS:**
+```bash
+# Cek apple-app-site-association
+curl -I https://cld-dkr-staging-hipmi.wibudev.com/.well-known/apple-app-site-association
+
+# Harus return:
+# Content-Type: application/json
+# HTTP/2 200
+```
+
+### Android (App Links)
+
+- [ ] File `assetlinks.json` valid dan accessible
+- [ ] SHA256 fingerprint benar
+- [ ] Package name match
+- [ ] Intent filters terdaftar di app.config.js
+- [ ] Test dengan **physical device**
+- [ ] Test dengan **Chrome**
+
+**Debug Android:**
+```bash
+# Dapatkan SHA256 fingerprint
+cd android
+./gradlew signingReport
+
+# Cek assetlinks.json
+curl https://cld-dkr-staging-hipmi.wibudev.com/.well-known/assetlinks.json
+```
+
+## 🐛 Troubleshooting
+
+### Problem: QR Scan Terbuka di Safari, Tidak Balik ke App
+
+**Penyebab:**
+- Domain belum terverifikasi untuk Universal Links/App Links
+- File `.well-known` tidak accessible atau invalid
+- App belum di-rebuild setelah perubahan domain
+
+**Solusi:**
+1. Pastikan file `.well-known` accessible:
+ ```bash
+ curl https://cld-dkr-staging-hipmi.wibudev.com/.well-known/apple-app-site-association
+ ```
+
+2. Rebuild app:
+ ```bash
+ bunx expo prebuild --clean
+ bun run android # atau bun run ios
+ ```
+
+3. Gunakan **Custom Scheme** untuk testing cepat
+
+### Problem: Link Tidak Membuka App Sama Sekali
+
+**Cek:**
+1. App sudah terinstall di device
+2. Link format benar (hipmimobile:// atau https://)
+3. Route handler sudah ada di app folder
+
+**Test manual:**
+```bash
+# iOS Simulator
+xcrun simctl openurl booted "hipmimobile://event/123/confirmation?userId=456"
+
+# Android Emulator
+adb shell am start -W -a android.intent.action.VIEW \
+ -d "hipmimobile://event/123/confirmation?userId=456" \
+ com.bip.hipmimobileapp
+```
+
+### Problem: "Cannot GET /event/..." di Next.js
+
+**Penyebab:**
+Route `/event/[id]/confirmation` tidak ada di Next.js server
+
+**Solusi:**
+Pastikan Next.js project punya file:
+```
+public/.well-known/apple-app-site-association
+public/.well-known/assetlinks.json
+```
+
+Dan API route untuk handle:
+```
+pages/api/event/[id]/confirmation.ts
+```
+
+## 📄 File Configuration
+
+### app.config.js - iOS
+```javascript
+ios: {
+ associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
+}
+```
+
+### app.config.js - Android
+```javascript
+android: {
+ intentFilters: [
+ {
+ action: "VIEW",
+ autoVerify: true,
+ data: [
+ {
+ scheme: "https",
+ host: "cld-dkr-staging-hipmi.wibudev.com",
+ pathPrefix: "/",
+ },
+ ],
+ category: ["BROWSABLE", "DEFAULT"],
+ },
+ ],
+}
+```
+
+### apple-app-site-association (Next.js)
+```json
+{
+ "applinks": {
+ "apps": [],
+ "details": [
+ {
+ "appID": "TEAM_ID.com.anonymous.hipmi-mobile",
+ "paths": ["/event/*/confirmation"]
+ }
+ ]
+ }
+}
+```
+
+### assetlinks.json (Next.js)
+```json
+[
+ {
+ "relation": ["delegate_permission/common.handle_all_urls"],
+ "target": {
+ "namespace": "android_app",
+ "package_name": "com.bip.hipmimobileapp",
+ "sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
+ }
+ }
+]
+```
+
+## 🎓 Best Practices
+
+1. **Development**: Gunakan Custom Scheme untuk testing cepat
+2. **Staging**: Gunakan HTTPS link dengan domain staging
+3. **Production**: Gunakan HTTPS link dengan domain production
+4. **Testing**: Selalu test di physical device, bukan simulator
+5. **Debugging**: Enable logging di confirmation page untuk track deep link
+
+## 🔗 Related Files
+
+- `screens/Admin/Event/EventDetailQRCode.tsx` - QR Code generator
+- `app/(application)/(user)/event/[id]/confirmation.tsx` - Confirmation page
+- `app.config.js` - App configuration
+- `service/api-config.ts` - API configuration (DEEP_LINK_URL)
+
+## 📞 Support
+
+Jika masih ada masalah:
+1. Cek logs di console
+2. Test manual dengan adb/xcrun
+3. Verify .well-known files dengan curl
+4. Pastikan app rebuild setelah perubahan config
diff --git a/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj b/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj
index d7d08be..7784b2a 100644
--- a/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj
+++ b/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj
@@ -183,6 +183,7 @@
FB0CB57BF4D74C1D87C2036C /* Remove signature files (Xcode workaround) */,
14B3DE54EE4049AEB1EADA6B /* Remove signature files (Xcode workaround) */,
B4CF5E09DBB44A4FB9CB91B9 /* Remove signature files (Xcode workaround) */,
+ C894BD25C8224984AAD73398 /* Remove signature files (Xcode workaround) */,
);
buildRules = (
);
@@ -995,6 +996,23 @@
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
";
};
+ C894BD25C8224984AAD73398 /* Remove signature files (Xcode workaround) */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ name = "Remove signature files (Xcode workaround)";
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ shellPath = /bin/sh;
+ shellScript = "
+ echo \"Remove signature files (Xcode workaround)\";
+ rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
+ ";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
diff --git a/screens/Admin/Event/EventDetailQRCode.tsx b/screens/Admin/Event/EventDetailQRCode.tsx
index 7604aa6..b7b5cef 100644
--- a/screens/Admin/Event/EventDetailQRCode.tsx
+++ b/screens/Admin/Event/EventDetailQRCode.tsx
@@ -1,26 +1,93 @@
-import { BaseBox, LoaderCustom, Spacing, StackCustom, TextCustom } from "@/components";
+import {
+ BaseBox,
+ ButtonCustom,
+ LoaderCustom,
+ Spacing,
+ StackCustom,
+ TextCustom,
+} from "@/components";
+import { MainColor } from "@/constants/color-palet";
+import { BASE_URL } from "@/service/api-config";
+import { useLocalSearchParams } from "expo-router";
+import { useState } from "react";
+import { StyleSheet } from "react-native";
import QRCode from "react-native-qrcode-svg";
interface EventDetailQRCodeProps {
- qrValue: string;
+ userId: string;
isLoading: boolean;
}
-export function EventDetailQRCode({ qrValue, isLoading }: EventDetailQRCodeProps) {
+export function EventDetailQRCode({
+ userId,
+ isLoading,
+}: EventDetailQRCodeProps) {
+ const { id } = useLocalSearchParams();
+ const [useHttpsLink, setUseHttpsLink] = useState(true);
+
+ // HTTPS link untuk Universal Links (iOS) dan App Links (Android)
+ // Ini akan membuka file .well-known di Next.js server Anda
+ const httpsLink = `https://cld-dkr-hipmi-stg.wibudev.com/event/${id}/confirmation?userId=${userId}`;
+
+ // Custom scheme link untuk fallback atau testing tanpa universal links
+ const deepLinkURL = `${BASE_URL}/event/${id}/confirmation?userId=${userId}`;
+
+ // Toggle antara HTTPS link dan custom scheme
+ const qrValue = useHttpsLink ? httpsLink : deepLinkURL;
+
return (
QR Code Event
- {isLoading ? (
-
- ) : (
-
- )}
+ {isLoading ? : }
+
+ {qrValue}
+
+
+
+ setUseHttpsLink(true)}
+ backgroundColor={useHttpsLink ? MainColor.yellow : "transparent"}
+ textColor={useHttpsLink ? MainColor.black : MainColor.yellow}
+ style={[
+ stylesButton.smallButton,
+ useHttpsLink && stylesButton.border,
+ ]}
+ >
+ HTTPS
+
+ setUseHttpsLink(false)}
+ backgroundColor={!useHttpsLink ? MainColor.yellow : "transparent"}
+ textColor={!useHttpsLink ? MainColor.black : MainColor.yellow}
+ style={[
+ stylesButton.smallButton,
+ !useHttpsLink && stylesButton.border,
+ ]}
+ >
+ Custom Scheme
+
+
+
+
+ {useHttpsLink
+ ? "✅ Testing Universal Links/App Links (butuh .well-known config)"
+ : "🔧 Testing langsung (tanpa domain verification)"}
+
);
}
+
+const stylesButton = StyleSheet.create({
+ smallButton: {
+ paddingHorizontal: 12,
+ paddingVertical: 6,
+ minWidth: 140,
+ },
+ border: {
+ borderWidth: 1,
+ borderColor: MainColor.yellow,
+ },
+});
diff --git a/screens/Admin/Event/ScreenEventDetail.tsx b/screens/Admin/Event/ScreenEventDetail.tsx
index 195676d..6abb9f5 100644
--- a/screens/Admin/Event/ScreenEventDetail.tsx
+++ b/screens/Admin/Event/ScreenEventDetail.tsx
@@ -4,13 +4,12 @@ import { IconDot } from "@/components/_Icon/IconComponent";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
-import ReportBox from "@/components/Box/ReportBox";
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
+import ReportBox from "@/components/Box/ReportBox";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { useAuth } from "@/hooks/use-auth";
import { funUpdateStatusEvent } from "@/screens/Admin/Event/funUpdateStatus";
import { apiAdminEventById } from "@/service/api-admin/api-admin-event";
-import { DEEP_LINK_URL } from "@/service/api-config";
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useMemo, useState } from "react";
import Toast from "react-native-toast-message";
@@ -25,10 +24,6 @@ export function Admin_ScreenEventDetail() {
const [data, setData] = useState(null);
const [loadData, setLoadData] = useState(false);
- const deepLinkURL = `${DEEP_LINK_URL}/event/${id}/confirmation?userId=${user?.id}`;
- const deepLinkURLDEV = `${DEEP_LINK_URL}/--/event/${id}/confirmation?userId=${user?.id}`;
- const isDevLink =
- process.env.NODE_ENV === "development" ? deepLinkURLDEV : deepLinkURL;
useFocusEffect(
useCallback(() => {
@@ -149,7 +144,7 @@ export function Admin_ScreenEventDetail() {
)}
{(status === "publish" || status === "history") && (
-
+
)}