diff --git a/frontend/android/app/capacitor.build.gradle b/frontend/android/app/capacitor.build.gradle index bf15962..c164c2d 100644 --- a/frontend/android/app/capacitor.build.gradle +++ b/frontend/android/app/capacitor.build.gradle @@ -11,6 +11,7 @@ apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { implementation project(':capacitor-camera') implementation project(':capacitor-geolocation') + implementation project(':capacitor-local-notifications') implementation project(':codetrix-studio-capacitor-google-auth') } diff --git a/frontend/android/app/src/main/AndroidManifest.xml b/frontend/android/app/src/main/AndroidManifest.xml index 30e0b1c..e7aa2dd 100644 --- a/frontend/android/app/src/main/AndroidManifest.xml +++ b/frontend/android/app/src/main/AndroidManifest.xml @@ -40,6 +40,7 @@ + diff --git a/frontend/android/app/src/main/res/drawable-land-hdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-hdpi/splash.png index e31573b..47dcf33 100644 Binary files a/frontend/android/app/src/main/res/drawable-land-hdpi/splash.png and b/frontend/android/app/src/main/res/drawable-land-hdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-ldpi/splash.png b/frontend/android/app/src/main/res/drawable-land-ldpi/splash.png new file mode 100644 index 0000000..da7d4cf Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-ldpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-mdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-mdpi/splash.png index f7a6492..af83328 100644 Binary files a/frontend/android/app/src/main/res/drawable-land-mdpi/splash.png and b/frontend/android/app/src/main/res/drawable-land-mdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-hdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-hdpi/splash.png new file mode 100644 index 0000000..fbfeb02 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-hdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-ldpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-ldpi/splash.png new file mode 100644 index 0000000..75ee966 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-ldpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-mdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-mdpi/splash.png new file mode 100644 index 0000000..3da0d24 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-mdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-xhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-xhdpi/splash.png new file mode 100644 index 0000000..b60c888 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-xhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png new file mode 100644 index 0000000..615ebd5 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-xxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png new file mode 100644 index 0000000..75104a9 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-xhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-xhdpi/splash.png index 8077255..35a7438 100644 Binary files a/frontend/android/app/src/main/res/drawable-land-xhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-land-xhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-xxhdpi/splash.png index 14c6c8f..5f66dcf 100644 Binary files a/frontend/android/app/src/main/res/drawable-land-xxhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-land-xxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-land-xxxhdpi/splash.png index 244ca25..af9ec88 100644 Binary files a/frontend/android/app/src/main/res/drawable-land-xxxhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-land-xxxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-night/splash.png b/frontend/android/app/src/main/res/drawable-night/splash.png new file mode 100644 index 0000000..75ee966 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-night/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-hdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-hdpi/splash.png index 74faaa5..9e55aa3 100644 Binary files a/frontend/android/app/src/main/res/drawable-port-hdpi/splash.png and b/frontend/android/app/src/main/res/drawable-port-hdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-ldpi/splash.png b/frontend/android/app/src/main/res/drawable-port-ldpi/splash.png new file mode 100644 index 0000000..1ab6e44 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-ldpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-mdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-mdpi/splash.png index e944f4a..03ee3e6 100644 Binary files a/frontend/android/app/src/main/res/drawable-port-mdpi/splash.png and b/frontend/android/app/src/main/res/drawable-port-mdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-hdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-hdpi/splash.png new file mode 100644 index 0000000..1539555 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-hdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-ldpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-ldpi/splash.png new file mode 100644 index 0000000..8d8f92f Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-ldpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-mdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-mdpi/splash.png new file mode 100644 index 0000000..a45d4a6 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-mdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-xhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-xhdpi/splash.png new file mode 100644 index 0000000..deef156 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-xhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png new file mode 100644 index 0000000..e16c049 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-xxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png new file mode 100644 index 0000000..df39518 Binary files /dev/null and b/frontend/android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-xhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-xhdpi/splash.png index 564a82f..d50de64 100644 Binary files a/frontend/android/app/src/main/res/drawable-port-xhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-port-xhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-xxhdpi/splash.png index bfabe68..cc03e12 100644 Binary files a/frontend/android/app/src/main/res/drawable-port-xxhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-port-xxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/frontend/android/app/src/main/res/drawable-port-xxxhdpi/splash.png index 6929071..3aa3b4a 100644 Binary files a/frontend/android/app/src/main/res/drawable-port-xxxhdpi/splash.png and b/frontend/android/app/src/main/res/drawable-port-xxxhdpi/splash.png differ diff --git a/frontend/android/app/src/main/res/drawable/splash.png b/frontend/android/app/src/main/res/drawable/splash.png index f7a6492..03ee3e6 100644 Binary files a/frontend/android/app/src/main/res/drawable/splash.png and b/frontend/android/app/src/main/res/drawable/splash.png differ diff --git a/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 036d09b..0aa82aa 100644 --- a/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,9 @@ - - + + + + + + \ No newline at end of file diff --git a/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09b..0aa82aa 100644 --- a/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/frontend/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,9 @@ - - + + + + + + \ No newline at end of file diff --git a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 7c2f911..d94f58c 100644 Binary files a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png new file mode 100644 index 0000000..c092285 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png index 2127973..ddd6b80 100644 Binary files a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 95d49ab..e5f9b40 100644 Binary files a/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher.png index e69a243..2243405 100644 Binary files a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png new file mode 100644 index 0000000..adc7b13 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png new file mode 100644 index 0000000..a696372 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png index b9a5218..d6bcc04 100644 Binary files a/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png differ diff --git a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 806d360..c945d92 100644 Binary files a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png new file mode 100644 index 0000000..8c57e54 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png index 8ed0605..8bee5be 100644 Binary files a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 2e689e6..68d689c 100644 Binary files a/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 627a4f4..078397d 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png new file mode 100644 index 0000000..704f168 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png index df0f158..9699fa9 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index f74d638..defcb62 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index db4e5a9..ba55bbf 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png new file mode 100644 index 0000000..af19909 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png index 2960cbb..d06e8f2 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 5ead8cd..b44e6d7 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index f460043..d7e926b 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png new file mode 100644 index 0000000..27a3773 Binary files /dev/null and b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png index d2ea9ab..8245228 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 08c7e98..b584611 100644 Binary files a/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/frontend/android/capacitor.settings.gradle b/frontend/android/capacitor.settings.gradle index 5c71550..5c823c6 100644 --- a/frontend/android/capacitor.settings.gradle +++ b/frontend/android/capacitor.settings.gradle @@ -8,5 +8,8 @@ project(':capacitor-camera').projectDir = new File('../../node_modules/@capacito include ':capacitor-geolocation' project(':capacitor-geolocation').projectDir = new File('../../node_modules/@capacitor/geolocation/android') +include ':capacitor-local-notifications' +project(':capacitor-local-notifications').projectDir = new File('../../node_modules/@capacitor/local-notifications/android') + include ':codetrix-studio-capacitor-google-auth' project(':codetrix-studio-capacitor-google-auth').projectDir = new File('../../node_modules/@codetrix-studio/capacitor-google-auth/android') diff --git a/frontend/assets/icon-background.png b/frontend/assets/icon-background.png new file mode 100644 index 0000000..f1465a6 Binary files /dev/null and b/frontend/assets/icon-background.png differ diff --git a/frontend/assets/icon-only.png b/frontend/assets/icon-only.png index d92c524..59bb216 100644 Binary files a/frontend/assets/icon-only.png and b/frontend/assets/icon-only.png differ diff --git a/frontend/assets/icon.png b/frontend/assets/icon.png new file mode 100644 index 0000000..cce0e9b Binary files /dev/null and b/frontend/assets/icon.png differ diff --git a/frontend/assets/splash-dark.png b/frontend/assets/splash-dark.png new file mode 100644 index 0000000..34bce9e Binary files /dev/null and b/frontend/assets/splash-dark.png differ diff --git a/frontend/assets/splash.png b/frontend/assets/splash.png new file mode 100644 index 0000000..5fd6834 Binary files /dev/null and b/frontend/assets/splash.png differ diff --git a/frontend/dist/index.html b/frontend/dist/index.html index b8504e5..624c270 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -21,8 +21,16 @@ - - + + + + + + + + + + diff --git a/frontend/package.json b/frontend/package.json index 6f7eb83..8e62372 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "@capacitor/cli": "^7.6.7", "@capacitor/core": "^8.4.1", "@capacitor/geolocation": "^8.2.0", + "@capacitor/local-notifications": "^8.2.0", "@codetrix-studio/capacitor-google-auth": "^3.4.0-rc.4", "date-fns": "^4.4.0", "jspdf": "^4.2.1", diff --git a/frontend/src/components/TourChat.tsx b/frontend/src/components/TourChat.tsx index 892888c..1c601d9 100644 --- a/frontend/src/components/TourChat.tsx +++ b/frontend/src/components/TourChat.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { io, Socket } from 'socket.io-client'; import { Capacitor } from '@capacitor/core'; +import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; import { Send, MessageSquare, Loader2, Image as ImageIcon, MapPin, Download, X } from 'lucide-react'; import { useNotification } from '@/hooks/useNotification'; @@ -255,6 +256,41 @@ export const TourChat: React.FC = ({ tourId, embedded = false }) }); }; + // Handle Native Image Selection (Camera or Library) + const handleNativePhotoSelect = async () => { + try { + const image = await Camera.getPhoto({ + quality: 90, + allowEditing: false, + resultType: CameraResultType.Uri, + source: CameraSource.Prompt, // Prompt selection + saveToGallery: true, // Auto-save original photo to device gallery + promptLabelHeader: 'Chọn hình ảnh', + promptLabelPhoto: 'Chọn từ thư viện', + promptLabelPicture: 'Chụp ảnh mới (Camera)' + }); + + if (image && image.webPath) { + setImagePreview(image.webPath); + + // Convert Capacitor webPath resource back to standard File instance + const response = await fetch(image.webPath); + const blob = await response.blob(); + const file = new File([blob], `photo.${image.format}`, { type: `image/${image.format}` }); + setSelectedImage(file); + } + } catch (error: any) { + console.error('Lỗi chọn ảnh native:', error); + if (error?.message !== 'User cancelled photos app' && error?.message !== 'User cancelled camera') { + notify({ + title: 'Lỗi', + message: 'Không thể truy cập máy ảnh hoặc thư viện ảnh.', + type: 'error' + }); + } + } + }; + // Handle Image Selection const handleImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; @@ -609,7 +645,7 @@ export const TourChat: React.FC = ({ tourId, embedded = false }) {/* Attach photo button */} fileInputRef.current?.click()} + onClick={Capacitor.isNativePlatform() ? handleNativePhotoSelect : () => fileInputRef.current?.click()} className="p-2.5 bg-white border border-gray-200 hover:bg-gray-50 text-gray-500 rounded-xl transition-all shadow-sm active:scale-95 flex items-center justify-center shrink-0" title="Đính kèm hình ảnh" > diff --git a/frontend/src/hooks/useNotification.tsx b/frontend/src/hooks/useNotification.tsx index 46a7a09..a924610 100644 --- a/frontend/src/hooks/useNotification.tsx +++ b/frontend/src/hooks/useNotification.tsx @@ -1,5 +1,7 @@ import React, { createContext, useContext, useState, useCallback, useEffect } from 'react'; import { NotificationModal } from '../components/NotificationModal'; +import { Capacitor } from '@capacitor/core'; +import { LocalNotifications } from '@capacitor/local-notifications'; interface NotificationOptions { title: string; @@ -24,6 +26,24 @@ export const NotificationProvider: React.FC<{ children: React.ReactNode }> = ({ message, type, }); + + if (Capacitor.isNativePlatform()) { + LocalNotifications.schedule({ + notifications: [ + { + title: title || 'YoTrip', + body: message, + id: Math.floor(Math.random() * 1000000), + schedule: { at: new Date(Date.now() + 100) }, + sound: 'default', + actionTypeId: 'OPEN_APP', + extra: null + } + ] + }).catch(err => { + console.error('[LocalNotifications] Error scheduling native notification:', err); + }); + } }, []); const handleClose = useCallback(() => { diff --git a/frontend/src/pages/TourDetailPage.tsx b/frontend/src/pages/TourDetailPage.tsx index 045d313..581cb5e 100644 --- a/frontend/src/pages/TourDetailPage.tsx +++ b/frontend/src/pages/TourDetailPage.tsx @@ -1906,7 +1906,7 @@ export const TourDetailPage = ({ {/* Top Navigation Bar */} - + setActiveTab('plan') : onBack} className="p-2 hover:bg-[var(--background)] rounded-full transition-colors"> @@ -2206,7 +2206,7 @@ export const TourDetailPage = ({ {/* Main Content Area - Điều chỉnh max-width khi ở chế độ bản đồ */} {/* Tab Switcher */} - {!(activeTab === 'plan' && viewMode === 'map') && ( + {!(activeTab === 'plan' && viewMode === 'map') && activeTab !== 'chat' && ( {tabs.map((tab) => ( { + console.log('[LocalNotifications] Permissions requested:', result); + }); + } catch (e) { + console.error('[LocalNotifications] Failed to request permissions:', e); + } + const backendUrl = import.meta.env.VITE_BACKEND_URL || 'https://yotrip.labz.io.vn'; const originalFetch = window.fetch; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 320ea9b..9a798e5 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -23,6 +23,33 @@ export default defineConfig(({ mode }) => { '@': path.resolve(__dirname, './src'), }, }, + build: { + chunkSizeWarningLimit: 1500, + rollupOptions: { + output: { + manualChunks(id) { + if (id.includes('node_modules')) { + if (id.includes('react') || id.includes('scheduler')) { + return 'vendor-react'; + } + if (id.includes('leaflet')) { + return 'vendor-maps'; + } + if (id.includes('jspdf')) { + return 'vendor-pdf'; + } + if (id.includes('lucide-react')) { + return 'vendor-icons'; + } + if (id.includes('quill')) { + return 'vendor-editor'; + } + return 'vendor-others'; + } + } + } + } + }, server: { port: 3002, host: true, diff --git a/package-lock.json b/package-lock.json index 40321a7..a907088 100644 --- a/package-lock.json +++ b/package-lock.json @@ -205,6 +205,7 @@ "@capacitor/cli": "^7.6.7", "@capacitor/core": "^8.4.1", "@capacitor/geolocation": "^8.2.0", + "@capacitor/local-notifications": "^8.2.0", "@codetrix-studio/capacitor-google-auth": "^3.4.0-rc.4", "date-fns": "^4.4.0", "jspdf": "^4.2.1", @@ -1013,6 +1014,15 @@ "@capacitor/core": ">=8.0.0" } }, + "node_modules/@capacitor/local-notifications": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@capacitor/local-notifications/-/local-notifications-8.2.0.tgz", + "integrity": "sha512-fvLY0w2w4MiX+DD4+Wv4DOwOLdzKZsMDwAcRv/Juudd+QbKbn69s6cM3xVqPwAiDqfnqsY4/S8xtQD6M73wY2A==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, "node_modules/@capacitor/synapse": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@capacitor/synapse/-/synapse-1.0.4.tgz",