Compare commits
3 Commits
notificati
...
notificati
| Author | SHA1 | Date | |
|---|---|---|---|
| 57ac1eb45e | |||
| 145ad73616 | |||
| 7c85e35c61 |
@@ -1,6 +1,4 @@
|
|||||||
<manifest
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
@@ -17,36 +15,13 @@ xmlns:tools="http://schemas.android.com/tools">
|
|||||||
<data android:scheme="https"/>
|
<data android:scheme="https"/>
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
<application
|
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false" android:fullBackupContent="@xml/secure_store_backup_rules" android:dataExtractionRules="@xml/secure_store_data_extraction_rules">
|
||||||
android:name=".MainApplication"
|
<meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/notification_icon_color" tools:replace="android:resource"/>
|
||||||
android:label="@string/app_name"
|
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon"/>
|
||||||
android:icon="@mipmap/ic_launcher"
|
<meta-data android:name="expo.modules.notifications.default_notification_color" android:resource="@color/notification_icon_color"/>
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
<meta-data android:name="expo.modules.notifications.default_notification_icon" android:resource="@drawable/notification_icon"/>
|
||||||
android:allowBackup="true"
|
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
|
||||||
android:theme="@style/AppTheme"
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
||||||
android:supportsRtl="true"
|
|
||||||
android:enableOnBackInvokedCallback="false"
|
|
||||||
android:fullBackupContent="@xml/secure_store_backup_rules"
|
|
||||||
android:dataExtractionRules="@xml/secure_store_data_extraction_rules">
|
|
||||||
<meta-data
|
|
||||||
android:name="com.google.firebase.messaging.default_notification_color"
|
|
||||||
android:resource="@color/notification_icon_color"
|
|
||||||
tools:replace="android:resource"/>
|
|
||||||
<meta-data
|
|
||||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
|
||||||
android:resource="@drawable/notification_icon"/>
|
|
||||||
<meta-data
|
|
||||||
android:name="expo.modules.notifications.default_notification_color"
|
|
||||||
android:resource="@color/notification_icon_color"/>
|
|
||||||
<meta-data
|
|
||||||
android:name="expo.modules.notifications.default_notification_icon"
|
|
||||||
android:resource="@drawable/notification_icon"/>
|
|
||||||
<meta-data
|
|
||||||
android:name="expo.modules.updates.ENABLED"
|
|
||||||
android:value="false"/>
|
|
||||||
<meta-data
|
|
||||||
android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH"
|
|
||||||
android:value="ALWAYS"/>
|
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
||||||
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
|
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@@ -519,7 +519,8 @@ export default function UserLayout() {
|
|||||||
name="job/(tabs)"
|
name="job/(tabs)"
|
||||||
options={{
|
options={{
|
||||||
title: "Job Vacancy",
|
title: "Job Vacancy",
|
||||||
headerLeft: () => <BackButton path="/home" />,
|
// headerLeft: () => <BackButton path="/home" />,
|
||||||
|
// Note: headerLeft di pindahkan ke Tabs Layout
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
|
|||||||
@@ -1,34 +1,72 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import { BackButton } from "@/components";
|
||||||
import { IconHome, IconStatus } from "@/components/_Icon";
|
import { IconHome, IconStatus } from "@/components/_Icon";
|
||||||
import { TabsStyles } from "@/styles/tabs-styles";
|
import { TabsStyles } from "@/styles/tabs-styles";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { Tabs } from "expo-router";
|
import {
|
||||||
|
router,
|
||||||
|
Tabs,
|
||||||
|
useLocalSearchParams,
|
||||||
|
useNavigation
|
||||||
|
} from "expo-router";
|
||||||
|
import { useLayoutEffect } from "react";
|
||||||
|
|
||||||
export default function JobTabsLayout() {
|
export default function JobTabsLayout() {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
const { from, category } = useLocalSearchParams<{
|
||||||
|
from?: string;
|
||||||
|
category?: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// Atur header secara dinamis
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
navigation.setOptions({
|
||||||
|
headerLeft: () => (
|
||||||
|
<BackButton
|
||||||
|
onPress={() => {
|
||||||
|
if (from === "notifications") {
|
||||||
|
router.replace(`/notifications?category=${category}`);
|
||||||
|
} else {
|
||||||
|
if (from) {
|
||||||
|
router.replace(`/${from}` as any);
|
||||||
|
} else {
|
||||||
|
router.navigate("/home");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}, [from, router, navigation]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs screenOptions={TabsStyles}>
|
<>
|
||||||
<Tabs.Screen
|
<Tabs screenOptions={TabsStyles}>
|
||||||
name="index"
|
<Tabs.Screen
|
||||||
options={{
|
name="index"
|
||||||
title: "Beranda",
|
options={{
|
||||||
tabBarIcon: ({ color }) => <IconHome color={color} />,
|
title: "Beranda",
|
||||||
}}
|
tabBarIcon: ({ color }) => <IconHome color={color} />,
|
||||||
/>
|
}}
|
||||||
<Tabs.Screen
|
/>
|
||||||
name="status"
|
<Tabs.Screen
|
||||||
options={{
|
name="status"
|
||||||
title: "Status",
|
options={{
|
||||||
tabBarIcon: ({ color }) => <IconStatus color={color} />,
|
title: "Status",
|
||||||
}}
|
tabBarIcon: ({ color }) => <IconStatus color={color} />,
|
||||||
/>
|
}}
|
||||||
<Tabs.Screen
|
/>
|
||||||
name="archive"
|
<Tabs.Screen
|
||||||
options={{
|
name="archive"
|
||||||
title: "Arsip",
|
options={{
|
||||||
tabBarIcon: ({ color }) => (
|
title: "Arsip",
|
||||||
<Ionicons size={20} name="archive" color={color} />
|
tabBarIcon: ({ color }) => (
|
||||||
),
|
<Ionicons size={20} name="archive" color={color} />
|
||||||
}}
|
),
|
||||||
/>
|
}}
|
||||||
</Tabs>
|
/>
|
||||||
|
</Tabs>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,17 @@ import {
|
|||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { dummyMasterStatus } from "@/lib/dummy-data/_master/status";
|
import { dummyMasterStatus } from "@/lib/dummy-data/_master/status";
|
||||||
import { apiJobGetByStatus } from "@/service/api-client/api-job";
|
import { apiJobGetByStatus } from "@/service/api-client/api-job";
|
||||||
import { useFocusEffect } from "expo-router";
|
import { useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function JobStatus() {
|
export default function JobStatus() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
const { status } = useLocalSearchParams<{ status?: string }>();
|
||||||
|
console.log("STATUS", status);
|
||||||
|
|
||||||
const [activeCategory, setActiveCategory] = useState<string | null>(
|
const [activeCategory, setActiveCategory] = useState<string | null>(
|
||||||
"publish"
|
status || "publish"
|
||||||
);
|
);
|
||||||
const [listData, setListData] = useState<any[]>([]);
|
const [listData, setListData] = useState<any[]>([]);
|
||||||
const [isLoadList, setIsLoadList] = useState(false);
|
const [isLoadList, setIsLoadList] = useState(false);
|
||||||
@@ -60,25 +63,29 @@ export default function JobStatus() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewWrapper headerComponent={scrollComponent} hideFooter>
|
<>
|
||||||
{isLoadList ? (
|
<ViewWrapper headerComponent={scrollComponent} hideFooter>
|
||||||
<LoaderCustom />
|
{isLoadList ? (
|
||||||
) : _.isEmpty(listData) ? (
|
<LoaderCustom />
|
||||||
<TextCustom align="center">Tidak ada data {activeCategory}</TextCustom>
|
) : _.isEmpty(listData) ? (
|
||||||
) : (
|
<TextCustom align="center">
|
||||||
listData.map((e, i) => (
|
Tidak ada data {activeCategory}
|
||||||
<BaseBox
|
</TextCustom>
|
||||||
key={i}
|
) : (
|
||||||
paddingTop={20}
|
listData.map((e, i) => (
|
||||||
paddingBottom={20}
|
<BaseBox
|
||||||
href={`/job/${e?.id}/${activeCategory}/detail`}
|
key={i}
|
||||||
>
|
paddingTop={20}
|
||||||
<TextCustom align="center" bold truncate size="large">
|
paddingBottom={20}
|
||||||
{e?.title}
|
href={`/job/${e?.id}/${activeCategory}/detail`}
|
||||||
</TextCustom>
|
>
|
||||||
</BaseBox>
|
<TextCustom align="center" bold truncate size="large">
|
||||||
))
|
{e?.title}
|
||||||
)}
|
</TextCustom>
|
||||||
</ViewWrapper>
|
</BaseBox>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</ViewWrapper>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default function JobDetailStatus() {
|
|||||||
<StackCustom gap={"xs"}>
|
<StackCustom gap={"xs"}>
|
||||||
{data &&
|
{data &&
|
||||||
data?.catatan &&
|
data?.catatan &&
|
||||||
(status === "draft" || status === "rejected") && (
|
(status === "draft" || status === "reject") && (
|
||||||
<ReportBox text={data?.catatan} />
|
<ReportBox text={data?.catatan} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ export default function JobDetail() {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiJobGetOne({ id: id as string });
|
const response = await apiJobGetOne({ id: id as string });
|
||||||
|
|
||||||
|
console.log("DATA", JSON.stringify(response.data, null,2));
|
||||||
|
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { useState } from "react";
|
|||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function JobCreate() {
|
export default function JobCreate() {
|
||||||
const nextUrl = "/(application)/(user)/job/(tabs)/status";
|
const nextUrl = "/(application)/(user)/job/(tabs)/status?status=review";
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [image, setImage] = useState<string | null>(null);
|
const [image, setImage] = useState<string | null>(null);
|
||||||
|
|||||||
@@ -1,26 +1,52 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BaseBox,
|
BaseBox,
|
||||||
NewWrapper,
|
NewWrapper,
|
||||||
ScrollableCustom,
|
ScrollableCustom,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom
|
TextCustom,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
|
import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
|
||||||
|
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||||
import { AccentColor } from "@/constants/color-palet";
|
import { AccentColor } from "@/constants/color-palet";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { useNotificationStore } from "@/hooks/use-notification-store";
|
import { useNotificationStore } from "@/hooks/use-notification-store";
|
||||||
import { apiGetNotificationsById } from "@/service/api-notifications";
|
import { apiGetNotificationsById } from "@/service/api-notifications";
|
||||||
import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
|
import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
|
||||||
import { formatChatTime } from "@/utils/formatChatTime";
|
import { formatChatTime } from "@/utils/formatChatTime";
|
||||||
import { router, useFocusEffect } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { RefreshControl, View } from "react-native";
|
import { RefreshControl, View } from "react-native";
|
||||||
|
|
||||||
const selectedCategory = (value: string) => {
|
const selectedCategory = (value: string) => {
|
||||||
const category = listOfcategoriesAppNotification.find((c) => c.value === value);
|
const category = listOfcategoriesAppNotification.find(
|
||||||
|
(c) => c.value === value
|
||||||
|
);
|
||||||
return category?.label;
|
return category?.label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fixPath = ({
|
||||||
|
deepLink,
|
||||||
|
categoryApp,
|
||||||
|
}: {
|
||||||
|
deepLink: string;
|
||||||
|
categoryApp: string;
|
||||||
|
}) => {
|
||||||
|
if (categoryApp === "OTHER") {
|
||||||
|
return deepLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
const separator = deepLink.includes("?") ? "&" : "?";
|
||||||
|
|
||||||
|
const fixedPath =
|
||||||
|
`${deepLink}${separator}from=notifications&category=${_.lowerCase(categoryApp)}`;
|
||||||
|
|
||||||
|
console.log("Fix Path", fixedPath);
|
||||||
|
|
||||||
|
return fixedPath;
|
||||||
|
};
|
||||||
|
|
||||||
const BoxNotification = ({
|
const BoxNotification = ({
|
||||||
data,
|
data,
|
||||||
activeCategory,
|
activeCategory,
|
||||||
@@ -28,18 +54,28 @@ const BoxNotification = ({
|
|||||||
data: any;
|
data: any;
|
||||||
activeCategory: string | null;
|
activeCategory: string | null;
|
||||||
}) => {
|
}) => {
|
||||||
|
// console.log("DATA NOTIFICATION", JSON.stringify(data, null, 2));
|
||||||
const { markAsRead } = useNotificationStore();
|
const { markAsRead } = useNotificationStore();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseBox
|
<BaseBox
|
||||||
backgroundColor={data.isRead ? AccentColor.darkblue : AccentColor.blue}
|
backgroundColor={data.isRead ? AccentColor.darkblue : AccentColor.blue}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
console.log(
|
// console.log(
|
||||||
"Notification >",
|
// "Notification >",
|
||||||
selectedCategory(activeCategory as string)
|
// selectedCategory(activeCategory as string)
|
||||||
);
|
// );
|
||||||
router.push(data.deepLink);
|
const newPath = fixPath({
|
||||||
markAsRead(data.id);
|
deepLink: data.deepLink,
|
||||||
|
categoryApp: data.kategoriApp,
|
||||||
|
});
|
||||||
|
|
||||||
|
router.replace(newPath as any);
|
||||||
|
selectedCategory(activeCategory as string);
|
||||||
|
|
||||||
|
if (!data.isRead) {
|
||||||
|
markAsRead(data.id);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
@@ -60,7 +96,10 @@ const BoxNotification = ({
|
|||||||
|
|
||||||
export default function Notifications() {
|
export default function Notifications() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [activeCategory, setActiveCategory] = useState<string | null>("event");
|
const { category } = useLocalSearchParams<{ category?: string }>();
|
||||||
|
const [activeCategory, setActiveCategory] = useState<string | null>(
|
||||||
|
category || "event"
|
||||||
|
);
|
||||||
const [listData, setListData] = useState<any[]>([]);
|
const [listData, setListData] = useState<any[]>([]);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -83,7 +122,7 @@ export default function Notifications() {
|
|||||||
id: user?.id as any,
|
id: user?.id as any,
|
||||||
category: activeCategory as any,
|
category: activeCategory as any,
|
||||||
});
|
});
|
||||||
// console.log("Response Notification", JSON.stringify(response, null, 2));
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setListData(response.data);
|
setListData(response.data);
|
||||||
} else {
|
} else {
|
||||||
@@ -120,7 +159,9 @@ export default function Notifications() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<ListSkeletonComponent/>
|
<ListSkeletonComponent />
|
||||||
|
) : _.isEmpty(listData) ? (
|
||||||
|
<NoDataText text="Belum ada notifikasi" />
|
||||||
) : (
|
) : (
|
||||||
listData.map((e, i) => (
|
listData.map((e, i) => (
|
||||||
<View key={i}>
|
<View key={i}>
|
||||||
|
|||||||
@@ -139,7 +139,9 @@ const ButtonnDot = ({
|
|||||||
isUserCheck: boolean;
|
isUserCheck: boolean;
|
||||||
logout: () => Promise<void>;
|
logout: () => Promise<void>;
|
||||||
}) => {
|
}) => {
|
||||||
const isId = id === undefined || id === null;
|
console.log("[ID] >>", id);
|
||||||
|
|
||||||
|
const isId = id === undefined || id === "undefined";
|
||||||
|
|
||||||
if (isId) {
|
if (isId) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
AlertDefaultSystem,
|
AlertDefaultSystem,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCenteredOnly,
|
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
InformationBox,
|
InformationBox,
|
||||||
NewWrapper,
|
NewWrapper,
|
||||||
StackCustom,
|
StackCustom
|
||||||
ViewWrapper,
|
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
|||||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||||
import ReportBox from "@/components/Box/ReportBox";
|
import ReportBox from "@/components/Box/ReportBox";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import funUpdateStatusJob from "@/screens/Admin/Job/funUpdateStatus";
|
import funUpdateStatusJob from "@/screens/Admin/Job/funUpdateStatus";
|
||||||
import { apiAdminJobGetById } from "@/service/api-admin/api-admin-job";
|
import { apiAdminJobGetById } from "@/service/api-admin/api-admin-job";
|
||||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
@@ -23,8 +24,10 @@ import { useCallback, useState } from "react";
|
|||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminJobDetailStatus() {
|
export default function AdminJobDetailStatus() {
|
||||||
|
const { user } = useAuth();
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [data, setData] = useState<any | null>(null);
|
const [data, setData] = useState<any | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
@@ -92,6 +95,9 @@ export default function AdminJobDetailStatus() {
|
|||||||
const response = await funUpdateStatusJob({
|
const response = await funUpdateStatusJob({
|
||||||
id: id as string,
|
id: id as string,
|
||||||
changeStatus,
|
changeStatus,
|
||||||
|
data: {
|
||||||
|
senderId: user?.id as string,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
@@ -142,12 +148,15 @@ export default function AdminJobDetailStatus() {
|
|||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</BaseBox>
|
||||||
|
|
||||||
{data && data?.catatan && (status === "reject" || status === "review") && (
|
{data &&
|
||||||
<ReportBox text={data?.catatan}/>
|
data?.catatan &&
|
||||||
)}
|
(status === "reject" || status === "review") && (
|
||||||
|
<ReportBox text={data?.catatan} />
|
||||||
|
)}
|
||||||
|
|
||||||
{status === "review" && (
|
{status === "review" && (
|
||||||
<AdminButtonReview
|
<AdminButtonReview
|
||||||
|
isLoading={isLoading}
|
||||||
onPublish={() => {
|
onPublish={() => {
|
||||||
AlertDefaultSystem({
|
AlertDefaultSystem({
|
||||||
title: "Publish",
|
title: "Publish",
|
||||||
@@ -156,6 +165,7 @@ export default function AdminJobDetailStatus() {
|
|||||||
textRight: "Ya",
|
textRight: "Ya",
|
||||||
onPressRight: () => {
|
onPressRight: () => {
|
||||||
handleUpdate({ changeStatus: "publish" });
|
handleUpdate({ changeStatus: "publish" });
|
||||||
|
setIsLoading(true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ import Toast from "react-native-toast-message";
|
|||||||
|
|
||||||
export default function AdminJobRejectInput() {
|
export default function AdminJobRejectInput() {
|
||||||
const { id, status } = useLocalSearchParams();
|
const { id, status } = useLocalSearchParams();
|
||||||
const [data, setData] = useState<any | null>(null);
|
const [data, setData] = useState({
|
||||||
|
catatan: "",
|
||||||
|
senderId: ""
|
||||||
|
});
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
@@ -48,7 +51,7 @@ export default function AdminJobRejectInput() {
|
|||||||
const response = await funUpdateStatusJob({
|
const response = await funUpdateStatusJob({
|
||||||
id: id as string,
|
id: id as string,
|
||||||
changeStatus,
|
changeStatus,
|
||||||
data: data,
|
data: data ,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
@@ -102,8 +105,8 @@ export default function AdminJobRejectInput() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Job" />}
|
headerComponent={<AdminBackButtonAntTitle title="Penolakan Job" />}
|
||||||
>
|
>
|
||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
value={data}
|
value={data?.catatan}
|
||||||
onChangeText={setData}
|
onChangeText={(text) => setData({ ...data, catatan: text })}
|
||||||
placeholder="Masukan alasan"
|
placeholder="Masukan alasan"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
TextCustom,
|
TextCustom,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconPlus } from "@/components/_Icon";
|
import { IconPlus } from "@/components/_Icon";
|
||||||
|
import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent";
|
||||||
|
import NoDataText from "@/components/_ShareComponent/NoDataText";
|
||||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { useNotificationStore } from "@/hooks/use-notification-store";
|
import { useNotificationStore } from "@/hooks/use-notification-store";
|
||||||
@@ -14,6 +16,7 @@ import { apiGetNotificationsById } from "@/service/api-notifications";
|
|||||||
import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
|
import { listOfcategoriesAppNotification } from "@/types/type-notification-category";
|
||||||
import { formatChatTime } from "@/utils/formatChatTime";
|
import { formatChatTime } from "@/utils/formatChatTime";
|
||||||
import { router, Stack, useFocusEffect } from "expo-router";
|
import { router, Stack, useFocusEffect } from "expo-router";
|
||||||
|
import _ from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { RefreshControl, View } from "react-native";
|
import { RefreshControl, View } from "react-native";
|
||||||
|
|
||||||
@@ -66,6 +69,7 @@ export default function AdminNotification() {
|
|||||||
const [activeCategory, setActiveCategory] = useState<string | null>("event");
|
const [activeCategory, setActiveCategory] = useState<string | null>("event");
|
||||||
const [listData, setListData] = useState<any[]>([]);
|
const [listData, setListData] = useState<any[]>([]);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const handlePress = (item: any) => {
|
const handlePress = (item: any) => {
|
||||||
setActiveCategory(item.value);
|
setActiveCategory(item.value);
|
||||||
@@ -80,11 +84,12 @@ export default function AdminNotification() {
|
|||||||
|
|
||||||
const fecthData = async () => {
|
const fecthData = async () => {
|
||||||
try {
|
try {
|
||||||
|
setLoading(true);
|
||||||
const response = await apiGetNotificationsById({
|
const response = await apiGetNotificationsById({
|
||||||
id: user?.id as any,
|
id: user?.id as any,
|
||||||
category: activeCategory as any,
|
category: activeCategory as any,
|
||||||
});
|
});
|
||||||
// console.log("Response Notification", JSON.stringify(response, null, 2));
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setListData(response.data);
|
setListData(response.data);
|
||||||
} else {
|
} else {
|
||||||
@@ -92,6 +97,8 @@ export default function AdminNotification() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error Notification", error);
|
console.log("Error Notification", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,11 +139,20 @@ export default function AdminNotification() {
|
|||||||
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
|
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{listData.map((e, i) => (
|
{loading ? (
|
||||||
<View key={i}>
|
<ListSkeletonComponent />
|
||||||
<BoxNotification data={e} activeCategory={activeCategory as any} />
|
) : _.isEmpty(listData) ? (
|
||||||
</View>
|
<NoDataText text="Belum ada notifikasi" />
|
||||||
))}
|
) : (
|
||||||
|
listData.map((e, i) => (
|
||||||
|
<View key={i}>
|
||||||
|
<BoxNotification
|
||||||
|
data={e}
|
||||||
|
activeCategory={activeCategory as any}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</NewWrapper>
|
</NewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export default function SuperAdminDetail() {
|
|||||||
const response = await apiAdminUserAccessUpdateStatus({
|
const response = await apiAdminUserAccessUpdateStatus({
|
||||||
id: id as string,
|
id: id as string,
|
||||||
role: data?.masterUserRoleId === "2" ? "user" : "admin",
|
role: data?.masterUserRoleId === "2" ? "user" : "admin",
|
||||||
|
category: "role"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
|
|||||||
@@ -9,15 +9,21 @@ import {
|
|||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
|
import { routeUser } from "@/lib/routeApp";
|
||||||
import {
|
import {
|
||||||
apiAdminUserAccessGetById,
|
apiAdminUserAccessGetById,
|
||||||
apiAdminUserAccessUpdateStatus,
|
apiAdminUserAccessUpdateStatus,
|
||||||
} from "@/service/api-admin/api-admin-user-access";
|
} from "@/service/api-admin/api-admin-user-access";
|
||||||
|
import {
|
||||||
|
apiNotificationsSendById
|
||||||
|
} from "@/service/api-notifications";
|
||||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminUserAccessDetail() {
|
export default function AdminUserAccessDetail() {
|
||||||
|
const { user } = useAuth();
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
const [data, setData] = useState<any | null>(null);
|
const [data, setData] = useState<any | null>(null);
|
||||||
const [loadData, setLoadData] = useState(false);
|
const [loadData, setLoadData] = useState(false);
|
||||||
@@ -33,6 +39,7 @@ export default function AdminUserAccessDetail() {
|
|||||||
try {
|
try {
|
||||||
setLoadData(true);
|
setLoadData(true);
|
||||||
const response = await apiAdminUserAccessGetById({ id: id as string });
|
const response = await apiAdminUserAccessGetById({ id: id as string });
|
||||||
|
console.log("[DATA]", JSON.stringify(response.data, null, 2));
|
||||||
|
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -48,6 +55,7 @@ export default function AdminUserAccessDetail() {
|
|||||||
const response = await apiAdminUserAccessUpdateStatus({
|
const response = await apiAdminUserAccessUpdateStatus({
|
||||||
id: id as string,
|
id: id as string,
|
||||||
active: !data?.active,
|
active: !data?.active,
|
||||||
|
category: "access",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
@@ -61,6 +69,21 @@ export default function AdminUserAccessDetail() {
|
|||||||
type: "success",
|
type: "success",
|
||||||
text1: "Update aktifasi berhasil ",
|
text1: "Update aktifasi berhasil ",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (data.active === false) {
|
||||||
|
await apiNotificationsSendById({
|
||||||
|
data: {
|
||||||
|
title: "Akun anda telah diaktifkan",
|
||||||
|
body: "Selamat menjelajahi HIConnect",
|
||||||
|
userLoginId: user?.id || "",
|
||||||
|
kategoriApp: "OTHER",
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeUser.home,
|
||||||
|
},
|
||||||
|
id: id as string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
router.back();
|
router.back();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR UPDATE STATUS]", error);
|
console.log("[ERROR UPDATE STATUS]", error);
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import { StackCustom, TextCustom, ViewWrapper } from "@/components";
|
import { BackButton, StackCustom, TextCustom, ViewWrapper } from "@/components";
|
||||||
|
import { Stack } from "expo-router";
|
||||||
|
|
||||||
export default function NotFoundScreen() {
|
export default function NotFoundScreen() {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<Stack.Screen
|
||||||
|
options={{ headerShown: false, headerLeft: () => <BackButton /> }}
|
||||||
|
/>
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
<StackCustom align="center" gap={0} style={{justifyContent: "center", alignItems: "center", flex: 1}}>
|
<StackCustom
|
||||||
<TextCustom size="large" bold style={{fontSize: 100}}>
|
align="center"
|
||||||
|
gap={0}
|
||||||
|
style={{ justifyContent: "center", alignItems: "center", flex: 1 }}
|
||||||
|
>
|
||||||
|
<TextCustom size="large" bold style={{ fontSize: 100 }}>
|
||||||
404
|
404
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
<TextCustom size="large" bold>
|
<TextCustom size="large" bold>
|
||||||
@@ -12,5 +21,6 @@ export default function NotFoundScreen() {
|
|||||||
</TextCustom>
|
</TextCustom>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
);
|
</>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ const LeftButtonCustom = ({
|
|||||||
path,
|
path,
|
||||||
icon = "arrow-back",
|
icon = "arrow-back",
|
||||||
iconCustom,
|
iconCustom,
|
||||||
|
onPress,
|
||||||
}: {
|
}: {
|
||||||
path?: Href;
|
path?: Href;
|
||||||
icon?: React.ReactNode | any;
|
icon?: React.ReactNode | any;
|
||||||
iconCustom?: React.ReactNode;
|
iconCustom?: React.ReactNode;
|
||||||
|
onPress?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -26,7 +28,7 @@ const LeftButtonCustom = ({
|
|||||||
name={icon}
|
name={icon}
|
||||||
size={20}
|
size={20}
|
||||||
color={MainColor.yellow}
|
color={MainColor.yellow}
|
||||||
onPress={() => (path ? router.replace(path) : router.back())}
|
onPress={() => (onPress ? onPress() : path ? router.replace(path) : router.back())}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
import { apiDeviceTokenDeleted } from "@/service/api-device-token";
|
import { apiDeviceTokenDeleted } from "@/service/api-device-token";
|
||||||
import { IUser } from "@/types/User";
|
import { IUser } from "@/types/User";
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
import * as Device from "expo-device";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { createContext, useEffect, useState } from "react";
|
import { createContext, useEffect, useState } from "react";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
import * as Device from "expo-device";
|
|
||||||
|
|
||||||
// --- Types ---
|
// --- Types ---
|
||||||
type AuthContextType = {
|
type AuthContextType = {
|
||||||
@@ -105,18 +105,6 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// const loginWithNomor = async (nomor: string) => {
|
|
||||||
// setIsLoading(true);
|
|
||||||
// try {
|
|
||||||
// const response = await apiLogin({ nomor: nomor });
|
|
||||||
// await AsyncStorage.setItem("kode_otp", response.kodeId);
|
|
||||||
// } catch (error: any) {
|
|
||||||
// throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
|
||||||
// } finally {
|
|
||||||
// setIsLoading(false);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// --- 2. Validasi OTP & cek user ---
|
// --- 2. Validasi OTP & cek user ---
|
||||||
const validateOtp = async (nomor: string) => {
|
const validateOtp = async (nomor: string) => {
|
||||||
try {
|
try {
|
||||||
@@ -209,7 +197,6 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await apiRegister({ data: userData });
|
const response = await apiRegister({ data: userData });
|
||||||
console.log("[REGISTER FETCH]", JSON.stringify(response, null, 2));
|
|
||||||
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
@@ -239,42 +226,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// const registerUser = async (userData: {
|
|
||||||
// username: string;
|
|
||||||
// nomor: string;
|
|
||||||
// termsOfServiceAccepted: boolean;
|
|
||||||
// }) => {
|
|
||||||
// setIsLoading(true);
|
|
||||||
// try {
|
|
||||||
// const response = await apiRegister({ data: userData });
|
|
||||||
// console.log("response", response);
|
|
||||||
|
|
||||||
// const { token } = response;
|
|
||||||
// if (!response.success) {
|
|
||||||
// Toast.show({
|
|
||||||
// type: "info",
|
|
||||||
// text1: "Info",
|
|
||||||
// text2: response.message,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// setToken(token);
|
|
||||||
// await AsyncStorage.setItem("authToken", token);
|
|
||||||
// Toast.show({
|
|
||||||
// type: "success",
|
|
||||||
// text1: "Sukses",
|
|
||||||
// text2: "Anda berhasil terdaftar",
|
|
||||||
// });
|
|
||||||
// router.replace("/(application)/(user)/waiting-room");
|
|
||||||
// return;
|
|
||||||
// } catch (error: any) {
|
|
||||||
// console.log("Error register", error);
|
|
||||||
// } finally {
|
|
||||||
// setIsLoading(false);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// --- 5. Logout ---
|
// --- 5. Logout ---
|
||||||
|
|
||||||
@@ -284,7 +236,8 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
setToken(null);
|
setToken(null);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
|
|
||||||
const deviceId = Device.osInternalBuildId || Device.modelName || "unknown";
|
const deviceId =
|
||||||
|
Device.osInternalBuildId || Device.modelName || "unknown";
|
||||||
|
|
||||||
await AsyncStorage.removeItem("authToken");
|
await AsyncStorage.removeItem("authToken");
|
||||||
await AsyncStorage.removeItem("userData");
|
await AsyncStorage.removeItem("userData");
|
||||||
|
|||||||
@@ -458,7 +458,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = "HIPMIBadungConnect";
|
PRODUCT_NAME = HIPMIBadungConnect;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -490,7 +490,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = "HIPMIBadungConnect";
|
PRODUCT_NAME = HIPMIBadungConnect;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
|||||||
9
lib/routeApp.ts
Normal file
9
lib/routeApp.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export { routeAdmin, routeUser };
|
||||||
|
|
||||||
|
const routeAdmin = {
|
||||||
|
userAccess: ({ id }: { id: string }) => `/admin/user-access/${id}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const routeUser = {
|
||||||
|
home: `/(user)/home`,
|
||||||
|
};
|
||||||
@@ -7,13 +7,17 @@ const funUpdateStatusJob = async ({
|
|||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
changeStatus: "publish" | "review" | "reject";
|
changeStatus: "publish" | "review" | "reject";
|
||||||
data?: string;
|
data: {
|
||||||
|
catatan?: string;
|
||||||
|
senderId: string;
|
||||||
|
};
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
|
const fixData = data;
|
||||||
const response = await apiAdminJobUpdate({
|
const response = await apiAdminJobUpdate({
|
||||||
id: id,
|
id: id,
|
||||||
status: changeStatus as any,
|
status: changeStatus as any,
|
||||||
data: data,
|
data: fixData as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@@ -17,7 +17,12 @@ export default function Home_BottomFeatureSection() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// console.log("[DATA JOB]", JSON.stringify(response.data, null, 2));
|
// console.log("[DATA JOB]", JSON.stringify(response.data, null, 2));
|
||||||
const result = response.data.slice(-2);
|
const result = response.data
|
||||||
|
.sort(
|
||||||
|
(a: any, b: any) =>
|
||||||
|
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||||
|
)
|
||||||
|
.slice(0, 2);
|
||||||
setListData(result);
|
setListData(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { ITabs } from "@/components/_Interface/types";
|
import { ITabs } from "@/components/_Interface/types";
|
||||||
|
import { Platform } from "react-native";
|
||||||
|
|
||||||
export const tabsHome: any = ({acceptedForumTermsAt, profileId}: {acceptedForumTermsAt: Date, profileId: string}) => [
|
export const tabsHome: any = ({
|
||||||
|
acceptedForumTermsAt,
|
||||||
|
profileId,
|
||||||
|
}: {
|
||||||
|
acceptedForumTermsAt: Date;
|
||||||
|
profileId: string;
|
||||||
|
}) => [
|
||||||
{
|
{
|
||||||
id: "forum",
|
id: "forum",
|
||||||
icon: "chatbubble-ellipses-outline",
|
icon: "chatbubble-ellipses-outline",
|
||||||
@@ -25,8 +32,8 @@ export const tabsHome: any = ({acceptedForumTermsAt, profileId}: {acceptedForumT
|
|||||||
activeIcon: "map",
|
activeIcon: "map",
|
||||||
label: "Maps",
|
label: "Maps",
|
||||||
path: "/maps",
|
path: "/maps",
|
||||||
isActive: true,
|
isActive: Platform.OS === "ios" ? true : false,
|
||||||
disabled: false,
|
disabled: Platform.OS === "ios" ? false : true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "profile",
|
id: "profile",
|
||||||
|
|||||||
@@ -28,13 +28,15 @@ export const apiAdminUserAccessUpdateStatus = async ({
|
|||||||
id,
|
id,
|
||||||
active,
|
active,
|
||||||
role,
|
role,
|
||||||
|
category,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
role?: "user" | "admin" | "super_admin";
|
role?: "user" | "admin" | "super_admin";
|
||||||
|
category: "access" | "role";
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
const response = await apiConfig.put(`/mobile/admin/user/${id}`, {
|
const response = await apiConfig.put(`/mobile/admin/user/${id}?category=${category}`, {
|
||||||
data: {
|
data: {
|
||||||
active,
|
active,
|
||||||
role,
|
role,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export async function apiDeviceTokenDeleted({ userId, deviceId }: { userId: stri
|
|||||||
const response = await apiConfig.delete(
|
const response = await apiConfig.delete(
|
||||||
`/mobile/auth/device-tokens/${userId}?deviceId=${deviceId}`
|
`/mobile/auth/device-tokens/${userId}?deviceId=${deviceId}`
|
||||||
);
|
);
|
||||||
console.log("Device token deleted:", response.data);
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to delete device token:", error);
|
console.error("Failed to delete device token:", error);
|
||||||
@@ -42,7 +42,7 @@ export async function apiDeviceTokenDeleted({ userId, deviceId }: { userId: stri
|
|||||||
export async function apiGetAllTokenDevice() {
|
export async function apiGetAllTokenDevice() {
|
||||||
try {
|
try {
|
||||||
const response = await apiConfig.get(`/mobile/auth/device-tokens`);
|
const response = await apiConfig.get(`/mobile/auth/device-tokens`);
|
||||||
console.log("Device token deleted:", response.data);
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to delete device token:", error);
|
console.error("Failed to delete device token:", error);
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
import { TypeNotificationCategoryApp, TypeOfTilteCategoryApp } from "@/types/type-notification-category";
|
import {
|
||||||
|
NotificationProp,
|
||||||
|
TypeNotificationCategoryApp
|
||||||
|
} from "@/types/type-notification-category";
|
||||||
import { apiConfig } from "./api-config";
|
import { apiConfig } from "./api-config";
|
||||||
|
|
||||||
type NotificationProp = {
|
|
||||||
title: TypeOfTilteCategoryApp;
|
|
||||||
body: string;
|
|
||||||
userLoginId: string;
|
|
||||||
appId?: string;
|
|
||||||
status?: string;
|
|
||||||
type?: "announcement" | "trigger";
|
|
||||||
deepLink?: string;
|
|
||||||
kategoriApp?: TypeNotificationCategoryApp
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function apiNotificationsSend({
|
export async function apiNotificationsSend({
|
||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
@@ -28,12 +20,30 @@ export async function apiNotificationsSend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function apiNotificationsSendById({
|
||||||
|
data,
|
||||||
|
id,
|
||||||
|
}: {
|
||||||
|
data: NotificationProp;
|
||||||
|
id: string;
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.post(`/mobile/notification/${id}`, {
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function apiGetNotificationsById({
|
export async function apiGetNotificationsById({
|
||||||
id,
|
id,
|
||||||
category,
|
category,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
category: TypeNotificationCategoryApp
|
category: TypeNotificationCategoryApp;
|
||||||
}) {
|
}) {
|
||||||
console.log("ID", id);
|
console.log("ID", id);
|
||||||
console.log("Category", category);
|
console.log("Category", category);
|
||||||
@@ -49,7 +59,13 @@ export async function apiGetNotificationsById({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apiNotificationUnreadCount({ id, role }: { id: string, role: "user" | "admin" }) {
|
export async function apiNotificationUnreadCount({
|
||||||
|
id,
|
||||||
|
role,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
role: "user" | "admin";
|
||||||
|
}) {
|
||||||
try {
|
try {
|
||||||
const response = await apiConfig.get(
|
const response = await apiConfig.get(
|
||||||
`/mobile/notification/${id}/unread-count?role=${role}`
|
`/mobile/notification/${id}/unread-count?role=${role}`
|
||||||
@@ -62,12 +78,11 @@ export async function apiNotificationUnreadCount({ id, role }: { id: string, rol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function apiNotificationMarkAsRead({ id }: { id: string }) {
|
||||||
export async function apiNotificationMarkAsRead({id}: {id: string}) {
|
|
||||||
try {
|
try {
|
||||||
const response = await apiConfig.put(`/mobile/notification/${id}`);
|
const response = await apiConfig.put(`/mobile/notification/${id}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
export type NotificationProp = {
|
||||||
|
title: TypeOfTilteCategoryApp | string
|
||||||
|
body: string;
|
||||||
|
userLoginId?: string;
|
||||||
|
appId?: string;
|
||||||
|
status?: string;
|
||||||
|
type?: "announcement" | "trigger";
|
||||||
|
deepLink?: string;
|
||||||
|
kategoriApp?: TypeNotificationCategoryApp
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type TypeNotificationCategoryApp =
|
export type TypeNotificationCategoryApp =
|
||||||
| "EVENT"
|
| "EVENT"
|
||||||
| "JOB"
|
| "JOB"
|
||||||
@@ -6,9 +19,9 @@ export type TypeNotificationCategoryApp =
|
|||||||
| "INVESTASI"
|
| "INVESTASI"
|
||||||
| "COLLABORATION"
|
| "COLLABORATION"
|
||||||
| "FORUM"
|
| "FORUM"
|
||||||
| "ACCESS";
|
| "OTHER";
|
||||||
|
|
||||||
export type TypeOfTilteCategoryApp = "Pendaftaran User Baru" | "Other" | string;
|
export type TypeOfTilteCategoryApp = "Pendaftaran User Baru" | "Other"
|
||||||
|
|
||||||
export const listOfcategoriesAppNotification = [
|
export const listOfcategoriesAppNotification = [
|
||||||
{ value: "event", label: "Event" },
|
{ value: "event", label: "Event" },
|
||||||
@@ -18,4 +31,5 @@ export const listOfcategoriesAppNotification = [
|
|||||||
{ value: "investasi", label: "Investasi" },
|
{ value: "investasi", label: "Investasi" },
|
||||||
{ value: "forum", label: "Forum" },
|
{ value: "forum", label: "Forum" },
|
||||||
{ value: "collaboration", label: "Collaboration" },
|
{ value: "collaboration", label: "Collaboration" },
|
||||||
|
{ value: "other", label: "Lainnya" },
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user