diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..e9e3e32 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,86 @@ +# Project Overview: Desa+ + +Desa+ is a mobile application built with React Native and Expo, designed to facilitate management and communication within villages/communities. It aims to streamline village administration, inter-community communication, and the management of essential information. + +## Key Features: +- Village announcements and information +- Community discussion forum +- Village activity calendar +- Village documentation and archives +- Project and task management +- Member and organizational structure management +- Push notifications for important updates +- Verification and authentication features + +## Technologies Used: +- **React Native**: Cross-platform mobile development framework. +- **Expo**: Platform for React Native application development. +- **Firebase**: Backend services including Authentication, Realtime Database, and Cloud Messaging. +- **Redux Toolkit**: State management. +- **React Navigation**: Application navigation. +- **TypeScript**: For type safety. + +## Building and Running: + +### Installation +1. **Clone the repository:** + ```bash + git clone + cd mobile-darmasaba + ``` +2. **Install dependencies:** + ```bash + npm install + ``` +3. **Configure environment variables:** + Create a `.env` file in the root directory and add the following variables: + ``` + URL_API= + URL_OTP= + URL_STORAGE= + URL_FIREBASE_DB= + PASS_ENC= + WA_SERVER_TOKEN= + IOS_GOOGLE_SERVICES_FILE= + ``` + +### Running the Application +- **Start development server:** + ```bash + npx expo start + ``` +- **Run on Android emulator/device:** + ```bash + npm run android + ``` +- **Run on iOS simulator/device:** + ```bash + npm run ios + ``` + +### Build Production +- **Build Android production package:** + ```bash + npm run build:android + ``` + +## Development Conventions: + +### Project Structure: +- `app/`: Main page files. +- `components/`: Reusable UI components, categorized by feature (e.g., `announcement/`, `auth/`, `discussion/`). +- `assets/`: Images and static assets. +- `constants/`: Global constants. +- `lib/`: Libraries and utilities. + +### Contribution Guidelines: +1. Fork the repository. +2. Create a new feature branch (`git checkout -b feature/FeatureName`). +3. Commit your changes (`git commit -m 'Add FeatureName feature'`). +4. Push to the branch (`git push origin feature/FeatureName`). +5. Create a pull request. + +## Platform Support: +- ✅ Android +- ✅ iOS +- ❌ Web (not yet optimized) diff --git a/app/(application)/announcement/[id].tsx b/app/(application)/announcement/[id].tsx index c489744..a11ac99 100644 --- a/app/(application)/announcement/[id].tsx +++ b/app/(application)/announcement/[id].tsx @@ -8,6 +8,7 @@ import { isImageFile } from "@/constants/FileExtensions"; import Styles from "@/constants/Styles"; import { apiGetAnnouncementOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Entypo, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; @@ -51,6 +52,7 @@ interface ApiResponse { export default function DetailAnnouncement() { const { id } = useLocalSearchParams<{ id: string }>(); const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [data, setData] = useState({ id: '', title: '', desc: '' }) const [dataMember, setDataMember] = useState>({}) const [dataFile, setDataFile] = useState([]) @@ -175,7 +177,7 @@ export default function DetailAnnouncement() { }; return ( - + { router.back() }} />, @@ -193,16 +195,17 @@ export default function DetailAnnouncement() { /> handleRefresh()} + tintColor={colors.primary} /> } > - + { loading ? @@ -219,7 +222,7 @@ export default function DetailAnnouncement() { : <> - + {data?.title} @@ -228,7 +231,7 @@ export default function DetailAnnouncement() { : {data?.desc} @@ -240,7 +243,7 @@ export default function DetailAnnouncement() { { dataFile.length > 0 && ( - + File @@ -251,7 +254,7 @@ export default function DetailAnnouncement() { icon={} title={item.name + '.' + item.extension} titleWeight="normal" @@ -265,7 +268,7 @@ export default function DetailAnnouncement() { ) } - + { loading ? arrSkeleton.map((item, index) => { @@ -286,7 +289,7 @@ export default function DetailAnnouncement() { dataMember[v].map((item: any, x: any) => { return ( - + {item.division} ) diff --git a/app/(application)/announcement/create.tsx b/app/(application)/announcement/create.tsx index 2ca3df3..eddd587 100644 --- a/app/(application)/announcement/create.tsx +++ b/app/(application)/announcement/create.tsx @@ -12,6 +12,7 @@ import Styles from "@/constants/Styles"; import { setUpdateAnnouncement } from "@/lib/announcementUpdate"; import { apiCreateAnnouncement } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Entypo, Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack } from "expo-router"; @@ -24,6 +25,7 @@ export default function CreateAnnouncement() { const dispatch = useDispatch() const update = useSelector((state: any) => state.announcementUpdate) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [disableBtn, setDisableBtn] = useState(true); const [modalDivisi, setModalDivisi] = useState(false); const [divisionMember, setDivisionMember] = useState([]) @@ -129,7 +131,7 @@ export default function CreateAnnouncement() { } return ( - + ( @@ -158,15 +160,15 @@ export default function CreateAnnouncement() { showBack={true} onPressLeft={() => router.back()} right={ - { - divisionMember.length == 0 - ? Toast.show({ type: 'small', text1: "Anda belum memilih divisi", }) - : handleCreate(); - }} - /> + { + divisionMember.length == 0 + ? Toast.show({ type: 'small', text1: "Anda belum memilih divisi", }) + : handleCreate(); + }} + /> } /> ) @@ -175,7 +177,7 @@ export default function CreateAnnouncement() { validationForm("title", val)} /> @@ -193,6 +196,7 @@ export default function CreateAnnouncement() { placeholder="Deskripsi Pengumuman" required error={error.desc} + bg={colors.card} errorText="Pengumuman harus diisi" onChange={(val) => validationForm("desc", val)} multiline @@ -208,7 +212,7 @@ export default function CreateAnnouncement() { 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModalFile(true) }} @@ -237,7 +241,7 @@ export default function CreateAnnouncement() { { item.Division.map((division: any, i: any) => ( - + {division.name} )) @@ -266,7 +270,7 @@ export default function CreateAnnouncement() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/announcement/edit/[id].tsx b/app/(application)/announcement/edit/[id].tsx index c96984b..35e2a73 100644 --- a/app/(application)/announcement/edit/[id].tsx +++ b/app/(application)/announcement/edit/[id].tsx @@ -12,6 +12,7 @@ import Styles from "@/constants/Styles"; import { setUpdateAnnouncement } from "@/lib/announcementUpdate"; import { apiEditAnnouncement, apiGetAnnouncementOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Entypo, Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -35,6 +36,7 @@ export default function EditAnnouncement() { const dispatch = useDispatch() const update = useSelector((state: any) => state.announcementUpdate) const { token, decryptToken } = useAuthSession(); + const { colors } = useTheme(); const [modalDivisi, setModalDivisi] = useState(false); const [disableBtn, setDisableBtn] = useState(true); const [dataMember, setDataMember] = useState([]); @@ -180,7 +182,7 @@ export default function EditAnnouncement() { } return ( - + ( @@ -226,7 +228,7 @@ export default function EditAnnouncement() { validationForm("title", val)} value={dataForm.title} @@ -245,6 +248,7 @@ export default function EditAnnouncement() { placeholder="Deskripsi Pengumuman" required error={error.desc} + bg={colors.card} errorText="Pengumuman harus diisi" onChange={(val) => validationForm("desc", val)} value={dataForm.desc} @@ -261,7 +265,7 @@ export default function EditAnnouncement() { 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name + '.' + item.extension} titleWeight="normal" onPress={() => { setIndexDelFile({ id: item.id, cat: "oldFile" }); setModalFile(true) }} @@ -273,7 +277,7 @@ export default function EditAnnouncement() { 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile({ id: index, cat: "newFile" }); setModalFile(true) }} @@ -300,7 +304,7 @@ export default function EditAnnouncement() { { item.Division.map((division: any, i: any) => ( - + {division.name} )) @@ -330,7 +334,7 @@ export default function EditAnnouncement() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile.id, indexDelFile.cat) }} /> diff --git a/app/(application)/announcement/index.tsx b/app/(application)/announcement/index.tsx index 75e628b..0c43ee3 100644 --- a/app/(application)/announcement/index.tsx +++ b/app/(application)/announcement/index.tsx @@ -6,6 +6,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetAnnouncement } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialIcons } from "@expo/vector-icons"; import { router } from "expo-router"; import { useEffect, useState } from "react"; @@ -22,6 +23,7 @@ type Props = { export default function Announcement() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [data, setData] = useState([]) const [search, setSearch] = useState('') const update = useSelector((state: any) => state.announcementUpdate) @@ -83,7 +85,7 @@ export default function Announcement() { }) return ( - + @@ -127,6 +129,7 @@ export default function Announcement() { } /> diff --git a/app/(application)/banner/[id].tsx b/app/(application)/banner/[id].tsx index 7e59eda..18d341c 100644 --- a/app/(application)/banner/[id].tsx +++ b/app/(application)/banner/[id].tsx @@ -7,6 +7,7 @@ import Styles from "@/constants/Styles"; import { apiEditBanner, apiGetBanner, apiGetBannerOne } from "@/lib/api"; import { setEntities } from "@/lib/bannerSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Entypo } from "@expo/vector-icons"; import * as ImagePicker from "expo-image-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -24,6 +25,7 @@ import { useDispatch } from "react-redux"; export default function EditBanner() { const dispatch = useDispatch(); const { decryptToken, token } = useAuthSession(); + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>(); const [selectedImage, setSelectedImage] = useState< string | undefined | { uri: string } @@ -112,7 +114,7 @@ export default function EditBanner() { }; return ( - + ( @@ -143,7 +145,7 @@ export default function EditBanner() { ) }} /> - + {selectedImage != undefined ? ( @@ -179,7 +181,7 @@ export default function EditBanner() { type="default" placeholder="Judul" required - bg="white" + bg={colors.card} value={title} error={error} onChange={onValidate} diff --git a/app/(application)/banner/create.tsx b/app/(application)/banner/create.tsx index 76e382a..a92562e 100644 --- a/app/(application)/banner/create.tsx +++ b/app/(application)/banner/create.tsx @@ -6,6 +6,7 @@ import Styles from "@/constants/Styles"; import { apiCreateBanner, apiGetBanner } from "@/lib/api"; import { setEntities } from "@/lib/bannerSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Entypo } from "@expo/vector-icons"; import * as ImagePicker from "expo-image-picker"; import { router, Stack } from "expo-router"; @@ -22,6 +23,7 @@ import { useDispatch } from "react-redux"; export default function CreateBanner() { const { decryptToken, token } = useAuthSession(); + const { colors } = useTheme(); const dispatch = useDispatch(); const [selectedImage, setSelectedImage] = useState( undefined @@ -94,7 +96,7 @@ export default function CreateBanner() { }; return ( - + ( @@ -133,7 +135,7 @@ export default function CreateBanner() { ) }} /> - + {selectedImage != undefined ? ( @@ -165,7 +167,7 @@ export default function CreateBanner() { type="default" placeholder="Judul" required - bg="white" + bg={colors.card} onChange={onValidate} error={error} errorText="Judul harus diisi" diff --git a/app/(application)/banner/index.tsx b/app/(application)/banner/index.tsx index 3de81f9..ff8d4b0 100644 --- a/app/(application)/banner/index.tsx +++ b/app/(application)/banner/index.tsx @@ -11,6 +11,7 @@ import Styles from "@/constants/Styles" import { apiDeleteBanner, apiGetBanner } from "@/lib/api" import { setEntities } from "@/lib/bannerSlice" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons" import * as FileSystem from 'expo-file-system' import { startActivityAsync } from 'expo-intent-launcher' @@ -32,6 +33,7 @@ type Props = { export default function BannerList() { const { decryptToken, token } = useAuthSession() + const { colors } = useTheme() const [isModal, setModal] = useState(false) const entities = useSelector((state: any) => state.banner) const [dataId, setDataId] = useState('') @@ -105,7 +107,7 @@ export default function BannerList() { return ( - + { router.back() }} />, @@ -130,9 +132,10 @@ export default function BannerList() { } - style={[Styles.h100]} + style={[Styles.h100, { backgroundColor: colors.background }]} > { entities.length > 0 @@ -170,7 +173,7 @@ export default function BannerList() { setModal(false)} title="Menu"> } + icon={} title="Edit" onPress={() => { setModal(false) @@ -178,7 +181,7 @@ export default function BannerList() { }} /> } + icon={} title="Lihat" onPress={() => { setModal(false) @@ -189,7 +192,7 @@ export default function BannerList() { }} /> } + icon={} title="Hapus" onPress={() => { setModal(false) diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx index a20d86f..edf3bd6 100644 --- a/app/(application)/discussion/[id].tsx +++ b/app/(application)/discussion/[id].tsx @@ -18,6 +18,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteDiscussionGeneralCommentar, apiGetDiscussionGeneralOne, apiSendDiscussionGeneralCommentar, apiUpdateDiscussionGeneralCommentar } from "@/lib/api"; import { getDB } from "@/lib/firebaseDatabase"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { ref } from '@react-native-firebase/database'; import { useHeaderHeight } from '@react-navigation/elements'; @@ -56,6 +57,7 @@ type PropsFile = { export default function DetailDiscussionGeneral() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const entities = useSelector((state: any) => state.entities) const { id } = useLocalSearchParams<{ id: string }>(); @@ -237,14 +239,15 @@ export default function DetailDiscussionGeneral() { ) }} /> - + handleRefresh()} + tintColor={colors.primary} /> } > @@ -333,7 +336,7 @@ export default function DetailDiscussionGeneral() { { @@ -341,11 +344,11 @@ export default function DetailDiscussionGeneral() { <> - + Edit Komentar handleViewEditKomentar()}> - + } + icon={} title="Edit" onPress={() => { handleViewEditKomentar() }} /> } + icon={} title="Hapus" onPress={() => { AlertKonfirmasi({ diff --git a/app/(application)/discussion/add-member/[id].tsx b/app/(application)/discussion/add-member/[id].tsx index fe3af20..3266b1e 100644 --- a/app/(application)/discussion/add-member/[id].tsx +++ b/app/(application)/discussion/add-member/[id].tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiAddMemberDiscussionGeneral, apiGetDiscussionGeneralOne, apiGetUser } from "@/lib/api"; import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -26,6 +27,7 @@ export default function AddMemberDiscussionDetail() { const dispatch = useDispatch() const update = useSelector((state: any) => state.discussionGeneralDetailUpdate) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>() const [dataOld, setDataOld] = useState([]) const [data, setData] = useState([]) @@ -125,7 +127,7 @@ export default function AddMemberDiscussionDetail() { ) }} /> - + { @@ -175,7 +177,7 @@ export default function AddMemberDiscussionDetail() { { - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && } ) diff --git a/app/(application)/discussion/create.tsx b/app/(application)/discussion/create.tsx index 22e660d..2a775be 100644 --- a/app/(application)/discussion/create.tsx +++ b/app/(application)/discussion/create.tsx @@ -16,6 +16,7 @@ import { apiCreateDiscussionGeneral } from "@/lib/api"; import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail"; import { setMemberChoose } from "@/lib/memberChoose"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack } from "expo-router"; @@ -27,6 +28,7 @@ import { useDispatch, useSelector } from "react-redux"; export default function CreateDiscussionGeneral() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user); const userLogin = useSelector((state: any) => state.entities) const [chooseGroup, setChooseGroup] = useState({ val: "", label: "" }); @@ -163,7 +165,7 @@ export default function CreateDiscussionGeneral() { } return ( - + ( @@ -205,7 +207,7 @@ export default function CreateDiscussionGeneral() { }} /> - + { (entityUser.role == "supadmin" || @@ -215,6 +217,7 @@ export default function CreateDiscussionGeneral() { placeholder="Pilih Lembaga Desa" value={chooseGroup.label} required + bg={colors.card} onPress={() => { setValChoose(chooseGroup.val); setValSelect("group"); @@ -231,6 +234,7 @@ export default function CreateDiscussionGeneral() { placeholder="Judul" required error={error.title} + bg={colors.card} errorText="Judul tidak boleh kosong" onChange={(val) => { validationForm("title", val) }} /> @@ -240,6 +244,7 @@ export default function CreateDiscussionGeneral() { placeholder="Hal yang didiskusikan" required error={error.desc} + bg={colors.card} errorText="Diskusi tidak boleh kosong" onChange={(val) => { validationForm("desc", val) }} multiline @@ -248,14 +253,14 @@ export default function CreateDiscussionGeneral() { { fileForm.length > 0 && - + File { fileForm.map((item, index) => ( 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModalFile(true) }} @@ -291,7 +296,7 @@ export default function CreateDiscussionGeneral() { Total {entitiesMember.length} Anggota - + { entitiesMember.map((item: { img: any; name: any; }, index: any) => { return ( @@ -327,7 +332,7 @@ export default function CreateDiscussionGeneral() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/discussion/edit/[id].tsx b/app/(application)/discussion/edit/[id].tsx index 4a01537..6315525 100644 --- a/app/(application)/discussion/edit/[id].tsx +++ b/app/(application)/discussion/edit/[id].tsx @@ -11,6 +11,7 @@ import Styles from "@/constants/Styles"; import { apiEditDiscussionGeneral, apiGetDiscussionGeneralOne } from "@/lib/api"; import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -21,6 +22,7 @@ import { useDispatch, useSelector } from "react-redux"; export default function EditDiscussionGeneral() { const { token, decryptToken } = useAuthSession(); + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>(); const [disableBtn, setDisableBtn] = useState(false) const dispatch = useDispatch() @@ -162,7 +164,7 @@ export default function EditDiscussionGeneral() { } return ( - + ( @@ -198,13 +200,14 @@ export default function EditDiscussionGeneral() { }} /> - + 0 || dataFile.filter((val) => !val.delete).length > 0) && - + File { dataFile.filter((val) => !val.delete).map((item, index) => ( 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name + '.' + item.extension} titleWeight="normal" onPress={() => { setIndexDelFile({ id: item.id, cat: "oldFile" }); setModalFile(true) }} @@ -244,7 +248,7 @@ export default function EditDiscussionGeneral() { 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile({ id: index, cat: "newFile" }); setModalFile(true) }} @@ -259,7 +263,7 @@ export default function EditDiscussionGeneral() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile.id, indexDelFile.cat) }} /> diff --git a/app/(application)/discussion/index.tsx b/app/(application)/discussion/index.tsx index b5714c5..4d94adb 100644 --- a/app/(application)/discussion/index.tsx +++ b/app/(application)/discussion/index.tsx @@ -8,6 +8,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetDiscussionGeneral } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather, Ionicons, MaterialIcons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -27,6 +28,7 @@ type Props = { export default function Discussion() { const entityUser = useSelector((state: any) => state.user) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const { active, group } = useLocalSearchParams<{ active?: string, group?: string }>() const [search, setSearch] = useState('') const [nameGroup, setNameGroup] = useState('') @@ -96,24 +98,24 @@ export default function Discussion() { }) return ( - + { entityUser.role != "user" && entityUser.role != "coadmin" && - + { setStatus("true") }} label="Aktif" - icon={} + icon={} n={2} /> { setStatus("false") }} label="Arsip" - icon={} + icon={} n={2} /> } @@ -178,6 +180,7 @@ export default function Discussion() { } /> diff --git a/app/(application)/discussion/member/[id].tsx b/app/(application)/discussion/member/[id].tsx index cb836bf..ee3ce94 100644 --- a/app/(application)/discussion/member/[id].tsx +++ b/app/(application)/discussion/member/[id].tsx @@ -11,6 +11,7 @@ import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { apiDeleteMemberDiscussionGeneral, apiGetDiscussionGeneralOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, MaterialCommunityIcons } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -26,6 +27,7 @@ type Props = { export default function MemberDiscussionDetail() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const { id } = useLocalSearchParams<{ id: string }>() const [data, setData] = useState([]) @@ -71,7 +73,7 @@ export default function MemberDiscussionDetail() { } return ( - + { router.back() }} />, @@ -86,10 +88,10 @@ export default function MemberDiscussionDetail() { ) }} /> - + {data.length} Anggota - + { entityUser.role != "user" && entityUser.role != "coadmin" && } + icon={} title="Lihat Profil" onPress={() => { setModal(false) @@ -145,7 +147,7 @@ export default function MemberDiscussionDetail() { { entityUser.role != "user" && entityUser.role != "coadmin" && } + icon={} title="Keluarkan" onPress={() => { setModal(false) diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/add-member.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/add-member.tsx index 6786243..56dcf74 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/add-member.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/add-member.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiAddMemberCalendar, apiGetCalendarOne, apiGetDivisionMember } from "@/lib/api"; import { setUpdateCalendar } from "@/lib/calendarUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberCalendarEvent() { + const { colors } = useTheme(); const dispatch = useDispatch() const update = useSelector((state: any) => state.calendarUpdate) const { token, decryptToken } = useAuthSession() @@ -100,7 +102,7 @@ export default function AddMemberCalendarEvent() { return ( - + { router.back() }} />, @@ -182,7 +184,7 @@ export default function AddMemberCalendarEvent() { { - selectMember.some((i: any) => i.idUser == item.idUser) && + selectMember.some((i: any) => i.idUser == item.idUser) && } ) diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/edit.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/edit.tsx index 422df92..0d6b753 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/edit.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/edit.tsx @@ -9,6 +9,7 @@ import { valueTypeEventRepeat } from "@/constants/TypeEventRepeat" import { apiGetCalendarOne, apiUpdateCalendar } from "@/lib/api" import { stringToDateTime } from "@/lib/fun_stringToDate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from "@react-navigation/elements" import { Stack, router, useLocalSearchParams } from "expo-router" import moment from "moment" @@ -17,6 +18,7 @@ import { KeyboardAvoidingView, Platform, SafeAreaView, ScrollView, View } from " import Toast from "react-native-toast-message" export default function EditEventCalendar() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const [choose, setChoose] = useState({ val: "", label: "" }) const [isSelect, setSelect] = useState(false) @@ -162,7 +164,7 @@ export default function EditEventCalendar() { return ( - + { router.back() }} />, @@ -205,7 +207,7 @@ export default function EditEventCalendar() { type="default" placeholder="Nama Acara" required - bg="white" + bg={colors.card} value={data.title} onChange={(val) => validationForm("title", val)} error={error.title} @@ -251,12 +253,12 @@ export default function EditEventCalendar() { label="Link Meet" type="default" placeholder="Link Meet" - bg="white" + bg={colors.card} value={data.linkMeet} onChange={(val) => validationForm("linkMeet", val)} /> validationForm("repeatValue", val)} error={error.repeatValue} @@ -279,7 +281,7 @@ export default function EditEventCalendar() { label="Deskripsi" type="default" placeholder="Deskripsi" - bg="white" + bg={colors.card} value={data.desc} onChange={(val) => validationForm("desc", val)} multiline diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx index 6778110..37b1b56 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/[detail]/index.tsx @@ -13,6 +13,7 @@ import Styles from "@/constants/Styles" import { apiDeleteCalendarMember, apiGetCalendarOne, apiGetDivisionOneFeature } from "@/lib/api" import { setUpdateCalendar } from "@/lib/calendarUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { MaterialCommunityIcons } from "@expo/vector-icons" import Clipboard from "@react-native-clipboard/clipboard" import { router, Stack, useLocalSearchParams } from "expo-router" @@ -45,6 +46,7 @@ type PropsMember = { } export default function DetailEventCalendar() { + const { colors } = useTheme() const { id, detail } = useLocalSearchParams<{ id: string, detail: string }>(); const [data, setData] = useState() const [member, setMember] = useState([]) @@ -152,14 +154,14 @@ export default function DetailEventCalendar() { }; return ( - + { router.back() }} />, headerTitle: 'Detail Acara', headerTitleAlign: 'center', // headerRight: () => (entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision ? <> : - header:()=>( + header: () => ( - + - + { loading ? @@ -192,7 +194,7 @@ export default function DetailEventCalendar() { - + { loading ? @@ -201,7 +203,7 @@ export default function DetailEventCalendar() { } - + { loading ? @@ -210,7 +212,7 @@ export default function DetailEventCalendar() { } - + { loading ? @@ -228,7 +230,7 @@ export default function DetailEventCalendar() { } - + { loading ? @@ -241,7 +243,7 @@ export default function DetailEventCalendar() { } - + { loading ? @@ -257,7 +259,7 @@ export default function DetailEventCalendar() { Total {member.length} Anggota - + { member.map((item, index) => ( } + icon={} title="Lihat Profil" onPress={() => { setModalMember(false) @@ -295,7 +297,7 @@ export default function DetailEventCalendar() { /> } + icon={} title="Keluarkan" onPress={() => { setModalMember(false) diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/create-member.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/create-member.tsx index 4365d8e..9c6c307 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/create-member.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/create-member.tsx @@ -10,6 +10,7 @@ import { apiCreateCalendar, apiGetDivisionMember } from "@/lib/api"; import { setFormCreateCalendar } from "@/lib/calendarCreate"; import { setUpdateCalendar } from "@/lib/calendarUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -24,6 +25,7 @@ type Props = { } export default function CreateCalendarAddMember() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>() const [data, setData] = useState([]) @@ -90,7 +92,7 @@ export default function CreateCalendarAddMember() { } return ( - + { router.back() }} />, @@ -164,7 +166,7 @@ export default function CreateCalendarAddMember() { { - selectMember.some((i: any) => i.idUser == item.idUser) && + selectMember.some((i: any) => i.idUser == item.idUser) && } ) diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/create.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/create.tsx index c6f1394..fe545d4 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/create.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/create.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { setFormCreateCalendar } from "@/lib/calendarCreate"; import { stringToDateTime } from "@/lib/fun_stringToDate"; import { useHeaderHeight } from '@react-navigation/elements'; +import { useTheme } from "@/providers/ThemeProvider"; import { Stack, router, useLocalSearchParams } from "expo-router"; import { useState } from "react"; import { @@ -21,6 +22,7 @@ import { import { useDispatch, useSelector } from "react-redux"; export default function CalendarDivisionCreate() { + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>() const [choose, setChoose] = useState({ val: "", label: "" }) const [isSelect, setSelect] = useState(false) @@ -126,7 +128,7 @@ export default function CalendarDivisionCreate() { } return ( - + ( @@ -144,7 +146,7 @@ export default function CalendarDivisionCreate() { // disable={Object.values(error).some((val) => val == true) || data.title == "" || data.dateStart == "" || data.timeStart == "" || data.timeEnd == "" || data.repeatEventType == ""} // /> // ), - header:()=>( + header: () => ( validationForm("title", val)} error={error.title} @@ -219,12 +221,12 @@ export default function CalendarDivisionCreate() { label="Link Meet" type="default" placeholder="Link Meet" - bg="white" + bg={colors.card} value={data.linkMeet} onChange={(val) => validationForm("linkMeet", val)} /> validationForm("repeatValue", val)} error={error.repeatValue} @@ -247,7 +249,7 @@ export default function CalendarDivisionCreate() { label="Deskripsi" type="default" placeholder="Deskripsi" - bg="white" + bg={colors.card} value={data.desc} onChange={(val) => validationForm("desc", val)} multiline diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/history.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/history.tsx index 9215379..875bf74 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/history.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/history.tsx @@ -5,6 +5,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetCalendarHistory } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { FlatList, View, VirtualizedList } from "react-native"; @@ -15,6 +16,7 @@ type Props = { data: [] } export default function CalendarHistory() { + const { colors, activeTheme } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>(); const { token, decryptToken } = useAuthSession(); const [data, setData] = useState([]) @@ -64,7 +66,7 @@ export default function CalendarHistory() { }) return ( - + setSearch(val)} /> @@ -81,7 +83,7 @@ export default function CalendarHistory() { getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - + {String(item.dateStart)} {item.year} diff --git a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx index 7d16ea1..a8a194b 100644 --- a/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/calendar/index.tsx @@ -7,6 +7,7 @@ import Text from "@/components/Text"; import Styles from "@/constants/Styles"; import { apiGetCalendarByDateDivision, apiGetIndicatorCalendar } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import 'intl'; @@ -34,6 +35,7 @@ type Props = { }; export default function CalendarDivision() { + const { colors, activeTheme } = useTheme(); const [selected, setSelected] = useState(new Date()) const [data, setData] = useState([]) const { token, decryptToken } = useAuthSession() @@ -117,15 +119,15 @@ export default function CalendarDivision() { ); }, IconNext: !loadingBtn ? setMonth(month + 1) : null}> - + , IconPrev: !loadingBtn ? setMonth(month - 1) : null}> - + , }; return ( - + ( @@ -158,7 +160,7 @@ export default function CalendarDivision() { style={[Styles.h100]} > - + setMonth(month)} styles={{ selected: Styles.selectedDate, - month_label: Styles.cBlack, - month_selector_label: Styles.cBlack, - year_label: Styles.cBlack, - year_selector_label: Styles.cBlack, - day_label: Styles.cBlack, - time_label: Styles.cBlack, - weekday_label: Styles.cBlack, + month_label: { color: colors.text }, + month_selector_label: { color: colors.text }, + year_label: { color: colors.text }, + year_selector_label: { color: colors.text }, + day_label: { color: colors.text }, + time_label: { color: colors.text }, + weekday_label: { color: colors.text }, }} /> Acara - + { loading ? <> diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/edit.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/edit.tsx index 15766ac..444c4bc 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/edit.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/edit.tsx @@ -11,6 +11,7 @@ import Styles from "@/constants/Styles"; import { apiEditDiscussion, apiGetDiscussionOne } from "@/lib/api"; import { setUpdateDiscussion } from "@/lib/discussionUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -20,6 +21,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function DiscussionDivisionEdit() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { token, decryptToken } = useAuthSession(); const [data, setData] = useState(""); @@ -127,7 +129,7 @@ export default function DiscussionDivisionEdit() { } return ( - + ( @@ -177,20 +179,21 @@ export default function DiscussionDivisionEdit() { value={data} onChange={setData} multiline + bg={colors.card} /> { (fileForm.length > 0 || dataFile.filter((val) => !val.delete).length > 0) && - + File { dataFile.filter((val) => !val.delete).map((item, index) => ( 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name + '.' + item.extension} titleWeight="normal" onPress={() => { setIndexDelFile({ id: item.id, cat: "oldFile" }); setModalFile(true) }} @@ -202,7 +205,7 @@ export default function DiscussionDivisionEdit() { 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile({ id: index, cat: "newFile" }); setModalFile(true) }} @@ -218,7 +221,7 @@ export default function DiscussionDivisionEdit() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile.id, indexDelFile.cat) }} /> diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx index 6c235c2..a795b09 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx @@ -25,6 +25,7 @@ import { getDB } from "@/lib/firebaseDatabase"; import { useAuthSession } from "@/providers/AuthProvider"; import { Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { ref } from "@react-native-firebase/database"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -64,6 +65,7 @@ type PropsFile = { } export default function DiscussionDetail() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const [data, setData] = useState(); const [dataComment, setDataComment] = useState([]); @@ -306,7 +308,7 @@ export default function DiscussionDetail() { ) }} /> - + @@ -419,15 +421,15 @@ export default function DiscussionDetail() { <> - + Edit Komentar handleViewEditKomentar()}> - + } + icon={} title="Edit" onPress={() => { handleViewEditKomentar() }} /> } + icon={} title="Hapus" onPress={() => { AlertKonfirmasi({ diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/create.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/create.tsx index 389f790..24638a4 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/create.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/create.tsx @@ -11,6 +11,7 @@ import Styles from "@/constants/Styles" import { apiCreateDiscussion } from "@/lib/api" import { setUpdateDiscussion } from "@/lib/discussionUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons" import * as DocumentPicker from "expo-document-picker" import { router, Stack, useLocalSearchParams } from "expo-router" @@ -21,6 +22,7 @@ import { useDispatch, useSelector } from "react-redux" export default function CreateDiscussionDivision() { + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>() const [desc, setDesc] = useState('') const { token, decryptToken } = useAuthSession() @@ -88,7 +90,7 @@ export default function CreateDiscussionDivision() { } return ( - + { router.back() }} />, @@ -127,19 +129,20 @@ export default function CreateDiscussionDivision() { required onChange={setDesc} multiline + bg={colors.card} /> { fileForm.length > 0 && - + File { fileForm.map((item, index) => ( 1 ? "bottom" : "none"} - icon={} + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModalFile(true) }} @@ -154,7 +157,7 @@ export default function CreateDiscussionDivision() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx index 35c32c8..777a0a0 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx @@ -9,6 +9,7 @@ import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { apiGetDiscussion, apiGetDivisionOneFeature } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -30,6 +31,7 @@ type Props = { export default function DiscussionDivision() { + const { colors } = useTheme(); const { id, active } = useLocalSearchParams<{ id: string, active?: string }>() const [data, setData] = useState([]) const { token, decryptToken } = useAuthSession() @@ -128,24 +130,24 @@ export default function DiscussionDivision() { }) return ( - + { ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && - + { setStatus("true") }} label="Aktif" - icon={} + icon={} n={2} /> { setStatus("false") }} label="Arsip" - icon={} + icon={} n={2} /> diff --git a/app/(application)/division/[id]/(fitur-division)/document/index.tsx b/app/(application)/division/[id]/(fitur-division)/document/index.tsx index 27a02f6..4de1b7b 100644 --- a/app/(application)/division/[id]/(fitur-division)/document/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/document/index.tsx @@ -24,6 +24,7 @@ import { } from "@/lib/api"; import { setUpdateDokumen } from "@/lib/dokumenUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, MaterialCommunityIcons, @@ -66,6 +67,7 @@ type PropsPath = { }; export default function DocumentDivision() { + const { colors } = useTheme(); const [loadingRename, setLoadingRename] = useState(false) const [isShare, setShare] = useState(false) const { token, decryptToken } = useAuthSession() @@ -334,7 +336,7 @@ export default function DocumentDivision() { }, [path]); return ( - + @@ -427,9 +429,9 @@ export default function DocumentDivision() { }} > {item.id != "home" && ( - + )} - {item.name} + {item.name} )) } diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-file.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-file.tsx index f29ebf4..22f043b 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-file.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-file.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiAddFileTask, apiCheckFileTask } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -23,6 +24,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function TaskDivisionAddFile() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const [fileForm, setFileForm] = useState([]); const [listFile, setListFile] = useState([]); @@ -127,7 +129,7 @@ export default function TaskDivisionAddFile() { } return ( - + ( @@ -169,13 +171,13 @@ export default function TaskDivisionAddFile() { listFile.length > 0 && ( File - + { listFile.map((item, index) => ( } + icon={} title={item} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModal(true) }} @@ -197,7 +199,7 @@ export default function TaskDivisionAddFile() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-member.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-member.tsx index c5ab805..09bf071 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-member.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-member.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiAddMemberTask, apiGetDivisionMember, apiGetTaskOne } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberTask() { + const { colors } = useTheme(); const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) const { token, decryptToken } = useAuthSession() @@ -127,7 +129,7 @@ export default function AddMemberTask() { ) }} /> - + setSearch(val)} value={search} /> { @@ -177,7 +179,7 @@ export default function AddMemberTask() { { - selectMember.some((i: any) => i.idUser == item.idUser) && + selectMember.some((i: any) => i.idUser == item.idUser) && } ) diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-task.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-task.tsx index 8b88b07..7498b06 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-task.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/add-task.tsx @@ -9,6 +9,7 @@ import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import 'intl'; @@ -25,6 +26,7 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import { useDispatch, useSelector } from "react-redux"; export default function TaskDivisionAddTask() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const dispatch = useDispatch(); const update = useSelector((state: any) => state.taskUpdate); @@ -138,7 +140,7 @@ export default function TaskDivisionAddTask() { } return ( - + ( @@ -183,7 +185,7 @@ export default function TaskDivisionAddTask() { > - + @@ -209,7 +211,7 @@ export default function TaskDivisionAddTask() { Tanggal Mulai * - + {from} @@ -217,7 +219,7 @@ export default function TaskDivisionAddTask() { Tanggal Berakhir * - + {to} @@ -238,7 +240,7 @@ export default function TaskDivisionAddTask() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/cancel.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/cancel.tsx index ac72588..d9d0254 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/cancel.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/cancel.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiCancelTask } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function TaskDivisionCancel() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { token, decryptToken } = useAuthSession(); const dispatch = useDispatch(); @@ -69,7 +71,7 @@ export default function TaskDivisionCancel() { } return ( - + ( @@ -115,7 +117,7 @@ export default function TaskDivisionCancel() { type="default" placeholder="Alasan Pembatalan" required - bg="white" + bg={colors.card} error={error} errorText="Alasan pembatalan harus diisi" onChange={(val) => onValidation(val)} diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/edit.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/edit.tsx index e67416b..eaf71b6 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/edit.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/edit.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiEditTask, apiGetTaskOne } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function TaskDivisionEdit() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { token, decryptToken } = useAuthSession(); const [judul, setJudul] = useState(""); @@ -87,7 +89,7 @@ export default function TaskDivisionEdit() { } return ( - + ( @@ -128,7 +130,7 @@ export default function TaskDivisionEdit() { type="default" placeholder="Judul Kegiatan" required - bg="white" + bg={colors.card} value={judul} onChange={(val) => { onValidation(val) }} error={error} diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx index 4ed956f..8eecb3c 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/index.tsx @@ -10,6 +10,7 @@ import SectionTanggalTugasTask from "@/components/task/sectionTanggalTugasTask"; import Styles from "@/constants/Styles"; import { apiGetDivisionOneFeature, apiGetTaskOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; @@ -25,6 +26,7 @@ type Props = { } export default function DetailTaskDivision() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string, detail: string }>(); const { token, decryptToken } = useAuthSession() const [data, setData] = useState() @@ -97,7 +99,7 @@ export default function DetailTaskDivision() { }; return ( - + { router.back() }} />, diff --git a/app/(application)/division/[id]/(fitur-division)/task/[detail]/report.tsx b/app/(application)/division/[id]/(fitur-division)/task/[detail]/report.tsx index ba00bd1..097d6f1 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/[detail]/report.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/[detail]/report.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiGetTaskOne, apiReportTask } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function TaskDivisionReport() { + const { colors } = useTheme(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { token, decryptToken } = useAuthSession(); const [laporan, setLaporan] = useState(""); @@ -87,7 +89,7 @@ export default function TaskDivisionReport() { } return ( - + ( @@ -128,7 +130,7 @@ export default function TaskDivisionReport() { type="default" placeholder="Laporan Kegiatan" required - bg="white" + bg={colors.card} value={laporan} onChange={(val) => { onValidation(val) }} error={error} diff --git a/app/(application)/division/[id]/(fitur-division)/task/create.tsx b/app/(application)/division/[id]/(fitur-division)/task/create.tsx index 698918b..3ecec35 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/create.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/create.tsx @@ -16,6 +16,7 @@ import { setMemberChoose } from "@/lib/memberChoose"; import { setTaskCreate } from "@/lib/taskCreate"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -26,6 +27,7 @@ import { useDispatch, useSelector } from "react-redux"; export default function CreateTaskDivision() { + const { colors } = useTheme(); const { id } = useLocalSearchParams(); const { token, decryptToken } = useAuthSession(); const dispatch = useDispatch(); @@ -113,7 +115,7 @@ export default function CreateTaskDivision() { return ( - + ( @@ -161,6 +163,7 @@ export default function CreateTaskDivision() { val == "" || val == "null" ? setError(true) : setError(false); }} error={error} + bg={colors.card} errorText="Judul Tugas tidak boleh kosong" /> { router.push(`/division/${id}/task/create/task`); }} /> @@ -171,13 +174,13 @@ export default function CreateTaskDivision() { fileForm.length > 0 && ( File - + { fileForm.map((item, index) => ( } + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModal(true) }} @@ -195,7 +198,7 @@ export default function CreateTaskDivision() { Total {entitiesMember.length} Anggota - + {entitiesMember.map( (item: { img: any; name: any }, index: any) => { return ( @@ -223,7 +226,7 @@ export default function CreateTaskDivision() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/division/[id]/(fitur-division)/task/create/member.tsx b/app/(application)/division/[id]/(fitur-division)/task/create/member.tsx index 2c4ac7b..3890c20 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/create/member.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/create/member.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiGetDivisionMember } from "@/lib/api"; import { setMemberChoose } from "@/lib/memberChoose"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberCreateTask() { + const { colors } = useTheme(); const dispatch = useDispatch() const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string, detail: string }>() @@ -97,7 +99,7 @@ export default function AddMemberCreateTask() { ) }} /> - + setSearch(val)} value={search} /> { @@ -143,7 +145,7 @@ export default function AddMemberCreateTask() { { - selectMember.some((i: any) => i.idUser == item.idUser) && + selectMember.some((i: any) => i.idUser == item.idUser) && } ) diff --git a/app/(application)/division/[id]/(fitur-division)/task/create/task.tsx b/app/(application)/division/[id]/(fitur-division)/task/create/task.tsx index de290dd..8c857b0 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/create/task.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/create/task.tsx @@ -1,5 +1,6 @@ import AppHeader from "@/components/AppHeader"; import ButtonSaveHeader from "@/components/buttonSaveHeader"; +import { useTheme } from "@/providers/ThemeProvider"; import { InputForm } from "@/components/inputForm"; import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask"; import Text from "@/components/Text"; @@ -27,6 +28,7 @@ import DateTimePicker, { import { useDispatch, useSelector } from "react-redux"; export default function CreateTaskAddTugas() { + const { colors } = useTheme(); const headerHeight = useHeaderHeight(); const dispatch = useDispatch() const [disable, setDisable] = useState(true); @@ -118,7 +120,7 @@ export default function CreateTaskAddTugas() { } return ( - + ( @@ -158,7 +160,7 @@ export default function CreateTaskAddTugas() { > - + @@ -184,7 +186,7 @@ export default function CreateTaskAddTugas() { Tanggal Mulai * - + {from} @@ -192,7 +194,7 @@ export default function CreateTaskAddTugas() { Tanggal Berakhir * - + {to} @@ -213,7 +215,7 @@ export default function CreateTaskAddTugas() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/division/[id]/(fitur-division)/task/index.tsx b/app/(application)/division/[id]/(fitur-division)/task/index.tsx index 6822cb9..700011d 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/index.tsx @@ -11,6 +11,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetTask } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Ionicons, @@ -31,6 +32,7 @@ type Props = { }; export default function ListTask() { + const { colors } = useTheme() const { id, status, year } = useLocalSearchParams<{ id: string; status: string; year: string }>() const [isList, setList] = useState(false) const { token, decryptToken } = useAuthSession() @@ -110,7 +112,7 @@ export default function ListTask() { }) return ( - + } @@ -135,7 +137,7 @@ export default function ListTask() { icon={ } @@ -149,7 +151,7 @@ export default function ListTask() { icon={ } @@ -163,7 +165,7 @@ export default function ListTask() { icon={ } @@ -179,7 +181,7 @@ export default function ListTask() { > diff --git a/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx b/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx index af675b2..a1c0f50 100644 --- a/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx +++ b/app/(application)/division/[id]/(fitur-division)/task/update/[detail].tsx @@ -4,6 +4,7 @@ import { InputForm } from "@/components/inputForm"; import ModalAddDetailTugasTask from "@/components/task/modalAddDetailTugasTask"; import Text from "@/components/Text"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { apiEditTaskTugas, apiGetTaskTugas } from "@/lib/api"; import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; @@ -28,6 +29,7 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import { useDispatch, useSelector } from "react-redux"; export default function UpdateProjectTaskDivision() { + const { colors } = useTheme(); const headerHeight = useHeaderHeight(); const { detail } = useLocalSearchParams<{ detail: string }>(); const dispatch = useDispatch(); @@ -186,7 +188,7 @@ export default function UpdateProjectTaskDivision() { }, [range]) return ( - + ( @@ -231,7 +233,7 @@ export default function UpdateProjectTaskDivision() { > - + {!loading && ( )} @@ -261,7 +263,7 @@ export default function UpdateProjectTaskDivision() { Tanggal Mulai * - + {from} @@ -269,7 +271,7 @@ export default function UpdateProjectTaskDivision() { Tanggal Berakhir * - + {to} @@ -292,7 +294,7 @@ export default function UpdateProjectTaskDivision() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/division/[id]/add-member.tsx b/app/(application)/division/[id]/add-member.tsx index 2fed69e..5b72741 100644 --- a/app/(application)/division/[id]/add-member.tsx +++ b/app/(application)/division/[id]/add-member.tsx @@ -8,6 +8,7 @@ import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { apiAddMemberDivision, apiGetDivisionOneDetail, apiGetUser } from "@/lib/api"; import { setUpdateDivision } from "@/lib/divisionUpdate"; +import { useTheme } from "@/providers/ThemeProvider"; import { useAuthSession } from "@/providers/AuthProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberDivision() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>() const [dataOld, setDataOld] = useState([]) @@ -130,7 +132,7 @@ export default function AddMemberDivision() { ) }} /> - + handleSearch(val)} value={search} /> { @@ -180,7 +182,7 @@ export default function AddMemberDivision() { { - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && } ) diff --git a/app/(application)/division/[id]/edit.tsx b/app/(application)/division/[id]/edit.tsx index 02e425a..478d1e3 100644 --- a/app/(application)/division/[id]/edit.tsx +++ b/app/(application)/division/[id]/edit.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiEditDivision, apiGetDivisionOneDetail } from "@/lib/api"; import { setUpdateDivision } from "@/lib/divisionUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function EditDivision() { + const { colors } = useTheme(); const dispatch = useDispatch() const update = useSelector((state: any) => state.divisionUpdate) const { token, decryptToken } = useAuthSession(); @@ -63,7 +65,7 @@ export default function EditDivision() { } return ( - + ( @@ -98,7 +100,7 @@ export default function EditDivision() { ) }} /> - + () const [data, setData] = useState() @@ -54,7 +56,7 @@ export default function DetailDivisionFitur() { }; return ( - + { router.back() }} />, diff --git a/app/(application)/division/[id]/info.tsx b/app/(application)/division/[id]/info.tsx index 4ccd6b3..3b509ed 100644 --- a/app/(application)/division/[id]/info.tsx +++ b/app/(application)/division/[id]/info.tsx @@ -14,6 +14,7 @@ import Styles from "@/constants/Styles" import { apiDeleteMemberDivision, apiGetDivisionOneDetail, apiGetDivisionOneFeature, apiUpdateStatusAdminDivision } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" import { Feather, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" +import { useTheme } from "@/providers/ThemeProvider" import { router, Stack, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native" @@ -39,6 +40,7 @@ type PropsMember = { } export default function InformationDivision() { + const { colors } = useTheme() const [refreshing, setRefreshing] = useState(false) const entityUser = useSelector((state: any) => state.user) const { id } = useLocalSearchParams<{ id: string }>() @@ -161,7 +163,7 @@ export default function InformationDivision() { } return ( - + { router.back() }} />, @@ -187,7 +189,7 @@ export default function InformationDivision() { onRefresh={handleRefresh} /> } - style={[Styles.h100]} + style={[Styles.h100, { backgroundColor: colors.background }]} > { @@ -197,7 +199,7 @@ export default function InformationDivision() { } Deskripsi Divisi - + {loading ? arrSkeleton.map((item, index) => { return ( @@ -211,7 +213,7 @@ export default function InformationDivision() { {dataMember.length} Anggota - + { ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && dataDetail?.isActive && ( @@ -220,7 +222,7 @@ export default function InformationDivision() { borderType="none" icon={ - + } title="Tambah Anggota" @@ -261,7 +263,7 @@ export default function InformationDivision() { { handleMemberAdmin() }}> - + @@ -274,7 +276,7 @@ export default function InformationDivision() { { handleMemberOut() }}> - + diff --git a/app/(application)/division/[id]/report.tsx b/app/(application)/division/[id]/report.tsx index 18e76bd..cadbdf0 100644 --- a/app/(application)/division/[id]/report.tsx +++ b/app/(application)/division/[id]/report.tsx @@ -6,6 +6,7 @@ import { InputDate } from "@/components/inputDate" import Styles from "@/constants/Styles" import { apiGetDivisionReport } from "@/lib/api" import { stringToDate } from "@/lib/fun_stringToDate" +import { useTheme } from "@/providers/ThemeProvider" import { useAuthSession } from "@/providers/AuthProvider" import dayjs from "dayjs" import { router, Stack, useLocalSearchParams } from "expo-router" @@ -14,6 +15,7 @@ import { SafeAreaView, ScrollView, View } from "react-native" import Toast from "react-native-toast-message" export default function ReportDivision() { + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>() const { token, decryptToken } = useAuthSession(); const [showReport, setShowReport] = useState(false); @@ -104,7 +106,7 @@ export default function ReportDivision() { }, [showReport]); return ( - + { router.back() }} />, @@ -119,7 +121,7 @@ export default function ReportDivision() { ) }} /> - + validationForm("date", val)} diff --git a/app/(application)/division/create.tsx b/app/(application)/division/create.tsx index 7af0eb8..e8ec765 100644 --- a/app/(application)/division/create.tsx +++ b/app/(application)/division/create.tsx @@ -8,6 +8,7 @@ import Styles from "@/constants/Styles"; import { apiCheckDivisionName } from "@/lib/api"; import { setFormCreateDivision } from "@/lib/divisionCreate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -15,6 +16,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function CreateDivision() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const [isSelect, setSelect] = useState(false) const [chooseGroup, setChooseGroup] = useState({ val: "", label: "" }) @@ -99,7 +101,7 @@ export default function CreateDivision() { }, []); return ( - + ( @@ -131,7 +133,7 @@ export default function CreateDivision() { /> { diff --git a/app/(application)/division/create/add-admin-division.tsx b/app/(application)/division/create/add-admin-division.tsx index be97d92..629fadc 100644 --- a/app/(application)/division/create/add-admin-division.tsx +++ b/app/(application)/division/create/add-admin-division.tsx @@ -8,6 +8,7 @@ import { apiCreateDivision } from "@/lib/api"; import { setFormCreateDivision } from "@/lib/divisionCreate"; import { setUpdateDivision } from "@/lib/divisionUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { StackActions, useNavigation } from "@react-navigation/native"; import { router, Stack, useLocalSearchParams } from "expo-router"; @@ -23,6 +24,7 @@ type Props = { } export default function CreateDivisionAddAdmin() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const navigation = useNavigation() const { id } = useLocalSearchParams<{ id: string }>() @@ -104,7 +106,7 @@ export default function CreateDivisionAddAdmin() { ) }} /> - + { data.length > 0 ? @@ -128,7 +130,7 @@ export default function CreateDivisionAddAdmin() { { - selectMember.some((i: any) => i == item.idUser) && + selectMember.some((i: any) => i == item.idUser) && } ) diff --git a/app/(application)/division/create/add-member.tsx b/app/(application)/division/create/add-member.tsx index 8fa7e64..c9d99c8 100644 --- a/app/(application)/division/create/add-member.tsx +++ b/app/(application)/division/create/add-member.tsx @@ -10,6 +10,7 @@ import { apiGetUser } from "@/lib/api"; import { setFormCreateDivision } from "@/lib/divisionCreate"; import { useAuthSession } from "@/providers/AuthProvider"; import { AntDesign } from "@expo/vector-icons"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { Pressable, ScrollView, View } from "react-native"; @@ -22,6 +23,7 @@ type Props = { } export default function CreateDivisionAddMember() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>() const [dataOld, setDataOld] = useState([]) @@ -84,7 +86,7 @@ export default function CreateDivisionAddMember() { ) }} /> - + setSearch(val)} value={search} /> { @@ -134,7 +136,7 @@ export default function CreateDivisionAddMember() { { - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && } ) diff --git a/app/(application)/division/index.tsx b/app/(application)/division/index.tsx index 8bb68b9..c7c9a37 100644 --- a/app/(application)/division/index.tsx +++ b/app/(application)/division/index.tsx @@ -10,6 +10,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetDivision } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather, @@ -38,9 +39,11 @@ export default function ListDivision() { const [isList, setList] = useState(false); const entityUser = useSelector((state: any) => state.user) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [search, setSearch] = useState("") const [nameGroup, setNameGroup] = useState("") const [data, setData] = useState([]) + // ... state same ... const update = useSelector((state: any) => state.divisionUpdate) const arrSkeleton = Array.from({ length: 3 }, (_, index) => index) const [loading, setLoading] = useState(false) @@ -114,11 +117,11 @@ export default function ListDivision() { return ( - + { entityUser.role != "user" && entityUser.role != "coadmin" ? - + } @@ -141,7 +144,7 @@ export default function ListDivision() { icon={ } @@ -149,7 +152,7 @@ export default function ListDivision() { /> : - + } @@ -172,7 +175,7 @@ export default function ListDivision() { icon={ } @@ -190,7 +193,7 @@ export default function ListDivision() { > @@ -232,9 +235,10 @@ export default function ListDivision() { key={index} onPress={() => { router.push(`/division/${item.id}`) }} borderType="bottom" + bgColor={colors.card} icon={ - + } title={item.name} diff --git a/app/(application)/division/report.tsx b/app/(application)/division/report.tsx index 3b2b26a..61399bd 100644 --- a/app/(application)/division/report.tsx +++ b/app/(application)/division/report.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiGetDivisionReport } from "@/lib/api"; import { stringToDate } from "@/lib/fun_stringToDate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import dayjs from "dayjs"; import { router, Stack } from "expo-router"; import { useEffect, useState } from "react"; @@ -16,6 +17,7 @@ import { SafeAreaView, ScrollView, View } from "react-native"; import Toast from "react-native-toast-message"; export default function Report() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const [chooseGroup, setChooseGroup] = useState({ val: "", label: "" }); const [showReport, setShowReport] = useState(false); @@ -122,7 +124,7 @@ export default function Report() { }, [showReport]); return ( - + ( @@ -144,11 +146,11 @@ export default function Report() { /> state.entities) const { token, decryptToken } = useAuthSession() const [errorImg, setErrorImg] = useState(false) + // ... keeping state same ... const [selectedImage, setSelectedImage] = useState(undefined); const [choosePosition, setChoosePosition] = useState({ val: entities.idPosition, label: entities.position }); const [chooseGender, setChooseGender] = useState({ val: entities.gender, label: entities.gender == "F" ? 'Perempuan' : 'Laki-laki' }); @@ -213,7 +216,7 @@ export default function EditProfile() { }; return ( - + ( diff --git a/app/(application)/feature.tsx b/app/(application)/feature.tsx index 9813bdb..2ffd15a 100644 --- a/app/(application)/feature.tsx +++ b/app/(application)/feature.tsx @@ -1,6 +1,7 @@ import AppHeader from "@/components/AppHeader"; import { ButtonFiturMenu } from "@/components/buttonFiturMenu"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Entypo, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import { SafeAreaView, View } from "react-native"; @@ -8,9 +9,10 @@ import { useSelector } from "react-redux"; export default function Feature() { const entityUser = useSelector((state: any) => state.user) + const { colors } = useTheme(); return ( - + - } text="Divisi" onPress={() => { router.push('/division?active=true') }} /> - } text="Kegiatan" onPress={() => { router.push('/project?status=0') }} /> - } text="Pengumuman" onPress={() => { router.push('/announcement') }} /> - } text="Diskusi" onPress={() => { router.push('/discussion?active=true') }} /> + } text="Divisi" onPress={() => { router.push('/division?active=true') }} /> + } text="Kegiatan" onPress={() => { router.push('/project?status=0') }} /> + } text="Pengumuman" onPress={() => { router.push('/announcement') }} /> + } text="Diskusi" onPress={() => { router.push('/discussion?active=true') }} /> - } text="Anggota" onPress={() => { router.push('/member') }} /> - } text="Jabatan" onPress={() => { router.push('/position') }} /> + } text="Anggota" onPress={() => { router.push('/member') }} /> + } text="Jabatan" onPress={() => { router.push('/position') }} /> { - entityUser.role == "cosupadmin" && } text="Banner" onPress={() => { router.push('/banner') }} /> + entityUser.role == "cosupadmin" && } text="Banner" onPress={() => { router.push('/banner') }} /> } { (entityUser.role == "supadmin" || entityUser.role == "developer") && <> - } text="Lembaga Desa" onPress={() => { router.push('/group') }} /> - {/* } text="Tema" onPress={() => { }} /> */} - } text="Banner" onPress={() => { router.push('/banner') }} /> + } text="Lembaga Desa" onPress={() => { router.push('/group') }} /> + {/* } text="Tema" onPress={() => { }} /> */} + } text="Banner" onPress={() => { router.push('/banner') }} /> } - {/* { - (entityUser.role == "supadmin" || entityUser.role == "developer") && - - } text="Banner" onPress={() => { router.push('/banner') }} /> - - } */} ) diff --git a/app/(application)/group/index.tsx b/app/(application)/group/index.tsx index 87a563a..f94d6b1 100644 --- a/app/(application)/group/index.tsx +++ b/app/(application)/group/index.tsx @@ -13,6 +13,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteGroup, apiEditGroup, apiGetGroup } from "@/lib/api"; import { setUpdateGroup } from "@/lib/groupSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather, MaterialCommunityIcons } from "@expo/vector-icons"; import { useEffect, useState } from "react"; import { RefreshControl, View, VirtualizedList } from "react-native"; @@ -27,6 +28,7 @@ type Props = { export default function Index() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [isModal, setModal] = useState(false) const [isVisibleEdit, setVisibleEdit] = useState(false) const [data, setData] = useState([]) @@ -127,9 +129,9 @@ export default function Index() { return ( - + - + } /> @@ -198,7 +201,7 @@ export default function Index() { setModal(false)} title={titleChoose}> } + icon={} title={activeChoose ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setModal(false) @@ -210,7 +213,7 @@ export default function Index() { }} /> } + icon={} title="Edit" onPress={() => { setModal(false) @@ -232,6 +235,7 @@ export default function Index() { label="Lembaga Desa" value={titleChoose} error={error.title} + bg={colors.card} errorText="Lembaga Desa tidak boleh kosong & minimal 3 karakter" onChange={(val) => { validationForm(val, 'title') }} /> diff --git a/app/(application)/home.tsx b/app/(application)/home.tsx index 10cce08..785226c 100644 --- a/app/(application)/home.tsx +++ b/app/(application)/home.tsx @@ -12,6 +12,7 @@ import Styles from "@/constants/Styles"; import { apiGetProfile } from "@/lib/api"; import { setEntities } from "@/lib/entitiesSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Stack } from "expo-router"; import { useEffect, useState } from "react"; import { Platform, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; @@ -23,6 +24,7 @@ export default function Home() { const entities = useSelector((state: any) => state.entities) const dispatch = useDispatch() const { token, decryptToken, signOut } = useAuthSession() + const { colors } = useTheme(); const insets = useSafeAreaInsets() const [refreshing, setRefreshing] = useState(false) @@ -47,13 +49,13 @@ export default function Home() { }; return ( - + ( - + {entities.village} @@ -65,19 +67,21 @@ export default function Home() { } showsVerticalScrollIndicator={false} + style={{ backgroundColor: colors.background }} > - + - - - - - - + + + + + + diff --git a/app/(application)/member/[id].tsx b/app/(application)/member/[id].tsx index 50dc13f..2844c89 100644 --- a/app/(application)/member/[id].tsx +++ b/app/(application)/member/[id].tsx @@ -10,6 +10,7 @@ import { ConstEnv } from "@/constants/ConstEnv"; import { valueRoleUser } from "@/constants/RoleUser"; import Styles from "@/constants/Styles"; import { apiGetProfile } from "@/lib/api"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import React, { useEffect, useState } from "react"; import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; @@ -33,6 +34,7 @@ type Props = { export default function MemberDetail() { const { id } = useLocalSearchParams<{ id: string }>(); + const { colors } = useTheme(); const [data, setData] = useState() const [errorImg, setErrorImg] = useState(false) const entityUser = useSelector((state: any) => state.user) @@ -74,13 +76,11 @@ export default function MemberDetail() { }; return ( - + { router.back() }} />, headerTitle: 'Anggota', headerTitleAlign: 'center', - // headerRight: () => (entityUser.role != "user") && isEdit ? : <>, header: () => ( } > @@ -122,7 +123,7 @@ export default function MemberDetail() { - Informasi + Informasi state.memberUpdate) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [valSelect, setValSelect] = useState<"group" | "position" | "role" | "gender">("group"); const [chooseGroup, setChooseGroup] = useState({ val: "", label: "" }); const [choosePosition, setChoosePosition] = useState({ val: "", label: "" }); @@ -206,25 +208,11 @@ export default function CreateMember() { }; return ( - + ( - // { - // router.back(); - // }} - // /> - // ), headerTitle: "Tambah Anggota", headerTitleAlign: "center", - // headerRight: () => ( - // { handleCreate() }} - // /> - // ), header: () => ( @@ -271,6 +259,7 @@ export default function CreateMember() { placeholder="Pilih Lembaga Desa" value={chooseGroup.label} required + bg={colors.card} onPress={() => { setValChoose(chooseGroup.val); setValSelect("group"); @@ -285,6 +274,7 @@ export default function CreateMember() { placeholder="Pilih Jabatan" value={choosePosition.label} required + bg={colors.card} onPress={() => { setValChoose(choosePosition.val); setValSelect("position"); @@ -298,6 +288,7 @@ export default function CreateMember() { placeholder="Pilih Role" value={chooseRole.label} required + bg={colors.card} onPress={() => { setValChoose(chooseRole.val); setValSelect("role"); @@ -311,6 +302,7 @@ export default function CreateMember() { type="numeric" placeholder="NIK" required + bg={colors.card} error={error.nik} errorText="NIK Harus 16 Karakter" onChange={val => { @@ -322,6 +314,7 @@ export default function CreateMember() { type="default" placeholder="Nama" required + bg={colors.card} error={error.name} errorText="Nama harus 3–50 karakter (huruf, angka, spasi, dan simbol ringan (. , ' _ -))" onChange={val => { @@ -333,6 +326,7 @@ export default function CreateMember() { type="default" placeholder="Email" required + bg={colors.card} error={error.email} errorText="Email tidak valid" onChange={val => { @@ -344,7 +338,8 @@ export default function CreateMember() { type="numeric" placeholder="8XX-XXX-XXX" required - itemLeft={+62} + bg={colors.card} + itemLeft={+62} error={error.phone} errorText="Nomor Telepon tidak valid" onChange={val => { @@ -356,6 +351,7 @@ export default function CreateMember() { placeholder="Pilih Jenis Kelamin" value={chooseGender.label} required + bg={colors.card} onPress={() => { setValChoose(chooseGender.val); setValSelect("gender"); diff --git a/app/(application)/member/edit/[id].tsx b/app/(application)/member/edit/[id].tsx index 0fb0c07..c2795f4 100644 --- a/app/(application)/member/edit/[id].tsx +++ b/app/(application)/member/edit/[id].tsx @@ -10,6 +10,7 @@ import { apiEditUser, apiGetProfile } from "@/lib/api"; import { validateName } from "@/lib/fun_validateName"; import { setUpdateMember } from "@/lib/memberSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import { useHeaderHeight } from '@react-navigation/elements'; import * as ImagePicker from "expo-image-picker"; @@ -47,6 +48,7 @@ export default function EditMember() { const update = useSelector((state: any) => state.memberUpdate) const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>(); + const { colors } = useTheme(); const [errorImg, setErrorImg] = useState(false) const [selectedImage, setSelectedImage] = useState(undefined); const [choosePosition, setChoosePosition] = useState({ val: "", label: "" }); @@ -236,27 +238,11 @@ export default function EditMember() { }; return ( - + ( - // { - // router.back(); - // }} - // /> - // ), headerTitle: "Edit Anggota", headerTitleAlign: "center", - // headerRight: () => ( - // { - // handleEdit() - // }} - // /> - // ), header: () => ( @@ -325,6 +311,7 @@ export default function EditMember() { placeholder="Pilih Jabatan" value={choosePosition.label} required + bg={colors.card} onPress={() => { setValChoose(choosePosition.val); setValSelect("position"); @@ -338,6 +325,7 @@ export default function EditMember() { placeholder="Pilih Role" value={chooseRole.label} required + bg={colors.card} onPress={() => { setValChoose(chooseRole.val); setValSelect("role"); @@ -352,6 +340,7 @@ export default function EditMember() { placeholder="NIK" required value={data?.nik} + bg={colors.card} error={error.nik} errorText="NIK Harus 16 Karakter" onChange={val => { @@ -364,6 +353,7 @@ export default function EditMember() { placeholder="Nama" required value={data?.name} + bg={colors.card} error={error.name} errorText="Nama harus 3–50 karakter (huruf, angka, spasi, dan simbol ringan (. , ' _ -))" onChange={val => { @@ -376,6 +366,7 @@ export default function EditMember() { placeholder="Email" required value={data?.email} + bg={colors.card} error={error.email} errorText="Email tidak valid" onChange={val => { @@ -387,8 +378,9 @@ export default function EditMember() { type="numeric" placeholder="8XX-XXX-XXX" required - itemLeft={+62} + itemLeft={+62} value={data?.phone} + bg={colors.card} error={error.phone} errorText="Nomor Telepon tidak valid" onChange={val => { @@ -400,6 +392,7 @@ export default function EditMember() { placeholder="Pilih Jenis Kelamin" value={chooseGender.label} required + bg={colors.card} onPress={() => { setValChoose(chooseGender.val); setValSelect("gender"); diff --git a/app/(application)/member/index.tsx b/app/(application)/member/index.tsx index 85a9156..b7573ef 100644 --- a/app/(application)/member/index.tsx +++ b/app/(application)/member/index.tsx @@ -9,6 +9,7 @@ import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { apiGetUser } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -33,6 +34,7 @@ export default function Index() { const { active, group } = useLocalSearchParams<{ active?: string, group?: string }>() const { token, decryptToken } = useAuthSession() const entityUser = useSelector((state: any) => state.user) + const { colors } = useTheme(); const [search, setSearch] = useState('') const [nameGroup, setNameGroup] = useState('') const [data, setData] = useState([]) @@ -104,22 +106,22 @@ export default function Index() { }); return ( - + - + { setStatus("true") }} label="Aktif" - icon={} + icon={} n={2} /> { setStatus("false") }} label="Tidak Aktif" - icon={} + icon={} n={2} /> @@ -168,6 +170,7 @@ export default function Index() { } /> diff --git a/app/(application)/notification.tsx b/app/(application)/notification.tsx index 0722e26..736916e 100644 --- a/app/(application)/notification.tsx +++ b/app/(application)/notification.tsx @@ -7,6 +7,7 @@ import { apiGetNotification, apiReadOneNotification } from "@/lib/api"; import { setUpdateNotification } from "@/lib/notificationSlice"; import { pushToPage } from "@/lib/pushToPage"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather } from "@expo/vector-icons"; import { useEffect, useState } from "react"; import { RefreshControl, SafeAreaView, View, VirtualizedList } from "react-native"; @@ -24,6 +25,7 @@ type Props = { export default function Notification() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [loading, setLoading] = useState(false) const [data, setData] = useState([]) const [page, setPage] = useState(1) @@ -97,7 +99,7 @@ export default function Notification() { }; return ( - + { loading ? @@ -124,7 +126,7 @@ export default function Notification() { title={item.title} rightTopInfo={item.createdAt} desc={item.desc} - textColor={item.isRead ? 'gray' : 'black'} + textColor={item.isRead ? 'gray' : colors.text} onPress={() => { handleReadNotification(item.id, item.category, item.idContent) @@ -140,6 +142,7 @@ export default function Notification() { } /> diff --git a/app/(application)/position/index.tsx b/app/(application)/position/index.tsx index f9d303c..d80fb0c 100644 --- a/app/(application)/position/index.tsx +++ b/app/(application)/position/index.tsx @@ -14,6 +14,7 @@ import Styles from "@/constants/Styles"; import { apiDeletePosition, apiEditPosition, apiGetPosition } from "@/lib/api"; import { setUpdatePosition } from "@/lib/positionSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Feather, MaterialCommunityIcons } from "@expo/vector-icons"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -33,6 +34,7 @@ export default function Index() { const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) const [loading, setLoading] = useState(true) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme() const [status, setStatus] = useState<'true' | 'false'>('true') const entityUser = useSelector((state: any) => state.user) const { active, group } = useLocalSearchParams<{ active?: string, group?: string }>() @@ -146,9 +148,9 @@ export default function Index() { }); return ( - + - + } /> @@ -222,7 +225,7 @@ export default function Index() { setModal(false)} title={chooseData.name}> } + icon={} title={chooseData.active ? 'Non Aktifkan' : "Aktifkan"} onPress={() => { setModal(false) @@ -234,7 +237,7 @@ export default function Index() { }} /> } + icon={} title="Edit" onPress={() => { setModal(false) @@ -255,6 +258,7 @@ export default function Index() { placeholder="Nama Jabatan" required label="Jabatan" + bg={colors.card} value={chooseData.name} onChange={(val) => { validationForm(val) }} error={error.name} diff --git a/app/(application)/profile.tsx b/app/(application)/profile.tsx index ba70df2..537054d 100644 --- a/app/(application)/profile.tsx +++ b/app/(application)/profile.tsx @@ -7,22 +7,40 @@ import { assetUserImage } from "@/constants/AssetsError"; import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { useAuthSession } from "@/providers/AuthProvider"; -import { AntDesign } from "@expo/vector-icons"; +import { useTheme } from "@/providers/ThemeProvider"; +import { AntDesign, Ionicons } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import { useState } from "react"; -import { Image, Pressable, SafeAreaView, ScrollView, View } from "react-native"; +import { Image, Modal, Pressable, SafeAreaView, ScrollView, TouchableOpacity, View } from "react-native"; import ImageViewing from 'react-native-image-viewing'; import { useSelector } from 'react-redux'; export default function Profile() { const { signOut } = useAuthSession() + const { theme, setTheme, colors } = useTheme(); const entities = useSelector((state: any) => state.entities) const [error, setError] = useState(false) const [preview, setPreview] = useState(false) + const [showThemeModal, setShowThemeModal] = useState(false) + const ThemeOption = ({ label, value, icon }: { label: string, value: 'light' | 'dark' | 'system', icon: string }) => ( + { + setTheme(value); + setShowThemeModal(false); + }} + > + + + {label} + + {theme === value && } + + ); return ( - + ) - // headerRight: () => } - // onPress={() => { - // AlertKonfirmasi({ - // title: 'Keluar', - // desc: 'Apakah anda yakin ingin keluar?', - // onPress: () => { signOut() } - // }) - // }} - // /> }} /> - + - + setPreview(true)}> {entities.role} - - Informasi + + Tampilan + + + setShowThemeModal(true)} + style={[Styles.wrapItemBorderAll, { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', borderColor: colors.icon + '40', backgroundColor: colors.background }]} + > + + + Tema Aplikasi + + + + {theme === 'light' ? 'Terang' : theme === 'dark' ? 'Gelap' : 'Sistem'} + + + + + + + Informasi { entities.idUserRole != "developer" && { router.push('/edit-profile') }} style={[Styles.textLink]}>Edit } + {/* Note: ItemDetailMember might need updates to support dynamic colors if it uses default text colors */} @@ -87,6 +116,30 @@ export default function Profile() { + + setShowThemeModal(false)} + > + setShowThemeModal(false)}> + + + Pilih Tema + setShowThemeModal(false)}> + + + + + + + + + + + + () const [fileForm, setFileForm] = useState([]) const [listFile, setListFile] = useState([]) @@ -127,7 +129,7 @@ export default function ProjectAddFile() { return ( - + { router.back() }} />, @@ -153,20 +155,20 @@ export default function ProjectAddFile() { ) }} /> - + { listFile.length > 0 && ( File - + { listFile.map((item, index) => ( } + icon={} title={item} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModal(true) }} @@ -188,7 +190,7 @@ export default function ProjectAddFile() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/project/[id]/add-member.tsx b/app/(application)/project/[id]/add-member.tsx index bc5fd29..a47fa35 100644 --- a/app/(application)/project/[id]/add-member.tsx +++ b/app/(application)/project/[id]/add-member.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiAddMemberProject, apiGetProjectOne, apiGetUser } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberProject() { + const { colors } = useTheme(); const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) const { token, decryptToken } = useAuthSession() @@ -127,7 +129,7 @@ export default function AddMemberProject() { ) }} /> - + handleSearch(val)} value={search} /> { selectMember.length > 0 @@ -152,7 +154,7 @@ export default function AddMemberProject() { } { data.length > 0 ? @@ -178,7 +180,7 @@ export default function AddMemberProject() { { - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && } ) diff --git a/app/(application)/project/[id]/add-task.tsx b/app/(application)/project/[id]/add-task.tsx index 1ae7937..921fa58 100644 --- a/app/(application)/project/[id]/add-task.tsx +++ b/app/(application)/project/[id]/add-task.tsx @@ -9,6 +9,7 @@ import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import 'intl'; @@ -30,6 +31,7 @@ import DateTimePicker, { import { useDispatch, useSelector } from "react-redux"; export default function ProjectAddTask() { + const { colors } = useTheme(); const headerHeight = useHeaderHeight(); const { token, decryptToken } = useAuthSession() const dispatch = useDispatch() @@ -133,7 +135,7 @@ export default function ProjectAddTask() { } return ( - + ( @@ -158,11 +160,11 @@ export default function ProjectAddTask() { showBack={true} onPressLeft={() => router.back()} right={ - { handleCreate() }} - /> + { handleCreate() }} + /> } /> ) @@ -172,9 +174,9 @@ export default function ProjectAddTask() { behavior={Platform.OS === 'ios' ? 'padding' : undefined} keyboardVerticalOffset={headerHeight} > - + - + @@ -200,7 +202,7 @@ export default function ProjectAddTask() { Tanggal Mulai * - + {from} @@ -208,7 +210,7 @@ export default function ProjectAddTask() { Tanggal Berakhir * - + {to} @@ -229,7 +231,7 @@ export default function ProjectAddTask() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/project/[id]/cancel.tsx b/app/(application)/project/[id]/cancel.tsx index ab2a77f..3b1d458 100644 --- a/app/(application)/project/[id]/cancel.tsx +++ b/app/(application)/project/[id]/cancel.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiCancelProject } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import React, { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function ProjectCancel() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); const dispatch = useDispatch(); @@ -65,7 +67,7 @@ export default function ProjectCancel() { } return ( - + ( @@ -106,7 +108,7 @@ export default function ProjectCancel() { /> onValidation(val)} diff --git a/app/(application)/project/[id]/edit.tsx b/app/(application)/project/[id]/edit.tsx index bff125d..18e09a1 100644 --- a/app/(application)/project/[id]/edit.tsx +++ b/app/(application)/project/[id]/edit.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiEditProject, apiGetProjectOne } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function EditProject() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); const dispatch = useDispatch() @@ -86,7 +88,7 @@ export default function EditProject() { return ( - + ( @@ -121,14 +123,14 @@ export default function EditProject() { ) }} /> - + { onValidation(val) }} error={error} diff --git a/app/(application)/project/[id]/index.tsx b/app/(application)/project/[id]/index.tsx index 0a28781..7fe4a41 100644 --- a/app/(application)/project/[id]/index.tsx +++ b/app/(application)/project/[id]/index.tsx @@ -10,6 +10,7 @@ import SectionProgress from "@/components/sectionProgress"; import Styles from "@/constants/Styles"; import { apiGetProjectOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import React, { useEffect, useState } from "react"; import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; @@ -32,6 +33,7 @@ type Props = { export default function DetailProject() { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>(); const [data, setData] = useState() const [progress, setProgress] = useState(0) @@ -91,7 +93,7 @@ export default function DetailProject() { }; return ( - + { router.back() }} />, @@ -111,10 +113,12 @@ export default function DetailProject() { }} /> } > diff --git a/app/(application)/project/[id]/report.tsx b/app/(application)/project/[id]/report.tsx index f5de565..eaffdfc 100644 --- a/app/(application)/project/[id]/report.tsx +++ b/app/(application)/project/[id]/report.tsx @@ -5,6 +5,7 @@ import Styles from "@/constants/Styles"; import { apiGetProjectOne, apiReportProject } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, ScrollView, View } from "react-native"; @@ -12,6 +13,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function ReportProject() { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); const dispatch = useDispatch() @@ -86,7 +88,7 @@ export default function ReportProject() { return ( - + ( @@ -123,7 +125,7 @@ export default function ReportProject() { /> { onValidation(val) }} error={error} diff --git a/app/(application)/project/create.tsx b/app/(application)/project/create.tsx index 73505c5..29ac193 100644 --- a/app/(application)/project/create.tsx +++ b/app/(application)/project/create.tsx @@ -18,6 +18,7 @@ import { setMemberChoose } from "@/lib/memberChoose"; import { setUpdateProject } from "@/lib/projectUpdate"; import { setTaskCreate } from "@/lib/taskCreate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { router, Stack } from "expo-router"; @@ -31,6 +32,7 @@ import Toast from "react-native-toast-message"; import { useDispatch, useSelector } from "react-redux"; export default function CreateProject() { + const { colors } = useTheme(); const [loading, setLoading] = useState(false) const { token, decryptToken } = useAuthSession(); const [chooseGroup, setChooseGroup] = useState({ val: "", label: "" }); @@ -190,7 +192,7 @@ export default function CreateProject() { return ( - + ( @@ -230,7 +232,7 @@ export default function CreateProject() { /> { @@ -242,6 +244,7 @@ export default function CreateProject() { placeholder="Pilih Lembaga Desa" value={chooseGroup.label} required + bg={colors.card} onPress={() => { setValChoose(chooseGroup.val); setValSelect("group"); @@ -257,6 +260,7 @@ export default function CreateProject() { type="default" placeholder="Nama Kegiatan" required + bg={colors.card} value={dataForm.title} error={error.title} errorText="Nama kegiatan tidak boleh kosong" @@ -294,13 +298,13 @@ export default function CreateProject() { fileForm.length > 0 && ( File - + { fileForm.map((item, index) => ( } + icon={} title={item.name} titleWeight="normal" onPress={() => { setIndexDelFile(index); setModal(true) }} @@ -318,7 +322,7 @@ export default function CreateProject() { Total {entitiesMember.length} Anggota - + {entitiesMember.map( (item: { img: any; name: any }, index: any) => { return ( @@ -344,7 +348,7 @@ export default function CreateProject() { } + icon={} title="Hapus" onPress={() => { deleteFile(indexDelFile) }} /> diff --git a/app/(application)/project/create/member.tsx b/app/(application)/project/create/member.tsx index 444bf10..947afad 100644 --- a/app/(application)/project/create/member.tsx +++ b/app/(application)/project/create/member.tsx @@ -9,6 +9,7 @@ import Styles from "@/constants/Styles"; import { apiGetUser } from "@/lib/api"; import { setMemberChoose } from "@/lib/memberChoose"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import React, { useEffect, useState } from "react"; @@ -23,6 +24,7 @@ type Props = { } export default function AddMemberCreateProject() { + const { colors } = useTheme(); const dispatch = useDispatch() const { token, decryptToken } = useAuthSession() const [data, setData] = useState([]) @@ -103,7 +105,7 @@ export default function AddMemberCreateProject() { ) }} /> - + setSearch(val)} value={search} /> { @@ -129,6 +131,7 @@ export default function AddMemberCreateProject() { } { @@ -149,7 +152,7 @@ export default function AddMemberCreateProject() { { - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && } ) diff --git a/app/(application)/project/create/task.tsx b/app/(application)/project/create/task.tsx index 6fbfad5..5aaad36 100644 --- a/app/(application)/project/create/task.tsx +++ b/app/(application)/project/create/task.tsx @@ -7,6 +7,7 @@ import Styles from "@/constants/Styles"; import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; import { setTaskCreate } from "@/lib/taskCreate"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack } from "expo-router"; import 'intl'; @@ -27,6 +28,7 @@ import DateTimePicker, { import { useDispatch, useSelector } from "react-redux"; export default function CreateProjectAddTask() { + const { colors } = useTheme(); const headerHeight = useHeaderHeight(); const dispatch = useDispatch() const [disable, setDisable] = useState(true); @@ -119,7 +121,7 @@ export default function CreateProjectAddTask() { } return ( - + ( @@ -158,9 +160,9 @@ export default function CreateProjectAddTask() { behavior={Platform.OS === 'ios' ? 'padding' : undefined} keyboardVerticalOffset={headerHeight} > - + - + Tanggal Mulai * - + {from} @@ -194,7 +196,7 @@ export default function CreateProjectAddTask() { Tanggal Berakhir * - + {to} @@ -215,7 +217,7 @@ export default function CreateProjectAddTask() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/project/index.tsx b/app/(application)/project/index.tsx index c6f4feb..d640f8c 100644 --- a/app/(application)/project/index.tsx +++ b/app/(application)/project/index.tsx @@ -11,6 +11,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetProject } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, Ionicons, @@ -40,9 +41,11 @@ export default function ListProject() { }>(); const [statusFix, setStatusFix] = useState<'0' | '1' | '2' | '3'>('0') const { token, decryptToken } = useAuthSession(); + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const [search, setSearch] = useState("") const [nameGroup, setNameGroup] = useState("") + // ... state same ... const [isYear, setYear] = useState("") const [data, setData] = useState([]) const [isList, setList] = useState(false) @@ -122,7 +125,7 @@ export default function ListProject() { }) return ( - + } @@ -147,7 +150,7 @@ export default function ListProject() { icon={ } @@ -161,7 +164,7 @@ export default function ListProject() { icon={ } @@ -175,7 +178,7 @@ export default function ListProject() { icon={ } @@ -191,7 +194,7 @@ export default function ListProject() { > diff --git a/app/(application)/project/update/[detail].tsx b/app/(application)/project/update/[detail].tsx index d955642..0aabbfe 100644 --- a/app/(application)/project/update/[detail].tsx +++ b/app/(application)/project/update/[detail].tsx @@ -9,6 +9,7 @@ import { formatDateOnly } from "@/lib/fun_formatDateOnly"; import { getDatesInRange } from "@/lib/fun_getDatesInRange"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import 'intl'; @@ -21,6 +22,7 @@ import DateTimePicker, { DateType } from "react-native-ui-datepicker"; import { useDispatch, useSelector } from "react-redux"; export default function UpdateProjectTask() { + const { colors } = useTheme(); const headerHeight = useHeaderHeight(); const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) @@ -169,7 +171,7 @@ export default function UpdateProjectTask() { }, [range]) return ( - + { router.back() }} />, @@ -200,9 +202,9 @@ export default function UpdateProjectTask() { behavior={Platform.OS === 'ios' ? 'padding' : undefined} keyboardVerticalOffset={headerHeight} > - + - + { !loading && @@ -217,13 +219,13 @@ export default function UpdateProjectTask() { selected: Styles.selectedDate, selected_label: Styles.cWhite, range_fill: Styles.selectRangeDate, - month_label: Styles.cBlack, - month_selector_label: Styles.cBlack, - year_label: Styles.cBlack, - year_selector_label: Styles.cBlack, - day_label: Styles.cBlack, - time_label: Styles.cBlack, - weekday_label: Styles.cBlack, + month_label: { color: colors.text }, + month_selector_label: { color: colors.text }, + year_label: { color: colors.text }, + year_selector_label: { color: colors.text }, + day_label: { color: colors.text }, + time_label: { color: colors.text }, + weekday_label: { color: colors.text }, }} /> } @@ -233,13 +235,13 @@ export default function UpdateProjectTask() { Tanggal Mulai * - + {from} Tanggal Berakhir * - + {to} @@ -260,7 +262,7 @@ export default function UpdateProjectTask() { type="default" placeholder="Judul Tugas" required - bg="white" + bg={colors.card} value={title} error={error.title} errorText="Judul tidak boleh kosong" diff --git a/app/(application)/search.tsx b/app/(application)/search.tsx index 79f3dba..7bc0e47 100644 --- a/app/(application)/search.tsx +++ b/app/(application)/search.tsx @@ -8,12 +8,14 @@ import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { apiGetSearch } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, MaterialIcons } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import React, { useState } from "react"; import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"; import Toast from "react-native-toast-message"; +// ... types ... type PropsUser = { id: string name: string @@ -43,6 +45,7 @@ export default function Search() { const [dataProject, setDataProject] = useState([]) const [refreshing, setRefreshing] = useState(false) const [search, setSearch] = useState('') + const { colors } = useTheme(); async function handleSearch(cari: string) { try { @@ -79,7 +82,7 @@ export default function Search() { return ( <> - + } > @@ -177,7 +181,7 @@ export default function Search() { : - Tidak ada data + Tidak ada data } diff --git a/app/_layout.tsx b/app/_layout.tsx index 4fb2042..c49bb5e 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,4 +1,5 @@ import AuthProvider from '@/providers/AuthProvider'; +import ThemeProvider from '@/providers/ThemeProvider'; import { useFonts } from 'expo-font'; import { Stack } from 'expo-router'; import * as SplashScreen from 'expo-splash-screen'; @@ -29,14 +30,16 @@ export default function RootLayout() { return ( - - - - - - - - + + + + + + + + + + ); diff --git a/app/verification.tsx b/app/verification.tsx index b074aef..d0290d1 100644 --- a/app/verification.tsx +++ b/app/verification.tsx @@ -3,6 +3,7 @@ import Text from '@/components/Text'; import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import CryptoES from "crypto-es"; import React, { useState } from "react"; import { Image, View } from "react-native"; @@ -15,6 +16,7 @@ export default function Index() { value, setValue, }); + const { colors } = useTheme(); const { signIn } = useAuthSession(); const login = (): void => { @@ -24,7 +26,7 @@ export default function Index() { signIn(encrypted); } return ( - + ( {symbol || (isFocused ? : null)} @@ -61,7 +63,7 @@ export default function Index() { // onPress={() => { router.push("/home") }} onPress={login} /> - + Tidak Menerima kode verifikasi? Kirim Ulang diff --git a/components/Text.tsx b/components/Text.tsx index 1b66f53..789c323 100644 --- a/components/Text.tsx +++ b/components/Text.tsx @@ -1,23 +1,19 @@ +import { useTheme } from '@/providers/ThemeProvider'; import React from 'react'; -import { Text as RNText, TextProps as RNTextProps, StyleSheet } from 'react-native'; +import { StyleSheet, Text as RNText, TextProps as RNTextProps } from 'react-native'; type TextProps = RNTextProps & { children: React.ReactNode; }; const Text: React.FC = ({ style, ...props }) => { + const { colors } = useTheme(); return ( - ); }; -const styles = StyleSheet.create({ - defaultText: { - color: 'black', - }, -}); - export default Text; diff --git a/components/announcement/headerAnnouncementDetail.tsx b/components/announcement/headerAnnouncementDetail.tsx index 38d9649..9a2cc5c 100644 --- a/components/announcement/headerAnnouncementDetail.tsx +++ b/components/announcement/headerAnnouncementDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { setUpdateAnnouncement } from "@/lib/announcementUpdate" import { apiDeleteAnnouncement } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -18,6 +19,7 @@ type Props = { } export default function HeaderRightAnnouncementDetail({ id }: Props) { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const update = useSelector((state: any) => state.announcementUpdate) const dispatch = useDispatch() @@ -46,7 +48,7 @@ export default function HeaderRightAnnouncementDetail({ id }: Props) { } + icon={} title="Edit" onPress={() => { setVisible(false) @@ -54,7 +56,7 @@ export default function HeaderRightAnnouncementDetail({ id }: Props) { }} /> } + icon={} title="Hapus" onPress={() => { setVisible(false) diff --git a/components/announcement/headerAnnouncementList.tsx b/components/announcement/headerAnnouncementList.tsx index 039323d..d67346f 100644 --- a/components/announcement/headerAnnouncementList.tsx +++ b/components/announcement/headerAnnouncementList.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -9,6 +10,7 @@ import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" export default function HeaderRightAnnouncementList() { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const entityUser = useSelector((state: any) => state.user) @@ -21,7 +23,7 @@ export default function HeaderRightAnnouncementList() { } + icon={} title="Tambah Pengumuman" onPress={() => { setVisible(false) diff --git a/components/auth/viewLogin.tsx b/components/auth/viewLogin.tsx index 4bff550..2b9e4f3 100644 --- a/components/auth/viewLogin.tsx +++ b/components/auth/viewLogin.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiCheckPhoneLogin, apiSendOtp } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import AsyncStorage from "@react-native-async-storage/async-storage" import { StatusBar } from "expo-status-bar" import { useState } from "react" @@ -21,6 +22,7 @@ export default function ViewLogin({ onValidate }: Props) { const [disableLogin, setDisableLogin] = useState(true) const [phone, setPhone] = useState('') const { signIn, encryptToken } = useAuthSession(); + const { colors, theme } = useTheme(); const handleCheckPhone = async () => { try { @@ -49,8 +51,8 @@ export default function ViewLogin({ onValidate }: Props) { }; return ( - - + + diff --git a/components/auth/viewVerification.tsx b/components/auth/viewVerification.tsx index a1ae472..fc921a9 100644 --- a/components/auth/viewVerification.tsx +++ b/components/auth/viewVerification.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiSendOtp } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { StatusBar } from "expo-status-bar"; import { useState } from "react"; @@ -20,6 +21,7 @@ export default function ViewVerification({ phone, otp }: Props) { const [value, setValue] = useState(''); const [otpFix, setOtpFix] = useState(otp) const { signIn, encryptToken } = useAuthSession(); + const { colors, theme } = useTheme(); const login = async () => { const valueUser = await AsyncStorage.getItem('user'); @@ -57,9 +59,9 @@ export default function ViewVerification({ phone, otp }: Props) { return ( <> - + - + setValue(text)} - focusColor={'#19345E'} + focusColor={colors.tint} type="numeric" theme={{ containerStyle: { width: '80%', alignSelf: 'center' }, - pinCodeContainerStyle: Styles.verificationCell, - pinCodeTextStyle: { color: 'black' } + pinCodeContainerStyle: { ...Styles.verificationCell, borderColor: colors.icon }, + pinCodeTextStyle: { color: colors.text } }} /> { onCheckOtp() }} /> - + Tidak Menerima kode verifikasi? { resendOtp() }}>Kirim Ulang diff --git a/components/banner/headerBannerList.tsx b/components/banner/headerBannerList.tsx index f8a0594..faea4fa 100644 --- a/components/banner/headerBannerList.tsx +++ b/components/banner/headerBannerList.tsx @@ -1,21 +1,23 @@ -import { useState } from "react"; -import ButtonMenuHeader from "../buttonMenuHeader"; -import DrawerBottom from "../drawerBottom"; -import { View } from "react-native"; import Styles from "@/constants/Styles"; -import MenuItemRow from "../menuItemRow"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import { router } from "expo-router"; +import { useState } from "react"; +import { View } from "react-native"; +import ButtonMenuHeader from "../buttonMenuHeader"; +import DrawerBottom from "../drawerBottom"; +import MenuItemRow from "../menuItemRow"; export default function HeaderRightBannerList() { const [isVisible, setVisible] = useState(false) + const { colors } = useTheme() return ( <> { setVisible(true) }} /> setVisible(false)} title="Menu"> } + icon={} title="Tambah Banner" onPress={() => { setVisible(false) diff --git a/components/borderBottomItem.tsx b/components/borderBottomItem.tsx index 1a15925..aae246a 100644 --- a/components/borderBottomItem.tsx +++ b/components/borderBottomItem.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import React, { useState } from "react"; import { Dimensions, Pressable, View } from "react-native"; import Text from "./Text"; @@ -16,7 +17,7 @@ type Props = { leftBottomInfo?: React.ReactNode | string rightBottomInfo?: React.ReactNode | string titleWeight?: 'normal' | 'bold' - bgColor?: 'white' | 'transparent' + bgColor?: string width?: number descEllipsize?: boolean textColor?: string, @@ -26,8 +27,9 @@ type Props = { export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, width, descEllipsize, textColor, colorPress, titleShowAll }: Props) { const lebarDim = Dimensions.get("window").width; + const { colors } = useTheme(); const lebar = width ? lebarDim * width / 100 : 'auto'; - const textColorFix = textColor ? textColor : 'black'; + const textColorFix = textColor ? textColor : colors.text; const [isTap, setIsTap] = useState(false); @@ -37,11 +39,11 @@ export default function BorderBottomItem({ title, subtitle, icon, desc, onPress, onPressOut={() => setIsTap(false)} style={({ pressed }) => [ borderType == 'bottom' - ? Styles.wrapItemBorderBottom + ? [Styles.wrapItemBorderBottom, { borderBottomColor: colors.icon }] : borderType == 'all' - ? Styles.wrapItemBorderAll + ? [Styles.wrapItemBorderAll, { borderColor: colors.icon }] : Styles.wrapItemBorderNone, - bgColor && bgColor == 'white' && ColorsStatus.white, + { backgroundColor: bgColor }, // efek warna saat ditekan (sementara) isTap && colorPress && ColorsStatus.pressedGray, ]} diff --git a/components/borderBottomItem2.tsx b/components/borderBottomItem2.tsx index 441d2bf..31e91b9 100644 --- a/components/borderBottomItem2.tsx +++ b/components/borderBottomItem2.tsx @@ -2,6 +2,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import { ConstEnv } from "@/constants/ConstEnv"; import { isImageFile } from "@/constants/FileExtensions"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; @@ -45,9 +46,10 @@ type PropsFile = { export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress, onLongPress, rightTopInfo, borderType, leftBottomInfo, rightBottomInfo, titleWeight, bgColor, width, descEllipsize, textColor, colorPress, titleShowAll, dataFile }: Props) { + const { colors } = useTheme(); const lebarDim = Dimensions.get("window").width; const lebar = width ? lebarDim * width / 100 : 'auto'; - const textColorFix = textColor ? textColor : 'black'; + const textColorFix = textColor ? textColor : colors.text; const [isTap, setIsTap] = useState(false); const [loadingOpen, setLoadingOpen] = useState(false) const [chooseFile, setChooseFile] = useState() @@ -115,11 +117,11 @@ export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress onPressOut={() => setIsTap(false)} style={({ pressed }) => [ borderType == 'bottom' - ? Styles.wrapItemBorderBottom + ? [Styles.wrapItemBorderBottom, { borderBottomColor: colors.icon }] : borderType == 'all' - ? Styles.wrapItemBorderAll + ? [Styles.wrapItemBorderAll, { borderColor: colors.icon }] : Styles.wrapItemBorderNone, - bgColor && bgColor == 'white' && ColorsStatus.white, + bgColor && bgColor == 'white' && { backgroundColor: colors.card }, // efek warna saat ditekan (sementara) isTap && colorPress && ColorsStatus.pressedGray, ]} @@ -151,7 +153,7 @@ export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress {dataFile.map((item, index) => ( { isImageFile(item.extension) ? handleChooseFile(item) @@ -161,7 +163,7 @@ export default function BorderBottomItem2({ title, subtitle, icon, desc, onPress + color={colors.icon} /> {item.name}.{item.extension} ))} diff --git a/components/buttonFiturMenu.tsx b/components/buttonFiturMenu.tsx index d772fa2..3687b68 100644 --- a/components/buttonFiturMenu.tsx +++ b/components/buttonFiturMenu.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import React from "react"; import { TouchableWithoutFeedback, View } from "react-native"; import Text from "./Text"; @@ -10,10 +11,11 @@ type Props = { }; export function ButtonFiturMenu({ onPress, icon, text }: Props) { + const { colors } = useTheme(); return ( - + {icon} {text} diff --git a/components/buttonSelect.tsx b/components/buttonSelect.tsx index 8bca73f..16d5a9f 100644 --- a/components/buttonSelect.tsx +++ b/components/buttonSelect.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather } from "@expo/vector-icons"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -12,12 +13,20 @@ type Props = { } export default function ButtonSelect({ value, onPress, round, error, errorText }: Props) { + const { colors } = useTheme(); return ( - - - {value} + + + {value} {error && ({errorText})} diff --git a/components/buttonTab.tsx b/components/buttonTab.tsx index b5449a9..746a7a4 100644 --- a/components/buttonTab.tsx +++ b/components/buttonTab.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus" import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider"; import { TouchableOpacity } from "react-native" import Text from "./Text"; @@ -14,10 +15,11 @@ type Props = { export default function ButtonTab({ active, value, onPress, label, n, icon }: Props) { + const { colors } = useTheme(); return ( { onPress() }}> {icon} - {label} + {label} ) } \ No newline at end of file diff --git a/components/calendar/headerCalendarDetail.tsx b/components/calendar/headerCalendarDetail.tsx index 2f694ed..8f88661 100644 --- a/components/calendar/headerCalendarDetail.tsx +++ b/components/calendar/headerCalendarDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiDeleteCalendar } from "@/lib/api" import { setUpdateCalendar } from "@/lib/calendarUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -19,6 +20,7 @@ type Props = { } export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() const update = useSelector((state: any) => state.calendarUpdate) @@ -49,7 +51,7 @@ export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { } + icon={} title="Tambah Anggota" onPress={() => { setVisible(false) @@ -57,7 +59,7 @@ export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { }} /> } + icon={} title="Edit" onPress={() => { setVisible(false) @@ -65,7 +67,7 @@ export default function HeaderRightCalendarDetail({ id, idReminder }: Props) { }} /> } + icon={} title="Hapus" onPress={() => { setVisible(false) diff --git a/components/calendar/headerCalendarList.tsx b/components/calendar/headerCalendarList.tsx index 3547e7b..daaabf9 100644 --- a/components/calendar/headerCalendarList.tsx +++ b/components/calendar/headerCalendarList.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiGetDivisionOneFeature } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, MaterialCommunityIcons } from "@expo/vector-icons" import { router, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" @@ -11,6 +12,7 @@ import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" export default function HeaderRightCalendarList() { + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>(); @@ -47,7 +49,7 @@ export default function HeaderRightCalendarList() { <> ) : ( } + icon={} title="Tambah Acara" onPress={() => { setVisible(false) @@ -57,7 +59,7 @@ export default function HeaderRightCalendarList() { ) } } + icon={} title="Riwayat" onPress={() => { setVisible(false) diff --git a/components/calendar/itemDateCalendar.tsx b/components/calendar/itemDateCalendar.tsx index 193b7e9..a932783 100644 --- a/components/calendar/itemDateCalendar.tsx +++ b/components/calendar/itemDateCalendar.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Pressable, View } from "react-native"; import Text from "../Text"; @@ -11,10 +12,11 @@ type Props = { export default function ItemDateCalendar({ text, isSelected, isSign, onPress }: Props) { + const { colors } = useTheme() return ( <> - {text} + {text} diff --git a/components/calendar/itemHistoryEvent.tsx b/components/calendar/itemHistoryEvent.tsx index 8c95ba8..b4e9248 100644 --- a/components/calendar/itemHistoryEvent.tsx +++ b/components/calendar/itemHistoryEvent.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { View } from "react-native"; import Text from "../Text"; @@ -14,12 +15,13 @@ type Props = { }[] export default function ItemHistoryEvent({ data }: { data: Props }) { + const { colors, activeTheme } = useTheme() return ( <> { data.length > 0 ? ( data.map((item, index) => ( - + {String(item.dateStart)} {item.year} diff --git a/components/discussion/headerDiscussionDetail.tsx b/components/discussion/headerDiscussionDetail.tsx index b2e4e4e..e25af32 100644 --- a/components/discussion/headerDiscussionDetail.tsx +++ b/components/discussion/headerDiscussionDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiArchiveDiscussion, apiOpenCloseDiscussion } from "@/lib/api" import { setUpdateDiscussion } from "@/lib/discussionUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -20,6 +21,7 @@ type Props = { } export default function HeaderRightDiscussionDetail({ id, status, isActive }: Props) { + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() const update = useSelector((state: any) => state.discussionUpdate) @@ -72,7 +74,7 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr isActive && <> } + icon={} title="Edit" onPress={() => { setVisible(false) @@ -80,7 +82,7 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr }} /> } + icon={} title={status == 1 ? 'Tutup Diskusi' : 'Buka Diskusi'} onPress={() => { setVisible(false) @@ -96,7 +98,7 @@ export default function HeaderRightDiscussionDetail({ id, status, isActive }: Pr } } + icon={} title={isActive ? 'Arsipkan' : 'Aktifkan Diskusi'} onPress={() => { setVisible(false) diff --git a/components/discussion/headerDiscussionList.tsx b/components/discussion/headerDiscussionList.tsx index 54b876f..d450bb3 100644 --- a/components/discussion/headerDiscussionList.tsx +++ b/components/discussion/headerDiscussionList.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiGetDivisionOneFeature } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" @@ -11,6 +12,7 @@ import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" export default function HeaderRightDiscussionList() { + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const [isAdminDivision, setIsAdminDivision] = useState(false); const { token, decryptToken } = useAuthSession() @@ -45,7 +47,7 @@ export default function HeaderRightDiscussionList() { } + icon={} title="Tambah Diskusi" onPress={() => { setVisible(false) diff --git a/components/discussionItem.tsx b/components/discussionItem.tsx index 8a9efdc..1b6fc3b 100644 --- a/components/discussionItem.tsx +++ b/components/discussionItem.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, Ionicons } from "@expo/vector-icons"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -11,21 +12,22 @@ type Props = { } export default function DiscussionItem({ title, user, date, onPress }: Props) { + const { colors } = useTheme(); return ( - + - + {title} - + {user} - + {date} diff --git a/components/discussion_general/headerDiscussionDetail.tsx b/components/discussion_general/headerDiscussionDetail.tsx index e546387..9a8c128 100644 --- a/components/discussion_general/headerDiscussionDetail.tsx +++ b/components/discussion_general/headerDiscussionDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiDeleteDiscussionGeneral, apiUpdateStatusDiscussionGeneral } from "@/lib/api" import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -21,6 +22,7 @@ type Props = { export default function HeaderRightDiscussionGeneralDetail({ id, active, status }: Props) { const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const entityUser = useSelector((state: any) => state.user) const dispatch = useDispatch() @@ -59,7 +61,7 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status } + icon={} title="Anggota" onPress={() => { setVisible(false) @@ -74,7 +76,7 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status ( <> } + icon={} title="Edit" onPress={() => { setVisible(false) @@ -82,7 +84,7 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status }} /> } + icon={} title={status == 1 ? 'Tutup Diskusi' : 'Buka Diskusi'} onPress={() => { setVisible(false) @@ -99,7 +101,7 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status ) : } + icon={} title="Aktifkan Diskusi" onPress={() => { setVisible(false) @@ -119,7 +121,7 @@ export default function HeaderRightDiscussionGeneralDetail({ id, active, status entityUser.role != "user" && entityUser.role != "coadmin" && active && } + icon={} title="Arsipkan" onPress={() => { setVisible(false) diff --git a/components/discussion_general/headerDiscussionGeneral.tsx b/components/discussion_general/headerDiscussionGeneral.tsx index 8b8a88d..adc554e 100644 --- a/components/discussion_general/headerDiscussionGeneral.tsx +++ b/components/discussion_general/headerDiscussionGeneral.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -10,6 +11,7 @@ import MenuItemRow from "../menuItemRow" import ModalFilter from "../modalFilter" export default function HeaderDiscussionGeneral() { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const [isFilter, setFilter] = useState(false) const entityUser = useSelector((state: any) => state.user) @@ -23,7 +25,7 @@ export default function HeaderDiscussionGeneral() { } + icon={} title="Tambah Diskusi" onPress={() => { setVisible(false) @@ -33,7 +35,7 @@ export default function HeaderDiscussionGeneral() { { (entityUser.role == 'supadmin' || entityUser.role == 'developer') && } + icon={} title="Filter" onPress={() => { setVisible(false) diff --git a/components/division/discussionDivisionDetail.tsx b/components/division/discussionDivisionDetail.tsx index 9531cbe..4ddfe96 100644 --- a/components/division/discussionDivisionDetail.tsx +++ b/components/division/discussionDivisionDetail.tsx @@ -7,6 +7,7 @@ import { View } from "react-native"; import Text from "../Text"; import DiscussionItem from "../discussionItem"; import Skeleton from "../skeleton"; +import { useTheme } from "@/providers/ThemeProvider"; type Props = { id: string; @@ -17,6 +18,7 @@ type Props = { }; export default function DiscussionDivisionDetail({ refreshing }: { refreshing: boolean }) { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); const [data, setData] = useState([]); @@ -48,11 +50,11 @@ export default function DiscussionDivisionDetail({ refreshing }: { refreshing: b handleLoad(true) }, []) - + return ( Diskusi - + { loading ? diff --git a/components/division/fileDivisionDetail.tsx b/components/division/fileDivisionDetail.tsx index a6825d6..781cc97 100644 --- a/components/division/fileDivisionDetail.tsx +++ b/components/division/fileDivisionDetail.tsx @@ -13,6 +13,7 @@ import * as mime from 'react-native-mime-types'; import { ICarouselInstance } from "react-native-reanimated-carousel"; import ModalLoading from "../modalLoading"; import Skeleton from "../skeleton"; +import { useTheme } from "@/providers/ThemeProvider"; import Text from "../Text"; type Props = { @@ -25,6 +26,7 @@ type Props = { } export default function FileDivisionDetail({ refreshing }: { refreshing: boolean }) { + const { colors } = useTheme(); const ref = React.useRef(null); const width = Dimensions.get("window").width; const [data, setData] = useState([]) diff --git a/components/division/fiturDivisionDetail.tsx b/components/division/fiturDivisionDetail.tsx index 9a2e2eb..6c4e287 100644 --- a/components/division/fiturDivisionDetail.tsx +++ b/components/division/fiturDivisionDetail.tsx @@ -7,6 +7,7 @@ import { router, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" import { View } from "react-native" import BorderBottomItem from "../borderBottomItem" +import { useTheme } from "@/providers/ThemeProvider" import Text from "../Text" type Props = { @@ -17,6 +18,7 @@ type Props = { } export default function FiturDivisionDetail({ refreshing }: { refreshing: boolean }) { + const { colors } = useTheme(); const { token, decryptToken } = useAuthSession() const { id } = useLocalSearchParams<{ id: string }>() const [data, setData] = useState({ @@ -51,11 +53,11 @@ export default function FiturDivisionDetail({ refreshing }: { refreshing: boolea - + } title="Tugas" @@ -65,11 +67,11 @@ export default function FiturDivisionDetail({ refreshing }: { refreshing: boolea /> - + } title="Dokumen" @@ -81,11 +83,11 @@ export default function FiturDivisionDetail({ refreshing }: { refreshing: boolea - + } title="Diskusi" @@ -95,11 +97,11 @@ export default function FiturDivisionDetail({ refreshing }: { refreshing: boolea /> - + } title="Kalender" diff --git a/components/division/headerDivisionDetail.tsx b/components/division/headerDivisionDetail.tsx index 5b3334d..4b41a9f 100644 --- a/components/division/headerDivisionDetail.tsx +++ b/components/division/headerDivisionDetail.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { MaterialCommunityIcons } from "@expo/vector-icons" import { useState } from "react" import { View } from "react-native" @@ -12,6 +13,7 @@ type Props = { } export default function HeaderRightDivisionDetail({ id }: Props) { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) return ( @@ -20,7 +22,7 @@ export default function HeaderRightDivisionDetail({ id }: Props) { } + icon={} title="Informasi Divisi" onPress={() => { setVisible(false) @@ -28,7 +30,7 @@ export default function HeaderRightDivisionDetail({ id }: Props) { }} /> } + icon={} title="Laporan Divisi" onPress={() => { setVisible(false) diff --git a/components/division/headerDivisionInfo.tsx b/components/division/headerDivisionInfo.tsx index d7f44e5..6112fac 100644 --- a/components/division/headerDivisionInfo.tsx +++ b/components/division/headerDivisionInfo.tsx @@ -12,6 +12,7 @@ import AlertKonfirmasi from "../alertKonfirmasi" import ButtonMenuHeader from "../buttonMenuHeader" import DrawerBottom from "../drawerBottom" import MenuItemRow from "../menuItemRow" +import { useTheme } from "@/providers/ThemeProvider" type Props = { id: string | string[] @@ -19,6 +20,7 @@ type Props = { } export default function HeaderRightDivisionInfo({ id, active }: Props) { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const { token, decryptToken } = useAuthSession() const update = useSelector((state: any) => state.divisionUpdate) @@ -48,7 +50,7 @@ export default function HeaderRightDivisionInfo({ id, active }: Props) { } + icon={} title="Edit Divisi" onPress={() => { setVisible(false) @@ -56,7 +58,7 @@ export default function HeaderRightDivisionInfo({ id, active }: Props) { }} /> } + icon={} title={active ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setVisible(false) diff --git a/components/division/headerDivisionList.tsx b/components/division/headerDivisionList.tsx index 8a6147f..6d269ce 100644 --- a/components/division/headerDivisionList.tsx +++ b/components/division/headerDivisionList.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, MaterialCommunityIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -10,6 +11,7 @@ import MenuItemRow from "../menuItemRow" import ModalFilter from "../modalFilter" export default function HeaderRightDivisionList() { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const [isFilter, setFilter] = useState(false) const entityUser = useSelector((state: any) => state.user) @@ -23,7 +25,7 @@ export default function HeaderRightDivisionList() { } + icon={} title="Tambah Divisi" onPress={() => { setVisible(false) @@ -31,9 +33,9 @@ export default function HeaderRightDivisionList() { }} /> { - (entityUser.role == "supadmin" || entityUser.role == "developer") && + (entityUser.role == "userRole" || entityUser.role == "developer") && } + icon={} title="Filter" onPress={() => { setVisible(false) @@ -47,7 +49,7 @@ export default function HeaderRightDivisionList() { { (entityUser.role == "supadmin" || entityUser.role == "developer" || entityUser.role == "cosupadmin") && } + icon={} title="Laporan" onPress={() => { setVisible(false) diff --git a/components/division/reportChartDocument.tsx b/components/division/reportChartDocument.tsx index 7109ca5..865bf5f 100644 --- a/components/division/reportChartDocument.tsx +++ b/components/division/reportChartDocument.tsx @@ -1,9 +1,11 @@ import Styles from "@/constants/Styles"; import { Dimensions, View } from "react-native"; import { BarChart } from "react-native-gifted-charts"; +import { useTheme } from "@/providers/ThemeProvider"; import Text from "../Text"; export default function ReportChartDocument({ data }: { data: { label: string; value: number; }[] }) { + const { colors } = useTheme(); const maxValue = Math.max(...data.map(i => i.value)) const barData = [ { value: 23, label: 'Gambar', }, @@ -12,9 +14,11 @@ export default function ReportChartDocument({ data }: { data: { label: string; v const width = Dimensions.get("window").width; return ( - + JUMLAH DOKUMEN - {item.value} + {item.value} ); }} diff --git a/components/division/reportChartEvent.tsx b/components/division/reportChartEvent.tsx index 25beb34..ec3398e 100644 --- a/components/division/reportChartEvent.tsx +++ b/components/division/reportChartEvent.tsx @@ -1,9 +1,11 @@ import Styles from "@/constants/Styles"; import { Dimensions, View } from "react-native"; import { BarChart } from "react-native-gifted-charts"; +import { useTheme } from "@/providers/ThemeProvider"; import Text from "../Text"; export default function ReportChartEvent({ data }: { data: { label: string; value: number; }[] }) { + const { colors } = useTheme(); const width = Dimensions.get("window").width; const maxValue = Math.max(...data.map(i => i.value)) const barData = [ @@ -12,9 +14,11 @@ export default function ReportChartEvent({ data }: { data: { label: string; valu ]; return ( - + ACARA DIVISI - {item.value} + {item.value} ); }} diff --git a/components/division/reportChartProgress.tsx b/components/division/reportChartProgress.tsx index 8fbeed1..2e5d128 100644 --- a/components/division/reportChartProgress.tsx +++ b/components/division/reportChartProgress.tsx @@ -1,9 +1,11 @@ import Styles from "@/constants/Styles"; import { View } from "react-native"; import { PieChart } from "react-native-gifted-charts"; +import { useTheme } from "@/providers/ThemeProvider"; import Text from "../Text"; export default function ReportChartProgress({ data }: { data: { color: string; text: string; value: number; }[] }) { + const { colors } = useTheme(); const pieData = [ { value: 54, text: "54%", color: '#177AD5' }, { value: 40, text: "40%", color: '#92cc76' }, @@ -12,13 +14,13 @@ export default function ReportChartProgress({ data }: { data: { color: string; t ]; return ( - + PROGRES KEGIATAN () const [data, setData] = useState([]) @@ -57,10 +59,10 @@ export default function TaskDivisionDetail({ refreshing }: { refreshing: boolean : data.length > 0 ? data.map((item, index) => ( - { router.push(`/division/${id}/task/${item.idProject}`) }}> + { router.push(`/division/${id}/task/${item.idProject}`) }}> {item.title} - {item.projectTitle} - + {item.dateStart} - {item.dateEnd} diff --git a/components/document/headerDocument.tsx b/components/document/headerDocument.tsx index 03fe8ed..8837ad4 100644 --- a/components/document/headerDocument.tsx +++ b/components/document/headerDocument.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles"; import { apiCreateFolderDocument, apiUploadFileDocument } from "@/lib/api"; import { setUpdateDokumen } from "@/lib/dokumenUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import * as DocumentPicker from "expo-document-picker"; import { useLocalSearchParams } from "expo-router"; @@ -16,6 +17,7 @@ import MenuItemRow from "../menuItemRow"; import ModalFloat from "../modalFloat"; export default function HeaderRightDocument({ path, isMember }: { path: string, isMember: boolean }) { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false); const [newFolder, setNewFolder] = useState(false); const { id } = useLocalSearchParams<{ id: string }>(); @@ -129,7 +131,7 @@ export default function HeaderRightDocument({ path, isMember }: { path: string, icon={ } @@ -143,7 +145,7 @@ export default function HeaderRightDocument({ path, isMember }: { path: string, /> } + icon={} title="Upload File" onPress={pickDocumentAsync} /> diff --git a/components/document/itemFile.tsx b/components/document/itemFile.tsx index 27c84b3..9d847bd 100644 --- a/components/document/itemFile.tsx +++ b/components/document/itemFile.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { Pressable, View } from "react-native"; import Text from "../Text"; @@ -15,8 +16,9 @@ type Props = { } export default function ItemFile({ category, checked, dateTime, title, onChecked, onPress, canChecked }: Props) { + const { colors } = useTheme(); return ( - + { @@ -54,8 +56,8 @@ export default function ItemFile({ category, checked, dateTime, title, onChecked { checked - ? - : + ? + : } diff --git a/components/document/menuBottomSelectDocument.tsx b/components/document/menuBottomSelectDocument.tsx index 820314a..f746c71 100644 --- a/components/document/menuBottomSelectDocument.tsx +++ b/components/document/menuBottomSelectDocument.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { useState } from "react"; import { Pressable, ScrollView, View } from "react-native"; @@ -22,6 +23,7 @@ type Props = { } export default function MenuBottomSelectDocument({ onDone }: Props) { + const { colors } = useTheme(); const [isModal, setModal] = useState(false) const [isInformasi, setInformasi] = useState(false) const [isRename, setRename] = useState(false) @@ -106,17 +108,17 @@ export default function MenuBottomSelectDocument({ onDone }: Props) { } + icon={} title="Pindah" onPress={() => { handleMoveCopy('move') }} /> } + icon={} title="Salin" onPress={() => { handleMoveCopy('copy') }} /> } + icon={} title="Informasi" onPress={() => { setModal(false); setInformasi(true) }} /> @@ -134,65 +136,65 @@ export default function MenuBottomSelectDocument({ onDone }: Props) { - + - + Telah dibagikan ke divisi - + - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat - + Keamanan Masyarakat diff --git a/components/document/modalInformasi.tsx b/components/document/modalInformasi.tsx index f64efea..912a370 100644 --- a/components/document/modalInformasi.tsx +++ b/components/document/modalInformasi.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetDocumentInformasi } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { useEffect, useState } from "react"; import { ActivityIndicator, Pressable, ScrollView, View } from "react-native"; @@ -26,6 +27,7 @@ type PropsShare = { } export default function ModalInformasi({ data }: { data: any }) { + const { colors } = useTheme(); const open = useSharedValue(false) const [dataInformasi, setDataInformasi] = useState() const { token, decryptToken } = useAuthSession() @@ -76,12 +78,12 @@ export default function ModalInformasi({ data }: { data: any }) { - { open.value = !open.value; }}> + { open.value = !open.value; }}> - + Telah dibagikan ke divisi - + @@ -89,7 +91,7 @@ export default function ModalInformasi({ data }: { data: any }) { dataShare.length > 0 ? ( dataShare.map((item, index) => ( - + {item.name} )) diff --git a/components/document/modalMore.tsx b/components/document/modalMore.tsx index bdd01b3..2f82955 100644 --- a/components/document/modalMore.tsx +++ b/components/document/modalMore.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles"; import { apiCopyDocument, apiMoveDocument } from "@/lib/api"; import { setUpdateDokumen } from "@/lib/dokumenUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -35,6 +36,7 @@ export default function ModalMore({ data: Props[]; share: boolean; }) { + const { colors } = useTheme(); const { id } = useLocalSearchParams<{ id: string }>(); const [isInformasi, setInformasi] = useState(false); const [isCut, setIsCut] = useState(false); @@ -110,7 +112,7 @@ export default function ModalMore({ icon={ } @@ -125,7 +127,7 @@ export default function ModalMore({ icon={ } @@ -140,7 +142,7 @@ export default function ModalMore({ icon={ } diff --git a/components/document/modalNewFolder.tsx b/components/document/modalNewFolder.tsx index 43927ac..5635e12 100644 --- a/components/document/modalNewFolder.tsx +++ b/components/document/modalNewFolder.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiCreateFolderDocument } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useLocalSearchParams } from "expo-router"; import { useState } from "react"; import { Pressable, View } from "react-native"; @@ -10,6 +11,7 @@ import { InputForm } from "../inputForm"; import ModalFloat from "../modalFloat"; export function ModalNewFolder({ path, onCreated }: { path: string, onCreated: () => void }) { + const { colors } = useTheme() const { token, decryptToken } = useAuthSession() const [newFolder, setNewFolder] = useState(false) const [name, setName] = useState("") @@ -39,7 +41,7 @@ export function ModalNewFolder({ path, onCreated }: { path: string, onCreated: ( return ( <> - setNewFolder(true)}> + setNewFolder(true)}> FOLDER BARU diff --git a/components/document/modalSalinMove.tsx b/components/document/modalSalinMove.tsx index 01a4e96..e39081d 100644 --- a/components/document/modalSalinMove.tsx +++ b/components/document/modalSalinMove.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiGetDocument } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, Ionicons } from "@expo/vector-icons" import { useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" @@ -37,6 +38,7 @@ type PropsPath = { }; export default function ModalSalinMove({ open, close, category, onConfirm, dataChoose }: Props) { + const { colors } = useTheme() const [data, setData] = useState([]) const { token, decryptToken } = useAuthSession() const [path, setPath] = useState('home') @@ -73,9 +75,9 @@ export default function ModalSalinMove({ open, close, category, onConfirm, dataC }} > {item.id != "home" && ( - + )} - {item.name} + {item.name} )) } @@ -106,7 +108,7 @@ export default function ModalSalinMove({ open, close, category, onConfirm, dataC Tidak ada data } - + getData()} /> onConfirm(path)}> {category == 'copy' ? 'SALIN' : 'PINDAH'} @@ -114,4 +116,4 @@ export default function ModalSalinMove({ open, close, category, onConfirm, dataC ) -} \ No newline at end of file +} diff --git a/components/drawerBottom.tsx b/components/drawerBottom.tsx index 75f0a93..4fada79 100644 --- a/components/drawerBottom.tsx +++ b/components/drawerBottom.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialIcons } from "@expo/vector-icons"; import { Dimensions, KeyboardAvoidingView, Platform, Pressable, View } from "react-native"; import Modal from 'react-native-modal'; @@ -17,6 +18,7 @@ type Props = { export default function DrawerBottom({ isVisible, setVisible, title, children, animation, height, backdropPressable = true, keyboard = false }: Props) { const tinggiScreen = Dimensions.get("window").height; + const { colors } = useTheme(); const tinggiInput = height != undefined ? height : 25 const tinggiFix = tinggiScreen * tinggiInput / 100; @@ -43,11 +45,11 @@ export default function DrawerBottom({ isVisible, setVisible, title, children, a behavior={Platform.OS === 'ios' ? 'padding' : undefined} keyboardVerticalOffset={0} > - - + + {title} setVisible(false)}> - + @@ -56,11 +58,11 @@ export default function DrawerBottom({ isVisible, setVisible, title, children, a : - - + + {title} setVisible(false)}> - + diff --git a/components/eventItem.tsx b/components/eventItem.tsx index 757760c..7ca758a 100644 --- a/components/eventItem.tsx +++ b/components/eventItem.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -12,8 +13,17 @@ type Props = { } export default function EventItem({ category, title, user, jamAwal, jamAkhir, onPress }: Props) { + const { theme } = useTheme(); + + const getBackgroundColor = (cat: 'purple' | 'orange') => { + if (theme === 'dark') { + return cat === 'orange' ? '#5A2D0C' : '#1F2255'; + } + return cat === 'orange' ? '#FED6C5' : '#D8D8F1'; + }; + return ( - + {jamAwal} - {jamAkhir} diff --git a/components/group/headerGroupList.tsx b/components/group/headerGroupList.tsx index 0cf50ed..10ec969 100644 --- a/components/group/headerGroupList.tsx +++ b/components/group/headerGroupList.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiCreateGroup } from "@/lib/api" import { setUpdateGroup } from "@/lib/groupSlice" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { useState } from "react" import { View } from "react-native" @@ -17,6 +18,7 @@ export default function HeaderRightGroupList() { const dispatch = useDispatch() const update = useSelector((state: any) => state.groupUpdate) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const [isVisibleTambah, setVisibleTambah] = useState(false) const [title, setTitle] = useState('') @@ -62,7 +64,7 @@ export default function HeaderRightGroupList() { setVisible(false)} title="Menu"> } + icon={} title="Tambah Lembaga" onPress={() => { setVisible(false); @@ -86,6 +88,7 @@ export default function HeaderRightGroupList() { placeholder="Nama Lembaga Desa" required label="Lembaga Desa" error={error.title} + bg={colors.card} errorText="Lembaga Desa tidak boleh kosong & minimal 3 karakter" onChange={(val) => { validationForm(val, 'title') }} /> diff --git a/components/home/carouselHome.tsx b/components/home/carouselHome.tsx index d2610b1..d570cc1 100644 --- a/components/home/carouselHome.tsx +++ b/components/home/carouselHome.tsx @@ -4,6 +4,7 @@ import { apiGetBanner, apiGetProfile } from "@/lib/api"; import { setEntities } from "@/lib/bannerSlice"; import { setEntityUser } from "@/lib/userSlice"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import React, { useEffect } from "react"; import { Dimensions, Image, View } from "react-native"; import { useSharedValue } from "react-native-reanimated"; @@ -13,6 +14,7 @@ import Text from "../Text"; export default function CaraouselHome({ refreshing }: { refreshing: boolean }) { const { decryptToken, token } = useAuthSession() + const { colors } = useTheme(); const ref = React.useRef(null); const width = Dimensions.get("window").width; const progress = useSharedValue(0); @@ -66,12 +68,12 @@ export default function CaraouselHome({ refreshing }: { refreshing: boolean }) { renderItem={({ index }) => ( )} /> : - + BANNER } diff --git a/components/home/chartDokumenHome.tsx b/components/home/chartDokumenHome.tsx index f78be1f..ee76ae2 100644 --- a/components/home/chartDokumenHome.tsx +++ b/components/home/chartDokumenHome.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetDataHome } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useEffect, useState } from "react"; import { Dimensions, View } from "react-native"; import { BarChart } from "react-native-gifted-charts"; @@ -16,6 +17,7 @@ type Props = { export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }) { const [loading, setLoading] = useState(true) const { decryptToken, token } = useAuthSession() + const { colors } = useTheme(); const [data, setData] = useState([]) const [maxValue, setMaxValue] = useState(5) const barData = [ @@ -56,7 +58,7 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean } }, []); return ( - + JUMLAH DOKUMEN { loading ? @@ -70,6 +72,8 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean } isAnimated width={width - 140} barWidth={width * 0.25} + yAxisTextStyle={{ color: colors.text }} + xAxisLabelTextStyle={{ color: colors.text }} renderTooltip={(item: any, index: any) => { return ( ([]) const [loading, setLoading] = useState(true) @@ -46,7 +48,7 @@ export default function ChartProgresHome({ refreshing }: { refreshing: boolean } }, []); return ( - + PROGRES KEGIATAN { loading ? @@ -56,7 +58,7 @@ export default function ChartProgresHome({ refreshing }: { refreshing: boolean } data={data} showText showValuesAsTooltipText - textColor="black" + textColor={colors.text} radius={120} textSize={15} focusOnPress={false} diff --git a/components/home/divisionHome.tsx b/components/home/divisionHome.tsx index 2dfd8b7..872bbb6 100644 --- a/components/home/divisionHome.tsx +++ b/components/home/divisionHome.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetDataHome } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather } from "@expo/vector-icons"; import { router } from "expo-router"; import React, { useEffect, useState } from "react"; @@ -17,6 +18,7 @@ type Props = { export default function DivisionHome({ refreshing }: { refreshing: boolean }) { const { decryptToken, token } = useAuthSession() + const { colors } = useTheme(); const ref = React.useRef(null) const width = Dimensions.get("window").width const [data, setData] = useState([]) @@ -58,13 +60,13 @@ export default function DivisionHome({ refreshing }: { refreshing: boolean }) { : data.length > 0 ? data.map((item, index) => ( - { router.push(`/division/${item.id}`) }}> + { router.push(`/division/${item.id}`) }}> {item.name} {item.jumlah} Kegiatan - + )) diff --git a/components/home/eventHome.tsx b/components/home/eventHome.tsx index 4c03e4f..049b0e0 100644 --- a/components/home/eventHome.tsx +++ b/components/home/eventHome.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetDataHome } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { router } from "expo-router"; import { useEffect, useState } from "react"; import { View } from "react-native"; @@ -24,6 +25,7 @@ type Props = { export default function EventHome({ refreshing }: { refreshing: boolean }) { const { decryptToken, token } = useAuthSession() + const { colors } = useTheme(); const [data, setData] = useState([]) const [loading, setLoading] = useState(true) @@ -52,7 +54,7 @@ export default function EventHome({ refreshing }: { refreshing: boolean }) { return ( Acara Hari Ini - + { loading ? diff --git a/components/home/fiturHome.tsx b/components/home/fiturHome.tsx index 03878cf..43004c7 100644 --- a/components/home/fiturHome.tsx +++ b/components/home/fiturHome.tsx @@ -1,12 +1,14 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" +import { router } from "expo-router" import React from "react" import { View } from "react-native" import { ButtonFiturMenu } from "../buttonFiturMenu" -import { router } from "expo-router" import Text from "../Text" export default function FiturHome() { + const { colors } = useTheme(); return ( Fitur diff --git a/components/inputDate.tsx b/components/inputDate.tsx index 50115da..c5898d2 100644 --- a/components/inputDate.tsx +++ b/components/inputDate.tsx @@ -1,6 +1,7 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { stringToDate, stringToDateTime } from "@/lib/fun_stringToDate"; +import { useTheme } from "@/providers/ThemeProvider"; import DateTimePicker from "@react-native-community/datetimepicker"; import dayjs from "dayjs"; import { useEffect, useState } from "react"; @@ -26,6 +27,7 @@ type Props = { export function InputDate({ label, value, placeholder, onChange, info, disable, error, errorText, required, mode, round, width, }: Props) { + const { colors } = useTheme(); const [modal, setModal] = useState(false); const [valueFix, setValueFix] = useState(new Date()) const [valueFirst, setValueFirst] = useState(mode == "date" ? dayjs(new Date()).format("DD-MM-YYYY") : mode == "time" ? dayjs(new Date()).format("HH:mm") : "") @@ -84,7 +86,7 @@ export function InputDate({ label, value, placeholder, onChange, info, disable, ) } - setModal(true)} disabled={disable}> + setModal(true)} disabled={disable}> {value ? value : placeholder} {error && ({errorText})} @@ -104,7 +106,7 @@ export function InputDate({ label, value, placeholder, onChange, info, disable, display="spinner" onChange={(event, date) => { onChangeDate(event.type, date) }} onTouchCancel={() => setModal(false)} - textColor="black" + textColor={colors.text} /> ) diff --git a/components/inputForm.tsx b/components/inputForm.tsx index e7f0b42..bd3773f 100644 --- a/components/inputForm.tsx +++ b/components/inputForm.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Dimensions, Platform, TextInput, View } from "react-native"; import Text from "./Text"; @@ -15,7 +16,7 @@ type Props = { type: 'default' | 'visible-password' | 'numeric' round?: boolean width?: number - bg?: 'white' | 'transparent' + bg?: string value?: string disable?: boolean multiline?: boolean @@ -26,13 +27,14 @@ type Props = { export function InputForm({ label, value, placeholder, onChange, info, disable, error, errorText, required, itemLeft, itemRight, type, round, width, bg, multiline, mb = true, focus }: Props) { const lebar = Dimensions.get("window").width; + const { colors } = useTheme(); if (itemLeft != undefined || itemRight != undefined) { return ( { label != undefined && ( - + {label} {required && (*)} @@ -43,13 +45,18 @@ export function InputForm({ label, value, placeholder, onChange, info, disable, itemRight != undefined ? Styles.inputRoundFormRight : Styles.inputRoundFormLeft, multiline && { alignItems: 'flex-end' }, round && Styles.round30, - { backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' }, + { + backgroundColor: bg + ? (bg === 'white' ? (colors.background === '#151718' ? '#2d2e2f' : 'white') : bg) + : 'transparent', + borderColor: colors.icon + }, error && { borderColor: "red" }, Platform.OS == 'ios' ? { paddingVertical: 10 } : { paddingVertical: 0, minHeight: 40 }, { alignItems: 'center' }, multiline - ? { alignItems: "flex-end" } // multiline: tombol send di bawah - : { alignItems: "center" }, // default: tetap di tengah + ? { alignItems: "flex-end" } + : { alignItems: "center" }, ]}> {itemRight != undefined ? itemRight : itemLeft} {error && ({errorText})} - {info != undefined && ({info})} + {info != undefined && ({info})} ) } @@ -81,7 +88,7 @@ export function InputForm({ label, value, placeholder, onChange, info, disable, { label != undefined && ( - + {label} {required && (*)} @@ -92,14 +99,27 @@ export function InputForm({ label, value, placeholder, onChange, info, disable, placeholder={placeholder} keyboardType={type} editable={!disable} - style={[Styles.inputRoundForm, Platform.OS == 'ios' ? { paddingVertical: 11 } : { paddingVertical: 6 }, error && { borderColor: "red" }, round && Styles.round30, { backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' }, { color: 'black' }, multiline && { height: 150, textAlignVertical: 'top' }]} + style={[ + Styles.inputRoundForm, + Platform.OS == 'ios' ? { paddingVertical: 11 } : { paddingVertical: 6 }, + error && { borderColor: "red" }, + round && Styles.round30, + { + backgroundColor: bg + ? (bg === 'white' ? (colors.background === '#151718' ? '#2d2e2f' : 'white') : bg) + : 'transparent', + borderColor: colors.icon + }, + { color: colors.text }, + multiline && { height: 150, textAlignVertical: 'top' } + ]} onChangeText={onChange} - placeholderTextColor={'gray'} + placeholderTextColor={colors.icon} multiline={multiline} numberOfLines={multiline ? 5 : undefined} /> {error && ({errorText})} - {info != undefined && ({info})} + {info != undefined && ({info})} ) -} \ No newline at end of file +} diff --git a/components/itemDetailMember.tsx b/components/itemDetailMember.tsx index 20fa869..42b9caa 100644 --- a/components/itemDetailMember.tsx +++ b/components/itemDetailMember.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"; import { View } from "react-native"; import Text from "./Text"; @@ -10,66 +11,69 @@ type Props = { } -const data = { +const getData = (color: string) => ({ nik: { label: 'NIK', - icon: + icon: }, group: { label: 'Lembaga Desa', - icon: + icon: }, position: { label: 'Jabatan', - icon: + icon: }, phone: { label: 'No Telepon', - icon: + icon: }, email: { label: 'Email', - icon: + icon: }, gender: { label: 'Jenis Kelamin', - icon: + icon: }, dokumen: { label: 'Dokumen', - icon: + icon: }, type: { label: 'Tipe', - icon: + icon: }, location: { label: 'Lokasi', - icon: + icon: }, owner: { label: 'Pemilik', - icon: + icon: }, calendar: { label: 'Tanggal', - icon: + icon: }, share: { label: 'Bagikan', - icon: + icon: } -} +}) export default function ItemDetailMember({ category, value, border }: Props) { + const { colors } = useTheme(); + const data = getData(colors.text); + return ( {data[category].icon} - {data[category].label} + {data[category].label} - {value} + {value} ) } \ No newline at end of file diff --git a/components/itemSectionTanggalTugas.tsx b/components/itemSectionTanggalTugas.tsx index 440b926..e53f225 100644 --- a/components/itemSectionTanggalTugas.tsx +++ b/components/itemSectionTanggalTugas.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -12,19 +13,21 @@ type Props = { } export default function ItemSectionTanggalTugas({ done, title, dateStart, dateEnd, onPress }: Props) { + const { colors } = useTheme(); + return ( - + { done != undefined ? done ? <> - + Selesai : <> - + Belum Selesai : @@ -32,9 +35,9 @@ export default function ItemSectionTanggalTugas({ done, title, dateStart, dateEn } - - - + + + {title} @@ -43,13 +46,13 @@ export default function ItemSectionTanggalTugas({ done, title, dateStart, dateEn Tanggal Mulai - + {dateStart} Tanggal Berakhir - + {dateEnd} diff --git a/components/member/headerMemberDetail.tsx b/components/member/headerMemberDetail.tsx index 7e65b11..0e4d18f 100644 --- a/components/member/headerMemberDetail.tsx +++ b/components/member/headerMemberDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiDeleteUser } from "@/lib/api" import { setUpdateMember } from "@/lib/memberSlice" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { MaterialCommunityIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -22,6 +23,7 @@ export default function HeaderRightMemberDetail({ active, id }: Props) { const { token, decryptToken } = useAuthSession() const [isVisible, setVisible] = useState(false) const update = useSelector((state: any) => state.memberUpdate) + const { colors } = useTheme(); const dispatch = useDispatch() async function handleActive() { @@ -48,7 +50,7 @@ export default function HeaderRightMemberDetail({ active, id }: Props) { } + icon={} title={active ? "Non Aktifkan" : "Aktifkan"} onPress={() => { setVisible(false) @@ -62,7 +64,7 @@ export default function HeaderRightMemberDetail({ active, id }: Props) { }} /> } + icon={} title="Edit" onPress={() => { setVisible(false) diff --git a/components/member/headerMemberList.tsx b/components/member/headerMemberList.tsx index 91d2e32..78a5f04 100644 --- a/components/member/headerMemberList.tsx +++ b/components/member/headerMemberList.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -13,6 +14,7 @@ export default function HeaderMemberList() { const [isVisible, setVisible] = useState(false) const [isFilter, setFilter] = useState(false) const entityUser = useSelector((state: any) => state.user) + const { colors } = useTheme(); return ( <> @@ -23,7 +25,7 @@ export default function HeaderMemberList() { setVisible(false)} title="Menu"> } + icon={} title="Tambah Anggota" onPress={() => { setVisible(false) @@ -33,7 +35,7 @@ export default function HeaderMemberList() { { (entityUser.role == 'supadmin' || entityUser.role == 'developer') && } + icon={} title="Filter" onPress={() => { setVisible(false) diff --git a/components/modalFloat.tsx b/components/modalFloat.tsx index dd6b855..94ff13c 100644 --- a/components/modalFloat.tsx +++ b/components/modalFloat.tsx @@ -1,4 +1,5 @@ import Styles from '@/constants/Styles'; +import { useTheme } from '@/providers/ThemeProvider'; import { Pressable, View } from 'react-native'; import Modal from 'react-native-modal'; import Text from './Text'; @@ -14,6 +15,8 @@ type Props = { } export default function ModalFloat({ isVisible, setVisible, title, children, onSubmit, disableSubmit, buttonHide }: Props) { + const { colors } = useTheme(); + return ( { setVisible(false) }} > - - + + {title} diff --git a/components/modalSelect.tsx b/components/modalSelect.tsx index 57a5c29..6ab2eff 100644 --- a/components/modalSelect.tsx +++ b/components/modalSelect.tsx @@ -7,6 +7,7 @@ import { apiGetGroup, apiGetPosition, apiGetUser } from "@/lib/api" import { setEntityFilterGroup } from "@/lib/filterSlice" import { setMemberChoose } from "@/lib/memberChoose" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { useEffect, useState } from "react" import { Pressable, ScrollView, View } from "react-native" @@ -33,6 +34,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on const entityUser = useSelector((state: any) => state.user) const dispatch = useDispatch() const entitiesGroup = useSelector((state: any) => state.filterGroup) + const { colors } = useTheme(); const [chooseValue, setChooseValue] = useState({ val: valChoose, label: '' }) const [data, setData] = useState([]) const [search, setSearch] = useState('') @@ -174,9 +176,9 @@ export default function ModalSelect({ open, close, title, category, idParent, on { (category == 'member') ? - selectMember.some((i: any) => i.idUser == item.id) && + selectMember.some((i: any) => i.idUser == item.id) && : - chooseValue.val == item.id && + chooseValue.val == item.id && } )) @@ -192,7 +194,7 @@ export default function ModalSelect({ open, close, title, category, idParent, on }}> {item.label} { - valChoose == item.val && + valChoose == item.val && } )) diff --git a/components/modalSelectMultiple.tsx b/components/modalSelectMultiple.tsx index bb19b44..caa7c46 100644 --- a/components/modalSelectMultiple.tsx +++ b/components/modalSelectMultiple.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiGetDivisionGroup, apiGetDocumentInformasi, apiGetListDivisionByIdDivision } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { useEffect, useState } from "react" import { Pressable, ScrollView, View } from "react-native" @@ -34,6 +35,7 @@ type GroupData = { } export default function ModalSelectMultiple({ open, close, title, category, choose, onSelect, value, item }: Props) { + const { colors } = useTheme() const [isChoose, setChoose] = useState(choose) const { token, decryptToken } = useAuthSession() const [data, setData] = useState([]) @@ -161,7 +163,7 @@ export default function ModalSelectMultiple({ open, close, title, category, choo {item.name} { selectedDivision.some((i: any) => i.id == item.id) - ? + ? : <> } @@ -177,9 +179,9 @@ export default function ModalSelectMultiple({ open, close, title, category, choo {item.name} { checked[item.id] && checked[item.id]?.length === item.Division?.length - ? + ? : (checked[item.id] && checked[item.id]?.length > 0 && checked[item.id]?.length < item.Division?.length) - ? + ? : <> } @@ -189,7 +191,7 @@ export default function ModalSelectMultiple({ open, close, title, category, choo { handleCheck(item.id, child.id) }}> {child.name} { - checked[item.id] && checked[item.id].includes(child.id) && + checked[item.id] && checked[item.id].includes(child.id) && } ) diff --git a/components/paperGridContent.tsx b/components/paperGridContent.tsx index 647aa69..6da37bd 100644 --- a/components/paperGridContent.tsx +++ b/components/paperGridContent.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -11,15 +12,21 @@ type Props = { onPress?: () => void contentPosition?: 'top' | 'center' titleTail?: number + height?: number }; -export default function PaperGridContent({ content, children, title, headerColor, onPress, contentPosition, titleTail }: Props) { +export default function PaperGridContent({ content, children, title, headerColor, onPress, contentPosition, titleTail, height }: Props) { + const { colors } = useTheme(); return ( - + - {title} + {title} - + {children} diff --git a/components/position/headerRightPositionList.tsx b/components/position/headerRightPositionList.tsx index 549623f..f2de9e7 100644 --- a/components/position/headerRightPositionList.tsx +++ b/components/position/headerRightPositionList.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { useState } from "react" import { View } from "react-native" @@ -14,6 +15,7 @@ export default function HeaderRightPositionList() { const [isVisible, setVisible] = useState(false) const [isVisibleTambah, setVisibleTambah] = useState(false) const [isFilter, setFilter] = useState(false) + const { colors } = useTheme() return ( <> @@ -21,7 +23,7 @@ export default function HeaderRightPositionList() { } + icon={} title="Tambah Jabatan" onPress={() => { setVisible(false) @@ -33,7 +35,7 @@ export default function HeaderRightPositionList() { { (entityUser.role == 'supadmin' || entityUser.role == 'developer') && } + icon={} title="Filter" onPress={() => { setVisible(false) diff --git a/components/position/modalFormCreatePosition.tsx b/components/position/modalFormCreatePosition.tsx index 256a3f3..1f1db34 100644 --- a/components/position/modalFormCreatePosition.tsx +++ b/components/position/modalFormCreatePosition.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiCreatePosition } from "@/lib/api" import { setUpdatePosition } from "@/lib/positionSlice" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { update } from "@react-native-firebase/database" import { useEffect, useState } from "react" import { View } from "react-native" @@ -9,13 +10,14 @@ import Toast from "react-native-toast-message" import { useDispatch, useSelector } from "react-redux" import { ButtonForm } from "../buttonForm" import { InputForm } from "../inputForm" -import SelectForm from "../selectForm" import ModalSelect from "../modalSelect" +import SelectForm from "../selectForm" export default function ModalFormCreatePosition({ onClose }: { onClose: () => void }) { const dispatch = useDispatch() const { token, decryptToken } = useAuthSession() const entityUser = useSelector((state: any) => state.user) + const { colors } = useTheme() const [choose, setChoose] = useState({ val: '', label: '' }) const [isSelect, setSelect] = useState(false) const [disable, setDisable] = useState(true) @@ -104,6 +106,7 @@ export default function ModalFormCreatePosition({ onClose }: { onClose: () => vo label="Jabatan" onChange={(value) => { validationForm(value, 'name') }} error={error.name} + bg={colors.card} errorText="Nama jabatan harus diisi" value={dataForm.name} /> diff --git a/components/progressBar.tsx b/components/progressBar.tsx index a736f4f..21def4d 100644 --- a/components/progressBar.tsx +++ b/components/progressBar.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { useEffect, useState } from "react"; import { Animated, View } from "react-native"; @@ -10,6 +11,7 @@ type Props = { } export default function ProgressBar({ margin, value, category }: Props) { + const { colors } = useTheme(); const [progress, setProgress] = useState(new Animated.Value(0)); const [totalProgress, setTotalProgress] = useState(category == 'carousel' ? 232 : category == 'page' ? 245 : 290); const [componentWidth, setComponentWidth] = useState(0); @@ -34,7 +36,7 @@ export default function ProgressBar({ margin, value, category }: Props) { return ( - + diff --git a/components/project/headerProjectDetail.tsx b/components/project/headerProjectDetail.tsx index 83b79cc..6ad1b0f 100644 --- a/components/project/headerProjectDetail.tsx +++ b/components/project/headerProjectDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiAddLinkProject, apiDeleteProject } from "@/lib/api" import { setUpdateProject } from "@/lib/projectUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -23,6 +24,7 @@ type Props = { export default function HeaderRightProjectDetail({ id, status }: Props) { const entityUser = useSelector((state: any) => state.user) const { token, decryptToken } = useAuthSession() + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) @@ -70,7 +72,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { } + icon={} title="Tambah Tugas" onPress={() => { if (status == 3) return @@ -80,7 +82,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { disabled={status == 3} /> } + icon={} title="Tambah File" onPress={() => { if (status == 3) return @@ -90,7 +92,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { disabled={status == 3} /> } + icon={} title="Tambah Link" onPress={() => { if (status == 3) return @@ -104,7 +106,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { } + icon={} title="Laporan" onPress={() => { if (status == 3) return @@ -117,7 +119,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { entityUser.role != "user" && entityUser.role != "coadmin" && <> } + icon={} title="Tambah Anggota" onPress={() => { if (status == 3) return @@ -127,7 +129,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { disabled={status == 3} /> } + icon={} title="Edit" onPress={() => { if (status == 3) return @@ -146,7 +148,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { status == 3 ? } + icon={} title="Hapus" onPress={() => { setVisible(false) @@ -159,7 +161,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { /> : } + icon={} title="Batal" onPress={() => { setVisible(false) @@ -182,6 +184,7 @@ export default function HeaderRightProjectDetail({ id, status }: Props) { { setLink(text) }} /> diff --git a/components/project/headerProjectList.tsx b/components/project/headerProjectList.tsx index 9652fbc..ddb23ef 100644 --- a/components/project/headerProjectList.tsx +++ b/components/project/headerProjectList.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -10,6 +11,7 @@ import MenuItemRow from "../menuItemRow" import ModalFilter from "../modalFilter" export default function HeaderRightProjectList() { + const { colors } = useTheme(); const [isVisible, setVisible] = useState(false) const [isFilter, setFilter] = useState(false) const entityUser = useSelector((state: any) => state.user) @@ -22,7 +24,7 @@ export default function HeaderRightProjectList() { { entityUser.role != "user" && entityUser.role != "coadmin" && } + icon={} title="Tambah Kegiatan" onPress={() => { setVisible(false) @@ -33,7 +35,7 @@ export default function HeaderRightProjectList() { { // (entityUser.role == "user" || entityUser.role == "coadmin" || entityUser.role == "supadmin" || entityUser.role == "developer") && } + icon={} title="Filter" onPress={() => { setVisible(false) diff --git a/components/project/modalAddDetailTugasProject.tsx b/components/project/modalAddDetailTugasProject.tsx index 30cf6c2..766af45 100644 --- a/components/project/modalAddDetailTugasProject.tsx +++ b/components/project/modalAddDetailTugasProject.tsx @@ -1,5 +1,6 @@ import Styles from "@/constants/Styles"; import { stringToDateTime } from "@/lib/fun_stringToDate"; +import { useTheme } from "@/providers/ThemeProvider"; import { useEffect, useState } from "react"; import { Dimensions, View, VirtualizedList } from "react-native"; import { InputDate } from "../inputDate"; @@ -13,6 +14,7 @@ interface Props { } export default function ModalAddDetailTugasProject({ isVisible, setVisible, dataTanggal, onSubmit }: { isVisible: boolean, setVisible: (value: boolean) => void, dataTanggal: Props[], onSubmit: (data: Props[]) => void }) { + const { colors } = useTheme(); const [data, setData] = useState(dataTanggal) const tinggiScreen = Dimensions.get("window").height; const tinggiFix = tinggiScreen * 70 / 100; @@ -89,14 +91,14 @@ export default function ModalAddDetailTugasProject({ isVisible, setVisible, data setVisible(false) }} > - + data.length} getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - + {item.date} diff --git a/components/project/modalListDetailTugasProject.tsx b/components/project/modalListDetailTugasProject.tsx index 26d01c9..4305286 100644 --- a/components/project/modalListDetailTugasProject.tsx +++ b/components/project/modalListDetailTugasProject.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetProjectTask } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useEffect, useState } from "react"; import { Dimensions, View, VirtualizedList } from "react-native"; import { InputDate } from "../inputDate"; @@ -16,6 +17,7 @@ interface Props { } export default function ModalListDetailTugasProject({ isVisible, setVisible, idTask }: { isVisible: boolean, setVisible: (value: boolean) => void, idTask: string }) { + const { colors } = useTheme(); const [data, setData] = useState([]) const [loading, setLoading] = useState(false) const { token, decryptToken } = useAuthSession() @@ -75,7 +77,7 @@ export default function ModalListDetailTugasProject({ isVisible, setVisible, idT getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - + {item.date} diff --git a/components/project/sectionFile.tsx b/components/project/sectionFile.tsx index b72486e..44177fa 100644 --- a/components/project/sectionFile.tsx +++ b/components/project/sectionFile.tsx @@ -3,6 +3,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteFileProject, apiGetProjectOne } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; @@ -30,6 +31,7 @@ type Props = { } export default function SectionFile({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) { + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession(); @@ -135,7 +137,7 @@ export default function SectionFile({ status, member, refreshing }: { status: nu File - + { loading ? arrSkeleton.map((item, index) => { @@ -150,7 +152,7 @@ export default function SectionFile({ status, member, refreshing }: { status: nu } + icon={} title={item.name + '.' + item.extension} titleWeight="normal" onPress={() => { setSelectFile(item); setModal(true) }} @@ -167,7 +169,7 @@ export default function SectionFile({ status, member, refreshing }: { status: nu } + icon={} title="Lihat / Share" onPress={() => { openFile() @@ -177,7 +179,7 @@ export default function SectionFile({ status, member, refreshing }: { status: nu !member && (entityUser.role == "user" || entityUser.role == "coadmin") ? <> : } + icon={} title="Hapus" disabled={status == 3} onPress={() => { diff --git a/components/project/sectionLink.tsx b/components/project/sectionLink.tsx index cd81e4b..3c14a6d 100644 --- a/components/project/sectionLink.tsx +++ b/components/project/sectionLink.tsx @@ -3,6 +3,7 @@ import { apiDeleteLinkProject, apiGetProjectOne } from "@/lib/api"; import { urlCompleted } from "@/lib/fun_urlCompleted"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, Ionicons } from "@expo/vector-icons"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -22,6 +23,7 @@ type Props = { } export default function SectionLink({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) { + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession(); @@ -82,14 +84,14 @@ export default function SectionLink({ status, member, refreshing }: { status: nu <> Link - + { data.map((item, index) => { return ( } + icon={} title={item.link} titleWeight="normal" onPress={() => { setSelectLink(item); setModal(true) }} @@ -104,7 +106,7 @@ export default function SectionLink({ status, member, refreshing }: { status: nu } + icon={} title="Buka Link" onPress={() => { Linking.openURL(urlCompleted(String(selectLink?.link))) @@ -114,7 +116,7 @@ export default function SectionLink({ status, member, refreshing }: { status: nu !member && (entityUser.role == "user" || entityUser.role == "coadmin") ? <> : } + icon={} title="Hapus" disabled={status == 3} onPress={() => { diff --git a/components/project/sectionListAddTask.tsx b/components/project/sectionListAddTask.tsx index e466fc3..c2db0c0 100644 --- a/components/project/sectionListAddTask.tsx +++ b/components/project/sectionListAddTask.tsx @@ -1,5 +1,6 @@ import Styles from "@/constants/Styles"; import { deleteTaskCreate } from "@/lib/taskCreate"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons } from "@expo/vector-icons"; import { Key, useState } from "react"; import { View } from "react-native"; @@ -10,6 +11,7 @@ import MenuItemRow from "../menuItemRow"; import Text from "../Text"; export default function SectionListAddTask() { + const { colors } = useTheme(); const taskCreate = useSelector((state: any) => state.taskCreate) const [select, setSelect] = useState(null) const [isModal, setModal] = useState(false) @@ -30,7 +32,7 @@ export default function SectionListAddTask() { Tanggal & Tugas - + { taskCreate.map((item: { status: number; title: string; dateStart: string; dateEnd: string; }, index: Key | null | undefined) => { return ( @@ -58,7 +60,7 @@ export default function SectionListAddTask() { > } + icon={} title="Hapus Tugas" onPress={() => { handleDelete() }} /> diff --git a/components/project/sectionMember.tsx b/components/project/sectionMember.tsx index 07cf817..44d10d3 100644 --- a/components/project/sectionMember.tsx +++ b/components/project/sectionMember.tsx @@ -3,6 +3,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteProjectMember, apiGetProjectOne } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -27,6 +28,7 @@ type Props = { }; export default function SectionMember({ status, refreshing }: { status: number | undefined, refreshing?: boolean }) { + const { colors } = useTheme(); const dispatch = useDispatch() const entityUser = useSelector((state: any) => state.user) const update = useSelector((state: any) => state.projectUpdate) @@ -97,7 +99,7 @@ export default function SectionMember({ status, refreshing }: { status: number | Total {data.length} Anggota - + { loading ? arrSkeleton.map((item, index) => { @@ -143,7 +145,7 @@ export default function SectionMember({ status, refreshing }: { status: number | icon={ } @@ -159,7 +161,7 @@ export default function SectionMember({ status, refreshing }: { status: number | icon={ } diff --git a/components/project/sectionReportProject.tsx b/components/project/sectionReportProject.tsx index 18e7b82..0d3a139 100644 --- a/components/project/sectionReportProject.tsx +++ b/components/project/sectionReportProject.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetProjectOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { View } from "react-native"; @@ -9,6 +10,7 @@ import Text from "../Text"; import TextExpandable from "../textExpandable"; export default function SectionReportProject({ refreshing }: { refreshing?: boolean }) { + const { colors } = useTheme(); const update = useSelector((state: any) => state.projectUpdate) const { token, decryptToken } = useAuthSession(); const { id } = useLocalSearchParams<{ id: string }>(); @@ -45,7 +47,7 @@ export default function SectionReportProject({ refreshing }: { refreshing?: bool Laporan Kegiatan - + diff --git a/components/project/sectionTanggalTugas.tsx b/components/project/sectionTanggalTugas.tsx index 285b55e..c53b305 100644 --- a/components/project/sectionTanggalTugas.tsx +++ b/components/project/sectionTanggalTugas.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteProjectTask, apiGetProjectOne, apiUpdateStatusProjectTask } from "@/lib/api"; import { setUpdateProject } from "@/lib/projectUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -28,6 +29,7 @@ type Props = { }; export default function SectionTanggalTugasProject({ status, member, refreshing }: { status: number | undefined, member: boolean, refreshing?: boolean }) { + const { colors } = useTheme(); const entityUser = useSelector((state: any) => state.user) const dispatch = useDispatch() const update = useSelector((state: any) => state.projectUpdate) @@ -116,7 +118,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing Tanggal & Tugas - + { loading ? arrSkeleton.map((item, index) => { @@ -163,7 +165,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing icon={ } @@ -179,7 +181,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing icon={ } @@ -194,7 +196,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing icon={ } @@ -209,7 +211,7 @@ export default function SectionTanggalTugasProject({ status, member, refreshing } + icon={} title="Hapus Tugas" onPress={() => { setModal(false) diff --git a/components/sectionCancel.tsx b/components/sectionCancel.tsx index 34efbaf..e5d9a94 100644 --- a/components/sectionCancel.tsx +++ b/components/sectionCancel.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import Text from "./Text"; import { View } from "react-native"; @@ -10,10 +11,12 @@ type Props = { } export default function SectionCancel({ text, title }: Props) { + const { colors } = useTheme(); + return ( - + - + {title ? title : 'Kegiatan Dibatalkan'} { diff --git a/components/sectionProgress.tsx b/components/sectionProgress.tsx index 7215cf2..816c13d 100644 --- a/components/sectionProgress.tsx +++ b/components/sectionProgress.tsx @@ -1,5 +1,6 @@ import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { AntDesign } from "@expo/vector-icons"; import Text from "./Text"; import { View } from "react-native"; @@ -11,9 +12,11 @@ type Props = { } export default function SectionProgress({ text, progress }: Props) { + const { colors } = useTheme(); + return ( - - + + diff --git a/components/selectForm.tsx b/components/selectForm.tsx index a6775ac..fdd1531 100644 --- a/components/selectForm.tsx +++ b/components/selectForm.tsx @@ -1,4 +1,5 @@ import Styles from "@/constants/Styles"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather } from "@expo/vector-icons"; import { Pressable, View } from "react-native"; import Text from "./Text"; @@ -15,10 +16,11 @@ type Props = { errorText?: string; required?: boolean; round?: boolean - bg?: 'white' | 'transparent' + bg?: string }; -export default function SelectForm({ label, value, placeholder, onPress, info, error, errorText, required, itemLeft, round, bg }: Props) { +export default function SelectForm({ label, value, placeholder, onPress, info, error, errorText, required, round, bg }: Props) { + const { colors } = useTheme(); return ( { @@ -30,19 +32,27 @@ export default function SelectForm({ label, value, placeholder, onPress, info, e ) } - - + + { value ? ( - {value} + {value} ) : ( - {placeholder} + {placeholder} ) } - - {error && ({errorText})} - {info != undefined && ({info})} - + + {error && ({errorText}) + } + {info != undefined && ({info})} + ) } \ No newline at end of file diff --git a/components/task/headerTaskDetail.tsx b/components/task/headerTaskDetail.tsx index 248fc26..23cfeda 100644 --- a/components/task/headerTaskDetail.tsx +++ b/components/task/headerTaskDetail.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles" import { apiAddLinkTask, apiDeleteTask } from "@/lib/api" import { setUpdateTask } from "@/lib/taskUpdate" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign, Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router } from "expo-router" import { useState } from "react" @@ -23,6 +24,7 @@ type Props = { } export default function HeaderRightTaskDetail({ id, division, status, isAdminDivision }: Props) { + const { colors } = useTheme() const { token, decryptToken } = useAuthSession() const [isVisible, setVisible] = useState(false) const entityUser = useSelector((state: any) => state.user); @@ -72,7 +74,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv } + icon={} title="Tambah Tugas" onPress={() => { if (status == 3) return @@ -82,7 +84,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv disabled={status == 3} /> } + icon={} title="Tambah File" onPress={() => { if (status == 3) return @@ -93,7 +95,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv /> } + icon={} title="Tambah Link" onPress={() => { if (status == 3) return @@ -107,7 +109,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv } + icon={} title="Laporan" onPress={() => { if (status == 3) return @@ -122,7 +124,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv && <> } + icon={} title="Tambah Anggota" onPress={() => { if (status == 3) return @@ -132,7 +134,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv disabled={status == 3} /> } + icon={} title="Edit" onPress={() => { if (status == 3) return @@ -152,7 +154,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv status == 3 ? } + icon={} title="Hapus" onPress={() => { setVisible(false) @@ -166,7 +168,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv : } + icon={} title="Batal" onPress={() => { setVisible(false) @@ -191,6 +193,7 @@ export default function HeaderRightTaskDetail({ id, division, status, isAdminDiv placeholder="Masukkan link" value={link} onChange={(text) => { setLink(text) }} + bg={colors.card} /> diff --git a/components/task/headerTaskList.tsx b/components/task/headerTaskList.tsx index df15d06..b2ab7e6 100644 --- a/components/task/headerTaskList.tsx +++ b/components/task/headerTaskList.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles" import { apiGetDivisionOneFeature } from "@/lib/api" import { useAuthSession } from "@/providers/AuthProvider" +import { useTheme } from "@/providers/ThemeProvider" import { AntDesign } from "@expo/vector-icons" import { router, useLocalSearchParams } from "expo-router" import { useEffect, useState } from "react" @@ -12,6 +13,7 @@ import MenuItemRow from "../menuItemRow" import ModalFilter from "../modalFilter" export default function HeaderRightTaskList() { + const { colors } = useTheme() const [isVisible, setVisible] = useState(false) const [isAdminDivision, setIsAdminDivision] = useState(false); const { token, decryptToken } = useAuthSession() @@ -52,7 +54,7 @@ export default function HeaderRightTaskList() { (entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision && } + icon={} title="Tambah Tugas Divisi" onPress={() => { setVisible(false) @@ -61,7 +63,7 @@ export default function HeaderRightTaskList() { /> } } + icon={} title="Filter" onPress={() => { setVisible(false) diff --git a/components/task/modalAddDetailTugasTask.tsx b/components/task/modalAddDetailTugasTask.tsx index ca98600..e02271e 100644 --- a/components/task/modalAddDetailTugasTask.tsx +++ b/components/task/modalAddDetailTugasTask.tsx @@ -1,5 +1,6 @@ import Styles from "@/constants/Styles"; import { stringToDateTime } from "@/lib/fun_stringToDate"; +import { useTheme } from "@/providers/ThemeProvider"; import { useEffect, useState } from "react"; import { Dimensions, View, VirtualizedList } from "react-native"; import { InputDate } from "../inputDate"; @@ -13,6 +14,7 @@ interface Props { } export default function ModalAddDetailTugasTask({ isVisible, setVisible, dataTanggal, onSubmit }: { isVisible: boolean, setVisible: (value: boolean) => void, dataTanggal: Props[], onSubmit: (data: Props[]) => void }) { + const { colors } = useTheme() const [data, setData] = useState(dataTanggal) const tinggiScreen = Dimensions.get("window").height; const tinggiFix = tinggiScreen * 70 / 100; @@ -96,7 +98,7 @@ export default function ModalAddDetailTugasTask({ isVisible, setVisible, dataTan getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - + {item.date} diff --git a/components/task/modalListDetailTugasTask.tsx b/components/task/modalListDetailTugasTask.tsx index b909ac2..7a79268 100644 --- a/components/task/modalListDetailTugasTask.tsx +++ b/components/task/modalListDetailTugasTask.tsx @@ -1,5 +1,6 @@ import Styles from "@/constants/Styles"; import { apiGetProjectTask, apiGetTaskTugas } from "@/lib/api"; +import { useTheme } from "@/providers/ThemeProvider"; import { useAuthSession } from "@/providers/AuthProvider"; import { useEffect, useState } from "react"; import { Dimensions, View, VirtualizedList } from "react-native"; @@ -16,6 +17,7 @@ interface Props { } export default function ModalListDetailTugasTask({ isVisible, setVisible, idTask }: { isVisible: boolean, setVisible: (value: boolean) => void, idTask: string }) { + const { colors } = useTheme() const [data, setData] = useState([]) const [loading, setLoading] = useState(false) const { token, decryptToken } = useAuthSession() @@ -75,7 +77,7 @@ export default function ModalListDetailTugasTask({ isVisible, setVisible, idTask getItem={getItem} renderItem={({ item, index }: { item: Props, index: number }) => { return ( - + {item.date} diff --git a/components/task/sectionFileTask.tsx b/components/task/sectionFileTask.tsx index 33f3c6f..b409972 100644 --- a/components/task/sectionFileTask.tsx +++ b/components/task/sectionFileTask.tsx @@ -3,6 +3,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteFileTask, apiGetTaskOne } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import * as FileSystem from 'expo-file-system'; import { startActivityAsync } from 'expo-intent-launcher'; @@ -29,6 +30,7 @@ type Props = { } export default function SectionFileTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) { + const { colors } = useTheme() const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession() const { detail } = useLocalSearchParams<{ detail: string }>() @@ -126,7 +128,7 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr File - + { loading ? arrSkeleton.map((item, index) => { @@ -141,7 +143,7 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr } + icon={} title={item.name + '.' + item.extension} titleWeight="normal" onPress={() => { setSelectFile(item); setModal(true) }} @@ -158,7 +160,7 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr } + icon={} title="Lihat / Share" onPress={() => { openFile() @@ -168,7 +170,7 @@ export default function SectionFileTask({ refreshing, isMemberDivision }: { refr (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision ? } + icon={} title="Hapus" onPress={() => { setModal(false) diff --git a/components/task/sectionLinkTask.tsx b/components/task/sectionLinkTask.tsx index 17a3293..fbe6a6b 100644 --- a/components/task/sectionLinkTask.tsx +++ b/components/task/sectionLinkTask.tsx @@ -3,6 +3,7 @@ import { apiDeleteLinkTask, apiGetTaskOne } from "@/lib/api"; import { urlCompleted } from "@/lib/fun_urlCompleted"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Feather, Ionicons } from "@expo/vector-icons"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -21,6 +22,7 @@ type Props = { } export default function SectionLinkTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) { + const { colors } = useTheme() const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession() const { detail } = useLocalSearchParams<{ detail: string }>() @@ -74,14 +76,14 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr <> Link - + { data.map((item, index) => { return ( } + icon={} title={item.link} titleWeight="normal" onPress={() => { setSelectLink(item); setModal(true) }} @@ -96,7 +98,7 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr } + icon={} title="Buka Link" onPress={() => { Linking.openURL(urlCompleted(String(selectLink?.link))) @@ -106,7 +108,7 @@ export default function SectionLinkTask({ refreshing, isMemberDivision }: { refr (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision ? } + icon={} title="Hapus" onPress={() => { setModal(false) diff --git a/components/task/sectionMemberTask.tsx b/components/task/sectionMemberTask.tsx index 39971cc..612a2c4 100644 --- a/components/task/sectionMemberTask.tsx +++ b/components/task/sectionMemberTask.tsx @@ -3,6 +3,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteTaskMember, apiGetTaskOne } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { MaterialCommunityIcons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -27,6 +28,7 @@ type Props = { }; export default function SectionMemberTask({ refreshing, isAdminDivision }: { refreshing: boolean, isAdminDivision: boolean }) { + const { colors } = useTheme() const [isModal, setModal] = useState(false); const entityUser = useSelector((state: any) => state.user); const { token, decryptToken } = useAuthSession(); @@ -100,7 +102,7 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref Total {data.length} Anggota - + { loading ? arrSkeleton.map((item, index) => { @@ -155,7 +157,7 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref icon={ } @@ -174,7 +176,7 @@ export default function SectionMemberTask({ refreshing, isAdminDivision }: { ref icon={ } diff --git a/components/task/sectionReportTask.tsx b/components/task/sectionReportTask.tsx index 3c52f95..64d270b 100644 --- a/components/task/sectionReportTask.tsx +++ b/components/task/sectionReportTask.tsx @@ -1,6 +1,7 @@ import Styles from "@/constants/Styles"; import { apiGetTaskOne } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { View } from "react-native"; @@ -10,6 +11,7 @@ import TextExpandable from "../textExpandable"; export default function SectionReportTask({ refreshing }: { refreshing: boolean }) { + const { colors } = useTheme() const update = useSelector((state: any) => state.taskUpdate) const { token, decryptToken } = useAuthSession() const { id, detail } = useLocalSearchParams<{ id: string, detail: string }>(); @@ -43,7 +45,7 @@ export default function SectionReportTask({ refreshing }: { refreshing: boolean Laporan Kegiatan - + diff --git a/components/task/sectionTanggalTugasTask.tsx b/components/task/sectionTanggalTugasTask.tsx index 5f19055..60b1eb7 100644 --- a/components/task/sectionTanggalTugasTask.tsx +++ b/components/task/sectionTanggalTugasTask.tsx @@ -2,6 +2,7 @@ import Styles from "@/constants/Styles"; import { apiDeleteTaskTugas, apiGetTaskOne, apiUpdateStatusTaskDivision } from "@/lib/api"; import { setUpdateTask } from "@/lib/taskUpdate"; import { useAuthSession } from "@/providers/AuthProvider"; +import { useTheme } from "@/providers/ThemeProvider"; import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; @@ -27,6 +28,7 @@ type Props = { } export default function SectionTanggalTugasTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) { + const { colors } = useTheme() const dispatch = useDispatch() const entityUser = useSelector((state: any) => state.user); const update = useSelector((state: any) => state.taskUpdate) @@ -119,7 +121,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } <> Tanggal & Tugas - + { loading ? arrSkeleton.map((item, index) => { @@ -160,7 +162,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } icon={ } @@ -177,7 +179,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } ? <> } + icon={} title="Update Status" onPress={() => { setModal(false) @@ -187,7 +189,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } }} /> } + icon={} title="Edit Tugas" onPress={() => { setModal(false) @@ -205,7 +207,7 @@ export default function SectionTanggalTugasTask({ refreshing, isMemberDivision } ? } + icon={} title="Hapus Tugas" onPress={() => { setModal(false) diff --git a/constants/Colors.ts b/constants/Colors.ts index be9eec1..0996736 100644 --- a/constants/Colors.ts +++ b/constants/Colors.ts @@ -6,7 +6,9 @@ export const Colors = { text: '#11181C', background: '#f4f9fd', tint: tintColorLight, + primary: '#19345E', icon: '#687076', + card: '#ffffff', tabIconDefault: '#687076', tabIconSelected: tintColorLight, }, @@ -14,7 +16,9 @@ export const Colors = { text: '#ECEDEE', background: '#151718', tint: tintColorDark, + primary: '#19345E', icon: '#9BA1A6', + card: '#232526', // slightly lighter than background #151718 tabIconDefault: '#9BA1A6', tabIconSelected: tintColorDark, }, diff --git a/providers/ThemeProvider.tsx b/providers/ThemeProvider.tsx new file mode 100644 index 0000000..0dc31ea --- /dev/null +++ b/providers/ThemeProvider.tsx @@ -0,0 +1,66 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react'; +import { useColorScheme } from 'react-native'; +import { Colors } from '@/constants/Colors'; + +type Theme = 'light' | 'dark' | 'system'; +type StartTheme = 'light' | 'dark'; + +interface ThemeContextType { + theme: Theme; + activeTheme: StartTheme; + setTheme: (theme: Theme) => void; + colors: typeof Colors.light; +} + +const ThemeContext = createContext({ + theme: 'system', + activeTheme: 'light', + setTheme: () => { }, + colors: Colors.light, +}); + +export const useTheme = () => useContext(ThemeContext); + +export default function ThemeProvider({ children }: { children: ReactNode }) { + const systemColorScheme = useColorScheme(); + const [theme, setThemeState] = useState('system'); + const [isReady, setIsReady] = useState(false); + + useEffect(() => { + (async () => { + try { + const storedTheme = await AsyncStorage.getItem('@theme'); + if (storedTheme) { + setThemeState(storedTheme as Theme); + } + } catch (e) { + console.error('Failed to load theme', e); + } finally { + setIsReady(true); + } + })(); + }, []); + + const setTheme = async (newTheme: Theme) => { + setThemeState(newTheme); + try { + await AsyncStorage.setItem('@theme', newTheme); + } catch (e) { + console.error('Failed to save theme', e); + } + }; + + if (!isReady) { + return null; + } + + const activeTheme = theme === 'system' ? (systemColorScheme || 'light') : theme; + const colors = Colors[activeTheme]; + + return ( + + {children} + + ); +}