Notifikasi admin to user
Fix: - android/app/src/main/AndroidManifest.xml - app/(application)/(user)/job/(tabs)/_layout.tsx - app/(application)/(user)/job/[id]/index.tsx - app/(application)/(user)/notifications/index.tsx - app/(application)/(user)/profile/[id]/index.tsx - app/(application)/admin/job/[id]/[status]/index.tsx - app/(application)/admin/notification/index.tsx - app/+not-found.tsx - ios/HIPMIBadungConnect.xcodeproj/project.pbxproj - screens/Admin/Job/funUpdateStatus.ts - screens/Home/bottomFeatureSection.tsx ### No Issue
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import { BackButton } from "@/components";
|
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 {
|
import {
|
||||||
Stack,
|
router,
|
||||||
Tabs,
|
Tabs,
|
||||||
useLocalSearchParams,
|
useLocalSearchParams,
|
||||||
router,
|
useNavigation
|
||||||
useNavigation,
|
|
||||||
} from "expo-router";
|
} from "expo-router";
|
||||||
import { useLayoutEffect } from "react";
|
import { useLayoutEffect } from "react";
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export default function JobTabsLayout() {
|
|||||||
if (from) {
|
if (from) {
|
||||||
router.replace(`/${from}` as any);
|
router.replace(`/${from}` as any);
|
||||||
} else {
|
} else {
|
||||||
router.back();
|
router.navigate("/home");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BaseBox,
|
BaseBox,
|
||||||
NewWrapper,
|
NewWrapper,
|
||||||
@@ -32,10 +33,18 @@ const fixPath = ({
|
|||||||
deepLink: string;
|
deepLink: string;
|
||||||
categoryApp: string;
|
categoryApp: string;
|
||||||
}) => {
|
}) => {
|
||||||
const fixPath =
|
if (categoryApp === "OTHER") {
|
||||||
deepLink + "&from=notifications&category=" + _.lowerCase(categoryApp);
|
return deepLink;
|
||||||
|
}
|
||||||
|
|
||||||
return fixPath;
|
const separator = deepLink.includes("?") ? "&" : "?";
|
||||||
|
|
||||||
|
const fixedPath =
|
||||||
|
`${deepLink}${separator}from=notifications&category=${_.lowerCase(categoryApp)}`;
|
||||||
|
|
||||||
|
console.log("Fix Path", fixedPath);
|
||||||
|
|
||||||
|
return fixedPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BoxNotification = ({
|
const BoxNotification = ({
|
||||||
@@ -114,7 +123,6 @@ export default function Notifications() {
|
|||||||
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 {
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export default function AdminNotification() {
|
|||||||
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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
</>
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -7,13 +7,17 @@ const funUpdateStatusJob = async ({
|
|||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
changeStatus: "publish" | "review" | "reject";
|
changeStatus: "publish" | "review" | "reject";
|
||||||
data?: any;
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user