From bbacd40ae94931dc4430b0d11ab57eed0c799ad4 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 4 Feb 2026 11:37:57 +0800 Subject: [PATCH 1/3] upd: view file Deskripsi: - view file pada pengumuman, diskusi divisi dan diskusi umum No Issues --- app/(application)/announcement/[id].tsx | 9 +- app/(application)/discussion/[id].tsx | 2 - components/borderBottomItem2.tsx | 253 ++++++++++++++++-------- 3 files changed, 174 insertions(+), 90 deletions(-) diff --git a/app/(application)/announcement/[id].tsx b/app/(application)/announcement/[id].tsx index 404fa14..c489744 100644 --- a/app/(application)/announcement/[id].tsx +++ b/app/(application)/announcement/[id].tsx @@ -14,7 +14,7 @@ import { startActivityAsync } from 'expo-intent-launcher'; import { router, Stack, useLocalSearchParams } from "expo-router"; import * as Sharing from 'expo-sharing'; import React, { useEffect, useState } from "react"; -import { Alert, Dimensions, Platform, Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; +import { Dimensions, Platform, Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; import ImageViewing from 'react-native-image-viewing'; import * as mime from 'react-native-mime-types'; import RenderHTML from 'react-native-render-html'; @@ -68,6 +68,7 @@ export default function DetailAnnouncement() { * Opens the image preview modal for the selected image file * @param item The file data object containing image information */ + function handleChooseFile(item: FileData) { setChooseFile(item) setPreview(true) @@ -156,11 +157,13 @@ export default function DetailAnnouncement() { } } catch (openError) { console.error('Error opening file:', openError); - Alert.alert('INFO', 'Tidak ada aplikasi yang dapat membuka file ini'); + Toast.show({ + type: 'error', + text1: 'Tidak ada aplikasi yang dapat membuka file ini' + }); } } catch (error) { console.error('Error downloading or opening file:', error); - Alert.alert('INFO', 'Gagal mengunduh atau membuka file'); Toast.show({ type: 'error', text1: 'Gagal membuka file', diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx index 8100d9e..a20d86f 100644 --- a/app/(application)/discussion/[id].tsx +++ b/app/(application)/discussion/[id].tsx @@ -80,8 +80,6 @@ export default function DetailDiscussionGeneral() { }) const [viewEdit, setViewEdit] = useState(false) - - useEffect(() => { const onValueChange = reference.on('value', snapshot => { if (snapshot.val() == null) { diff --git a/components/borderBottomItem2.tsx b/components/borderBottomItem2.tsx index fbfc243..441d2bf 100644 --- a/components/borderBottomItem2.tsx +++ b/components/borderBottomItem2.tsx @@ -1,14 +1,17 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import { ConstEnv } from "@/constants/ConstEnv"; +import { isImageFile } from "@/constants/FileExtensions"; import Styles from "@/constants/Styles"; -import { Ionicons } from "@expo/vector-icons"; +import { MaterialCommunityIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; import * as Sharing from 'expo-sharing'; import React, { useState } from "react"; -import { Alert, Dimensions, Platform, Pressable, View } from "react-native"; +import { Dimensions, Platform, Pressable, View } from "react-native"; import { ScrollView } from "react-native-gesture-handler"; +import ImageViewing from "react-native-image-viewing"; import * as mime from 'react-native-mime-types'; +import Toast from "react-native-toast-message"; import Text from "./Text"; @@ -33,26 +36,47 @@ type Props = { dataFile: { id: string; idStorage: string; name: string; extension: string }[] } +type PropsFile = { + id: string; + idStorage: string; + name: string; + extension: string +} + + export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, width, descEllipsize, textColor, colorPress, titleShowAll, dataFile }: Props) { const lebarDim = Dimensions.get("window").width; const lebar = width ? lebarDim * width / 100 : 'auto'; const textColorFix = textColor ? textColor : 'black'; const [isTap, setIsTap] = useState(false); const [loadingOpen, setLoadingOpen] = useState(false) + const [chooseFile, setChooseFile] = useState() + const [preview, setPreview] = useState(false) + function handleChooseFile(item: PropsFile) { + setChooseFile(item) + setPreview(true) + } - const openFile = (item: { idStorage: string; name: string; extension: string }) => { - if (Platform.OS == 'android') setLoadingOpen(true) - let remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage; - const fileName = item.name + '.' + item.extension; - let localPath = `${FileSystem.documentDirectory}/${fileName}`; - const mimeType = mime.lookup(fileName) + const openFile = async (item: PropsFile) => { + try { + setLoadingOpen(true); + const remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage; + const fileName = item.name + '.' + item.extension; + const localPath = `${FileSystem.documentDirectory}/${fileName}`; + const mimeType = mime.lookup(fileName); + + // Download the file + const downloadResult = await FileSystem.downloadAsync(remoteUrl, localPath); + + if (downloadResult.status !== 200) { + throw new Error(`Download failed with status ${downloadResult.status}`); + } + + const contentURL = await FileSystem.getContentUriAsync(downloadResult.uri); - FileSystem.downloadAsync(remoteUrl, localPath).then(async ({ uri }) => { - const contentURL = await FileSystem.getContentUriAsync(uri); - setLoadingOpen(false) try { - if (Platform.OS == 'android') { + if (Platform.OS === 'android') { await startActivityAsync( 'android.intent.action.VIEW', { @@ -61,89 +85,148 @@ export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress type: mimeType as string, } ); - } else if (Platform.OS == 'ios') { - Sharing.shareAsync(localPath); + } else if (Platform.OS === 'ios') { + await Sharing.shareAsync(localPath); } - } catch (error) { - Alert.alert('INFO', 'Gagal membuka file, tidak ada aplikasi yang dapat membuka file ini'); - } finally { - if (Platform.OS == 'android') setLoadingOpen(false) + } catch (openError) { + console.error('Error opening file:', openError); + Toast.show({ + type: 'error', + text1: 'Tidak ada aplikasi yang dapat membuka file ini' + }); } - }); + } catch (error) { + console.error('Error downloading or opening file:', error); + Toast.show({ + type: 'error', + text1: 'Gagal membuka file', + text2: 'Silakan coba lagi nanti' + }); + } finally { + setLoadingOpen(false); + } }; return ( - setIsTap(true)} - onPressOut={() => setIsTap(false)} - style={({ pressed }) => [ - borderType == 'bottom' - ? Styles.wrapItemBorderBottom - : borderType == 'all' - ? Styles.wrapItemBorderAll - : Styles.wrapItemBorderNone, - bgColor && bgColor == 'white' && ColorsStatus.white, - // efek warna saat ditekan (sementara) - isTap && colorPress && ColorsStatus.pressedGray, - ]} - > - - {icon} - - - {title} + <> + setIsTap(true)} + onPressOut={() => setIsTap(false)} + style={({ pressed }) => [ + borderType == 'bottom' + ? Styles.wrapItemBorderBottom + : borderType == 'all' + ? Styles.wrapItemBorderAll + : Styles.wrapItemBorderNone, + bgColor && bgColor == 'white' && ColorsStatus.white, + // efek warna saat ditekan (sementara) + isTap && colorPress && ColorsStatus.pressedGray, + ]} + > + + {icon} + + + {title} + { + subtitle && + typeof subtitle == "string" + ? {subtitle} + : + {subtitle} + + } + { - subtitle && - typeof subtitle == "string" - ? {subtitle} - : - {subtitle} - + rightTopInfo && {rightTopInfo} } - { - rightTopInfo && {rightTopInfo} - } - - - {desc && {desc}} - { - dataFile.length > 0 && ( - - {dataFile.map((item, index) => ( - { openFile({ idStorage: item.idStorage, name: item.name, extension: item.extension }) }} - > - - {item.name}.{item.extension} - - ))} - - ) - } - { - (leftBottomInfo || rightBottomInfo) && - ( - - { - typeof leftBottomInfo == 'string' ? - {leftBottomInfo} - : - leftBottomInfo - } - { - typeof rightBottomInfo == 'string' ? - {rightBottomInfo} - : - rightBottomInfo - } + + {desc && {desc}} + { + dataFile.length > 0 && ( + + {dataFile.map((item, index) => ( + { + isImageFile(item.extension) ? + handleChooseFile(item) + : openFile(item) + }} + > + + {item.name}.{item.extension} + + ))} + + ) + } + { + (leftBottomInfo || rightBottomInfo) && + ( + + { + typeof leftBottomInfo == 'string' ? + {leftBottomInfo} + : + leftBottomInfo + } + { + typeof rightBottomInfo == 'string' ? + {rightBottomInfo} + : + rightBottomInfo + } + + ) + } + + + setPreview(false)} + doubleTapToZoomEnabled + HeaderComponent={({ imageIndex }) => ( + + {/* CLOSE */} + setPreview(false)} + accessibilityRole="button" + accessibilityLabel="Close image viewer" + > + + + + {/* MENU */} + chooseFile && openFile(chooseFile)} + accessibilityRole="button" + accessibilityLabel="Download or share image" + disabled={loadingOpen} + > + + - ) - } - + )} + FooterComponent={({ imageIndex }) => ( + + {chooseFile?.name}.{chooseFile?.extension} + + )} + /> + ) } \ No newline at end of file From c421d267b93f7473d7e65e29f4189b23f7c9fbee Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 4 Feb 2026 11:41:18 +0800 Subject: [PATCH 2/3] upd: warna select pada filter --- constants/Styles.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/constants/Styles.ts b/constants/Styles.ts index c7abe89..688c9eb 100644 --- a/constants/Styles.ts +++ b/constants/Styles.ts @@ -662,21 +662,21 @@ const Styles = StyleSheet.create({ marginBottom: 10, }, chipSelected: { - backgroundColor: "#FFF5F2", - borderColor: "#FF5A3C", + backgroundColor: "#f2f6ffff", + borderColor: "#384288", }, chipText: { fontSize: 16, color: "#222", }, chipTextSelected: { - color: "#FF5A3C", + color: "#384288", }, checkIcon: { position: "absolute", top: -6, left: -6, - backgroundColor: "#FF5A3C", + backgroundColor: "#384288", borderRadius: 10, padding: 2, }, From ebe8380829f2be2e1b648e275da90c876f29610a Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 4 Feb 2026 13:58:15 +0800 Subject: [PATCH 3/3] upd: panduan penggunaan by QWEN AI --- Panduan-Penggunaan-Aplikasi.md | 334 +++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 Panduan-Penggunaan-Aplikasi.md diff --git a/Panduan-Penggunaan-Aplikasi.md b/Panduan-Penggunaan-Aplikasi.md new file mode 100644 index 0000000..af0c469 --- /dev/null +++ b/Panduan-Penggunaan-Aplikasi.md @@ -0,0 +1,334 @@ +# Panduan Penggunaan Aplikasi Desa+ + +## Daftar Isi +1. [Gambaran Umum Aplikasi](#gambaran-umum-aplikasi) +2. [Fitur-fitur Utama](#fitur-fitur-utama) +3. [User Roles dan Hak Akses](#user-roles-dan-hak-akses) +4. [Petunjuk Penggunaan](#petunjuk-penggunaan) +5. [Troubleshooting](#troubleshooting) + +## Gambaran Umum Aplikasi + +Aplikasi Desa+ adalah platform digital berbasis mobile yang dirancang untuk membantu pengelolaan dan komunikasi di lingkungan desa/kelurahan. Aplikasi ini menyediakan berbagai fitur untuk memudahkan administrasi desa, komunikasi antar warga, dan pengelolaan informasi penting. + +### Teknologi yang Digunakan +- React Native dengan Expo +- Firebase (Authentication, Realtime Database, Cloud Messaging) +- Redux Toolkit untuk manajemen state +- TypeScript untuk type safety + +## Fitur-fitur Utama + +### 1. Otentikasi (Login & Verifikasi) +**Deskripsi:** Sistem login menggunakan nomor telepon dan verifikasi OTP (One Time Password) +- **Fungsi:** Memverifikasi identitas pengguna sebelum mengakses aplikasi +- **Siapa yang bisa mengakses:** Semua pengguna yang terdaftar +- **Cara menggunakan:** + 1. Masukkan nomor telepon yang terdaftar + 2. Klik "Kirim OTP" + 3. Masukkan kode OTP yang diterima melalui WhatsApp + 4. Klik "Verifikasi" untuk masuk ke aplikasi + +### 2. Dashboard/Home Screen +**Deskripsi:** Tampilan utama aplikasi yang menampilkan informasi dan akses cepat ke berbagai fitur +- **Fungsi:** Menyediakan ringkasan informasi desa dan akses cepat ke fitur-fitur utama +- **Siapa yang bisa mengakses:** Semua pengguna yang telah login +- **Komponen:** + - Carousel banner untuk promosi atau informasi penting + - Grafik progres kegiatan + - Grafik dokumen + - Daftar kegiatan terbaru + - Daftar divisi aktif + - Daftar acara mendatang + - Diskusi terbaru + +### 3. Pengumuman +**Deskripsi:** Fitur untuk membuat, melihat, dan mengelola pengumuman desa +- **Fungsi:** Menyebarkan informasi penting kepada seluruh warga +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna +- **Cara menggunakan:** + 1. Pilih menu "Pengumuman" dari fitur utama + 2. Untuk membuat pengumuman baru, klik tombol "+" di kanan atas + 3. Isi judul dan deskripsi pengumuman + 4. Pilih grup yang akan menerima pengumuman (opsional) + 5. Klik "Simpan" untuk menerbitkan + +### 4. Diskusi Umum +**Deskripsi:** Forum diskusi untuk komunikasi antar warga dan pihak pengelola +- **Fungsi:** Tempat berdiskusi mengenai berbagai topik yang berkaitan dengan desa +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna + - Berkomentar: Semua pengguna +- **Cara menggunakan:** + 1. Pilih menu "Diskusi" dari fitur utama + 2. Untuk membuat diskusi baru, klik tombol "+" di kanan atas + 3. Isi judul dan deskripsi diskusi + 4. Pilih anggota yang akan menjadi partisipan + 5. Klik "Simpan" untuk membuat diskusi + 6. Klik pada judul diskusi untuk membuka dan memberikan komentar + +### 5. Kegiatan/Proyek +**Deskripsi:** Fitur untuk mengelola dan melacak proyek atau kegiatan desa +- **Fungsi:** Mengelola dan memonitor kemajuan proyek-proyek desa +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna + - Status (Buka/Tutup): Berdasarkan hak akses +- **Status Kegiatan:** + - Segera: Proyek yang akan segera dimulai + - Dikerjakan: Proyek yang sedang dalam proses pengerjaan + - Selesai: Proyek yang telah selesai + - Batal: Proyek yang dibatalkan +- **Cara menggunakan:** + 1. Pilih menu "Kegiatan" dari fitur utama + 2. Untuk membuat kegiatan baru, klik tombol "+" di kanan atas + 3. Isi nama kegiatan dan deskripsi + 4. Pilih tahun pelaksanaan + 5. Tambahkan anggota yang terlibat + 6. Klik "Simpan" untuk membuat kegiatan + +### 6. Divisi +**Deskripsi:** Fitur untuk mengelola struktur organisasi desa berdasarkan divisi +- **Fungsi:** Mengorganisir warga dan tugas-tugas berdasarkan divisi-divisi tertentu +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna + - Anggota: Berdasarkan divisi yang diikuti +- **Cara menggunakan:** + 1. Pilih menu "Divisi" dari fitur utama + 2. Untuk membuat divisi baru, klik tombol "+" di kanan atas + 3. Isi nama dan deskripsi divisi + 4. Pilih grup induk (jika ada) + 5. Tambahkan anggota dan admin divisi + 6. Klik "Simpan" untuk membuat divisi + 7. Klik pada nama divisi untuk melihat detail dan fitur dalam divisi tersebut + +### 7. Anggota +**Deskripsi:** Fitur untuk mengelola data warga atau anggota desa +- **Fungsi:** Menyimpan dan mengelola informasi tentang warga desa +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna +- **Cara menggunakan:** + 1. Pilih menu "Anggota" dari fitur utama + 2. Gunakan fitur pencarian untuk menemukan anggota tertentu + 3. Gunakan filter untuk menampilkan anggota aktif/tidak aktif + 4. Klik pada nama anggota untuk melihat detail profil + 5. Untuk menambah anggota baru, klik tombol "+" di kanan atas + +### 8. Jabatan +**Deskripsi:** Fitur untuk mengelola posisi atau jabatan dalam organisasi desa +- **Fungsi:** Mendefinisikan struktur jabatan dalam lembaga desa +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Admin, Deputy Super Admin + - Melihat: Semua pengguna +- **Cara menggunakan:** + 1. Pilih menu "Jabatan" dari fitur utama + 2. Gunakan fitur pencarian untuk menemukan jabatan tertentu + 3. Gunakan filter untuk menampilkan jabatan aktif/tidak aktif + 4. Untuk menambah jabatan baru, klik tombol "+" di kanan atas + +### 9. Lembaga Desa +**Deskripsi:** Fitur untuk mengelola berbagai lembaga dalam desa +- **Fungsi:** Mengorganisir struktur organisasi desa berdasarkan lembaga +- **Siapa yang bisa mengakses:** + - Pembuatan/Edit/Hapus: Super Admin, Developer + - Melihat: Semua pengguna +- **Cara menggunakan:** + 1. Pilih menu "Lembaga Desa" dari fitur utama + 2. Gunakan fitur pencarian untuk menemukan lembaga tertentu + 3. Gunakan filter untuk menampilkan lembaga aktif/tidak aktif + 4. Untuk menambah lembaga baru, klik tombol "+" di kanan atas + +### 10. Diskusi Divisi +**Deskripsi:** Forum diskusi khusus untuk masing-masing divisi +- **Fungsi:** Tempat berdiskusi secara internal dalam divisi +- **Siapa yang bisa mengakses:** Hanya anggota divisi yang bersangkutan +- **Cara menggunakan:** + 1. Pilih sebuah divisi dari menu "Divisi" + 2. Pilih submenu "Diskusi Divisi" + 3. Klik tombol "+" untuk membuat diskusi baru + 4. Isi judul dan deskripsi diskusi + 5. Klik "Simpan" untuk membuat diskusi + +### 11. Tugas Divisi +**Deskripsi:** Fitur untuk mengelola tugas-tugas dalam masing-masing divisi +- **Fungsi:** Menetapkan dan melacak tugas-tugas yang harus diselesaikan oleh anggota divisi +- **Siapa yang bisa mengakses:** Hanya anggota divisi yang bersangkutan +- **Cara menggunakan:** + 1. Pilih sebuah divisi dari menu "Divisi" + 2. Pilih submenu "Tugas Divisi" + 3. Klik tombol "+" untuk membuat tugas baru + 4. Isi nama tugas dan detail lainnya + 5. Tambahkan anggota yang bertugas + 6. Klik "Simpan" untuk membuat tugas + +### 12. Dokumen +**Deskripsi:** Sistem manajemen dokumen untuk menyimpan dan mengelola file-file desa +- **Fungsi:** Menyimpan dokumen penting dalam struktur folder +- **Siapa yang bisa mengakses:** Akses berdasarkan divisi dan hak akses +- **Cara menggunakan:** + 1. Pilih sebuah divisi dari menu "Divisi" + 2. Pilih submenu "Dokumen" + 3. Buat folder baru atau upload file + 4. Gunakan fitur share untuk membagikan dokumen ke divisi lain + +### 13. Kalender/Acara +**Deskripsi:** Fitur untuk menjadwalkan dan mengelola acara-acara desa +- **Fungsi:** Menjadwalkan kegiatan dan acara penting desa +- **Siapa yang bisa mengakses:** Hanya anggota divisi yang bersangkutan +- **Cara menggunakan:** + 1. Pilih sebuah divisi dari menu "Divisi" + 2. Pilih submenu "Kalender" + 3. Klik tombol "+" untuk membuat acara baru + 4. Isi detail acara (judul, deskripsi, tanggal, waktu) + 5. Tambahkan anggota yang ikut serta + 6. Klik "Simpan" untuk membuat acara + +### 14. Notifikasi +**Deskripsi:** Sistem notifikasi untuk memberitahu pengguna tentang aktivitas penting +- **Fungsi:** Memberitahu pengguna tentang pengumuman, komentar, atau aktivitas lainnya +- **Siapa yang bisa mengakses:** Semua pengguna +- **Cara menggunakan:** + 1. Klik ikon notifikasi di bagian atas layar + 2. Lihat daftar notifikasi yang belum dibaca + 3. Klik pada notifikasi untuk membuka konten terkait + +### 15. Profil +**Deskripsi:** Fitur untuk melihat dan mengedit informasi pribadi pengguna +- **Fungsi:** Menampilkan dan mengelola informasi akun pengguna +- **Siapa yang bisa mengakses:** Pengguna yang bersangkutan +- **Cara menggunakan:** + 1. Klik menu "Profil" dari navigasi bawah + 2. Lihat informasi pribadi + 3. Klik "Edit" untuk mengubah informasi (tidak tersedia untuk developer) + +### 16. Banner +**Deskripsi:** Fitur untuk mengelola banner promosi atau informasi penting di halaman utama +- **Fungsi:** Menampilkan informasi atau promosi penting di tampilan awal +- **Siapa yang bisa mengakses:** Super Admin, Deputy Super Admin, Developer +- **Cara menggunakan:** + 1. Pilih menu "Banner" dari fitur utama (jika tersedia) + 2. Klik tombol "+" untuk membuat banner baru + 3. Upload gambar banner dan isi deskripsi + 4. Klik "Simpan" untuk menerbitkan banner + +## User Roles dan Hak Akses + +Aplikasi Desa+ memiliki sistem hierarki peran pengguna sebagai berikut: + +### 1. Developer +- **Deskripsi:** Peran tertinggi dengan semua hak akses +- **Hak akses:** + - Semua fitur dan fungsi dalam aplikasi + - Manajemen semua data dan pengaturan sistem + +### 2. Super Admin (Supadmin) +- **Deskripsi:** Administrator utama desa +- **Hak akses:** + - Semua fitur kecuali beberapa fungsi sistem tingkat tinggi + - Manajemen Deputy Super Admin, Admin, Co-Admin, dan User + - Akses ke semua data dan fungsi administratif + +### 3. Deputy Super Admin (Cosupadmin) +- **Deskripsi:** Wakil administrator utama +- **Hak akses:** + - Manajemen Admin, Co-Admin, dan User + - Akses ke sebagian besar fitur administratif + - Dapat mengelola banner + +### 4. Admin +- **Deskripsi:** Administrator tingkat menengah +- **Hak akses:** + - Manajemen Co-Admin dan User + - Akses ke fitur-fitur administratif dasar + - Tidak dapat mengelola Deputy Super Admin dan Super Admin + +### 5. Deputy Admin (Coadmin) +- **Deskripsi:** Wakil administrator +- **Hak akses:** + - Manajemen User + - Akses terbatas ke fitur-fitur administratif + - Tidak dapat mengelola Admin ke atas + +### 6. User +- **Deskripsi:** Pengguna biasa +- **Hak akses:** + - Akses ke fitur-fitur umum + - Tidak dapat mengelola pengguna lain + - Tidak dapat mengakses fungsi administratif + +## Petunjuk Penggunaan + +### Login ke Aplikasi +1. Buka aplikasi Desa+ +2. Masukkan nomor telepon yang terdaftar +3. Klik "Kirim OTP" +4. Cek WhatsApp untuk menerima kode OTP +5. Masukkan kode OTP yang diterima +6. Klik "Verifikasi" untuk masuk ke aplikasi + +### Navigasi Utama +- **Home:** Tampilan utama dengan informasi dan akses cepat +- **Fitur:** Menu utama untuk mengakses semua fitur aplikasi +- **Pencarian:** Mencari konten di seluruh aplikasi +- **Notifikasi:** Melihat pemberitahuan penting +- **Profil:** Informasi akun dan pengaturan pribadi + +### Membuat Pengumuman Baru +1. Pilih menu "Fitur" dari navigasi bawah +2. Klik "Pengumuman" +3. Klik tombol "+" di kanan atas +4. Isi judul dan deskripsi pengumuman +5. Pilih grup sasaran (opsional) +6. Klik "Simpan" + +### Bergabung dalam Diskusi +1. Pilih menu "Fitur" dari navigasi bawah +2. Klik "Diskusi" +3. Pilih diskusi yang ingin diikuti +4. Ketik komentar di kotak bawah +5. Klik "Kirim" untuk mengirim komentar + +### Mengelola Divisi +1. Pilih menu "Fitur" dari navigasi bawah +2. Klik "Divisi" +3. Klik pada nama divisi untuk melihat detail +4. Di dalam detail divisi, Anda dapat mengakses: + - Tugas Divisi + - Dokumen Divisi + - Diskusi Divisi + - Kalender Divisi + +## Troubleshooting + +### Masalah Login +- Pastikan nomor telepon yang dimasukkan sudah benar dan terdaftar +- Pastikan koneksi internet stabil saat menerima OTP +- Jika tidak menerima OTP, coba kirim ulang setelah beberapa menit + +### Tidak Bisa Mengakses Fitur Tertentu +- Pastikan peran Anda memiliki hak akses ke fitur tersebut +- Beberapa fitur hanya tersedia untuk peran tertentu (misalnya Admin ke atas) + +### Notifikasi Tidak Muncul +- Pastikan izin notifikasi diaktifkan di pengaturan aplikasi +- Pastikan aplikasi tetap berjalan di latar belakang + +### Gambar Tidak Muncul +- Periksa koneksi internet +- Coba refresh halaman atau restart aplikasi + +### Lupa Password +- Aplikasi ini menggunakan sistem login OTP, jadi tidak ada password yang disimpan +- Cukup gunakan nomor telepon dan minta OTP kembali + +## Dukungan dan Bantuan + +Jika Anda mengalami masalah atau memiliki pertanyaan tentang penggunaan aplikasi, silakan hubungi administrator desa atau tim pengembang aplikasi. + +--- +*Dokumen ini terakhir diperbarui pada 4 Februari 2026* \ No newline at end of file