Compare commits
26 Commits
donation/2
...
api/15-aug
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b6c360500 | |||
| 6f5d04e73f | |||
| 4f4d9b2f05 | |||
| f2ba8fd4b1 | |||
| 70a6de6cc0 | |||
| 0fa6d54dbe | |||
| 40cb0bfc47 | |||
| 52c16b25b7 | |||
| 6f3cc03fa5 | |||
| c2f18948bf | |||
| 25884b64e7 | |||
| 21f89aeec5 | |||
| 72f760c6a9 | |||
| 8750660fc7 | |||
| d0b64f8109 | |||
| 25f600e8c2 | |||
| 72e8d7aabd | |||
| 29377c0bb0 | |||
| 88cf3321e1 | |||
| 9ad1ccfd5f | |||
| d47fff469b | |||
| bcc0e02581 | |||
| caf250c5ca | |||
| c4c16f19c1 | |||
| 48c34aa26c | |||
| e16b0c2fce |
4
app.json
@@ -4,7 +4,7 @@
|
||||
"slug": "hipmi-mobile",
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/images/logo-hipmi.png",
|
||||
"icon": "./assets/images/icon.png",
|
||||
"scheme": "hipmimobile",
|
||||
"userInterfaceStyle": "automatic",
|
||||
"newArchEnabled": true,
|
||||
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
"foregroundImage": "./assets/images/adaptive-icon.png",
|
||||
"foregroundImage": "./assets/images/splash-icon.png",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"edgeToEdgeEnabled": true,
|
||||
|
||||
@@ -477,6 +477,20 @@ export default function UserLayout() {
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="donation/[id]/(transaction-flow)/[transaction]/success"
|
||||
options={{
|
||||
title: "Donasi Berhasil",
|
||||
headerLeft: () => <BackButton />,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="donation/[id]/(transaction-flow)/[transaction]/failed"
|
||||
options={{
|
||||
title: "Donasi Gagal",
|
||||
headerLeft: () => <BackButton />,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* ========== End Donation Section ========= */}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import {
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DummyLandscapeImage,
|
||||
Grid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DummyLandscapeImage,
|
||||
Grid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
||||
import { router } from "expo-router";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function DonationMyDonation() {
|
||||
@@ -17,6 +18,19 @@ export default function DonationMyDonation() {
|
||||
);
|
||||
return dummyMasterStatusTransaction[randomIndex];
|
||||
});
|
||||
|
||||
const handlePress = (value: string) => {
|
||||
if (value === "menunggu") {
|
||||
router.push(`/donation/${value}/(transaction-flow)/123/invoice`);
|
||||
} else if (value === "proses") {
|
||||
router.push(`/donation/${value}/(transaction-flow)/123/process`);
|
||||
} else if (value === "berhasil") {
|
||||
router.push(`/donation/${value}/(transaction-flow)/123/success`);
|
||||
} else if (value === "gagal") {
|
||||
router.push(`/donation/${value}/(transaction-flow)/123/failed`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ViewWrapper hideFooter>
|
||||
{randomStatusData.map((item, index) => (
|
||||
@@ -24,11 +38,13 @@ export default function DonationMyDonation() {
|
||||
key={index}
|
||||
paddingTop={7}
|
||||
paddingBottom={7}
|
||||
href={`/investment/${index}`}
|
||||
onPress={() => {
|
||||
handlePress(item.value);
|
||||
}}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={5}>
|
||||
<DummyLandscapeImage height={100} />
|
||||
<DummyLandscapeImage height={100} unClickPath />
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<View />
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default function DonasiFailed() {
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<TextCustom bold align="center">
|
||||
Transaksi anda gagal karena bukti transfer tidak sesuai dengan
|
||||
data kami. Jika ini masalah khusus silahkan hubungi pada kontak
|
||||
whatsapp kami.
|
||||
</TextCustom>
|
||||
|
||||
<FontAwesome6
|
||||
name="whatsapp"
|
||||
size={50}
|
||||
color={MainColor.green}
|
||||
style={GStyles.alignSelfCenter}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<TextCustom bold align="center" size="large">
|
||||
Detail Transaksi
|
||||
</TextCustom>
|
||||
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col span={5}>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={7}>
|
||||
<TextCustom style={{ paddingLeft: 10 }}>
|
||||
{item.value}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 750.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: `${dayjs(new Date()).format("DD/MM/YYYY")}`,
|
||||
},
|
||||
];
|
||||
@@ -13,12 +13,12 @@ import { MainColor } from "@/constants/color-palet";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function DonationInvoice() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const { id, transaction } = useLocalSearchParams();
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
<InformationBox text="Mohon transfer ke rekening dibawah" />
|
||||
<InformationBox text={`Mohon transfer donasi anda ke rekening dibawah dengan Id: ${transaction}`} />
|
||||
<BaseBox>
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom>Nama BANK</TextCustom>
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default function DonationSuccess() {
|
||||
return (
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<FontAwesome6
|
||||
name="money-bill-wave"
|
||||
size={100}
|
||||
color={MainColor.green}
|
||||
style={GStyles.alignSelfCenter}
|
||||
/>
|
||||
|
||||
<TextCustom bold align="center">
|
||||
Terimakasih telah percaya pada kami untuk mengelola dana anda!
|
||||
Info mengenai update Penggalian Dana ini bisa di lihat di kolom
|
||||
berita.
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<TextCustom bold align="center" size="large">
|
||||
Detail Transaksi
|
||||
</TextCustom>
|
||||
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col span={5}>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={7}>
|
||||
<TextCustom style={{ paddingLeft: 10 }}>
|
||||
{item.value}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Bank",
|
||||
value: " BCA",
|
||||
},
|
||||
{
|
||||
label: "Rekening Penerima",
|
||||
value: "Himpunan Pengusaha Muda Indonesia",
|
||||
},
|
||||
{
|
||||
label: "No Rekening",
|
||||
value: "2304235678854332",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 750.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: `${dayjs(new Date()).format("DD/MM/YYYY")}`,
|
||||
},
|
||||
];
|
||||
@@ -57,7 +57,7 @@ export default function DonationCreateStory() {
|
||||
<Spacing />
|
||||
<ButtonCustom
|
||||
onPress={() => {
|
||||
router.navigate(`/donation/(tabs)/status`);
|
||||
router.replace(`/donation/(tabs)/status`);
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function DonationCreate() {
|
||||
<Spacing />
|
||||
<ButtonCustom
|
||||
onPress={() => {
|
||||
router.push("/donation/create-story");
|
||||
router.replace("/donation/create-story");
|
||||
}}
|
||||
>
|
||||
Selanjutnya
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ViewWrapper } from "@/components";
|
||||
import TabsTwoHeaderCustom from "@/components/_ShareComponent/TabsTwoHeaderCustom";
|
||||
import TabsTwoButtonCustom from "@/components/_ShareComponent/TabsTwoHeaderCustom";
|
||||
import Voting_BoxPublishSection from "@/screens/Voting/BoxPublishSection";
|
||||
import { useState } from "react";
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function VotingHistory() {
|
||||
<ViewWrapper
|
||||
hideFooter
|
||||
headerComponent={
|
||||
<TabsTwoHeaderCustom
|
||||
<TabsTwoButtonCustom
|
||||
leftValue="all"
|
||||
rightValue="main"
|
||||
leftText="Semua Riwayat"
|
||||
|
||||
@@ -7,6 +7,8 @@ export default function ApplicationLayout() {
|
||||
<>
|
||||
<Stack screenOptions={HeaderStyles}>
|
||||
<Stack.Screen name="(user)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="admin" options={{ headerShown: false }} />
|
||||
|
||||
|
||||
{/* Take Picture */}
|
||||
<Stack.Screen
|
||||
|
||||
236
app/(application)/admin/_layout.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
DrawerCustom,
|
||||
GridComponentView,
|
||||
MenuDrawerDynamicGrid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
} from "@/components";
|
||||
import DrawerAdmin from "@/components/Drawer/DrawerAdmin";
|
||||
import NavbarMenu from "@/components/Drawer/NavbarMenu";
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_MEDIUM, ICON_SIZE_SMALL, ICON_SIZE_XLARGE } from "@/constants/constans-value";
|
||||
import { adminListMenu } from "@/screens/Admin/listPageAdmin";
|
||||
import { GStyles } from "@/styles/global-styles";
|
||||
import { FontAwesome6, Ionicons } from "@expo/vector-icons";
|
||||
import { router, Stack } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminLayout() {
|
||||
const [openDrawerNavbar, setOpenDrawerNavbar] = useState(false);
|
||||
const [openDrawerUser, setOpenDrawerUser] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Stack
|
||||
screenOptions={{
|
||||
title: "HIPMI DASHBOARD",
|
||||
headerStyle: GStyles.headerStyle,
|
||||
headerTitleStyle: GStyles.headerTitleStyle,
|
||||
headerTitleAlign: "center",
|
||||
contentStyle: {
|
||||
borderBottomColor: AccentColor.blue,
|
||||
},
|
||||
headerLeft: () => (
|
||||
<Ionicons
|
||||
name="menu"
|
||||
size={ICON_SIZE_XLARGE}
|
||||
color={MainColor.white}
|
||||
onPress={() => setOpenDrawerNavbar(true)}
|
||||
/>
|
||||
),
|
||||
headerRight: () => (
|
||||
<FontAwesome6
|
||||
name="circle-user"
|
||||
size={ICON_SIZE_MEDIUM}
|
||||
color={MainColor.white}
|
||||
onPress={() => setOpenDrawerUser(true)}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="dashboard" />
|
||||
{/* ================== Investment Start ================== */}
|
||||
<Stack.Screen name="investment/index" />
|
||||
{/* ================== Investment End ================== */}
|
||||
|
||||
{/* ================== Maps Start ================== */}
|
||||
<Stack.Screen name="maps" />
|
||||
{/* ================== Maps End ================== */}
|
||||
|
||||
{/* ================== App Information Start ================== */}
|
||||
<Stack.Screen name="app-information/index" />
|
||||
{/* ================== App Information End ================== */}
|
||||
|
||||
{/* ================== Job Start ================== */}
|
||||
<Stack.Screen name="job/index" />
|
||||
{/* <Stack.Screen name="job/publish" />
|
||||
<Stack.Screen name="job/review" />
|
||||
<Stack.Screen name="job/reject" /> */}
|
||||
<Stack.Screen name="job/[status]/status" />
|
||||
<Stack.Screen name="job/[id]/[status]/index" />
|
||||
|
||||
{/* ================== Collaboration Start ================== */}
|
||||
<Stack.Screen name="collaboration/index" />
|
||||
<Stack.Screen name="collaboration/publish" />
|
||||
<Stack.Screen name="collaboration/group" />
|
||||
<Stack.Screen name="collaboration/reject" />
|
||||
<Stack.Screen name="collaboration/[id]/[status]"/>
|
||||
<Stack.Screen name="collaboration/[id]/group"/>
|
||||
{/* ================== Collaboration End ================== */}
|
||||
|
||||
{/* ================== Forum Start ================== */}
|
||||
<Stack.Screen name="forum/index" />
|
||||
<Stack.Screen name="forum/[id]/index" />
|
||||
<Stack.Screen name="forum/report-comment"/>
|
||||
<Stack.Screen name="forum/report-posting"/>
|
||||
<Stack.Screen name="forum/[id]/list-report-posting" />
|
||||
<Stack.Screen name="forum/[id]/list-report-comment"/>
|
||||
{/* ================== Forum End ================== */}
|
||||
|
||||
{/* ================== Voting Start ================== */}
|
||||
<Stack.Screen name="voting/index" />
|
||||
<Stack.Screen name="voting/[status]/status" />
|
||||
<Stack.Screen name="voting/[id]/[status]/index" />
|
||||
<Stack.Screen name="voting/[id]/reject-input"/>
|
||||
{/* ================== Voting End ================== */}
|
||||
|
||||
{/* ================== Event Start ================== */}
|
||||
<Stack.Screen name="event/index" />
|
||||
<Stack.Screen name="event/[status]/status" />
|
||||
<Stack.Screen name="event/type-of-event"/>
|
||||
<Stack.Screen name="event/type-create"/>
|
||||
<Stack.Screen name="event/type-update"/>
|
||||
{/* <Stack.Screen name="event/[id]/[status]/index" />
|
||||
<Stack.Screen name="event/[id]/reject-input"/> */}
|
||||
{/* ================== Event End ================== */}
|
||||
|
||||
{/* ================== Donasi Start ================== */}
|
||||
{/* <Stack.Screen name="donation/index" /> */}
|
||||
{/* <Stack.Screen name="donation/[status]/status" /> */}
|
||||
{/* <Stack.Screen name="donation/[id]/[status]/index" />
|
||||
<Stack.Screen name="donation/[id]/reject-input"/> */}
|
||||
{/* ================== Donasi End ================== */}
|
||||
</Stack>
|
||||
|
||||
<DrawerAdmin
|
||||
isVisible={openDrawerNavbar}
|
||||
onClose={() => setOpenDrawerNavbar(false)}
|
||||
>
|
||||
<StackCustom gap={"xs"}>
|
||||
<Ionicons
|
||||
name="close"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
onPress={() => setOpenDrawerNavbar(false)}
|
||||
style={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
|
||||
<NavbarMenu
|
||||
items={adminListMenu}
|
||||
onClose={() => setOpenDrawerNavbar(false)}
|
||||
/>
|
||||
</StackCustom>
|
||||
</DrawerAdmin>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerUser}
|
||||
closeDrawer={() => setOpenDrawerUser(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<StackCustom>
|
||||
<GridComponentView
|
||||
leftIcon={
|
||||
<Ionicons
|
||||
name="person"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<TextCustom>Username</TextCustom>
|
||||
</GridComponentView>
|
||||
<GridComponentView
|
||||
leftIcon={
|
||||
<Ionicons
|
||||
name="ribbon-outline"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<TextCustom>User Role</TextCustom>
|
||||
</GridComponentView>
|
||||
|
||||
<MenuDrawerDynamicGrid
|
||||
columns={3}
|
||||
data={[
|
||||
{
|
||||
label: "Notifikasi",
|
||||
value: "notification",
|
||||
icon: (
|
||||
<Ionicons
|
||||
name="notifications"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
),
|
||||
path: "/admin/notification",
|
||||
},
|
||||
{
|
||||
label: "Kembali ke User",
|
||||
value: "back-to-user",
|
||||
icon: (
|
||||
<Ionicons
|
||||
name="git-compare"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
),
|
||||
path: "" as any,
|
||||
},
|
||||
{
|
||||
label: "Keluar",
|
||||
value: "logout",
|
||||
icon: (
|
||||
<Ionicons
|
||||
name="log-out"
|
||||
size={ICON_SIZE_SMALL}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
),
|
||||
path: "" as any,
|
||||
color: MainColor.red,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
if (item.value === "notification") {
|
||||
router.push("/admin/notification");
|
||||
setOpenDrawerUser(false);
|
||||
} else if (item.value === "back-to-user") {
|
||||
AlertDefaultSystem({
|
||||
title: "Kembali ke User",
|
||||
message: "Apakah Anda yakin ingin kembali ke user?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressRight: () => {
|
||||
router.replace(`/(application)/(user)/profile/${123}`);
|
||||
},
|
||||
});
|
||||
} else if (item.value === "logout") {
|
||||
AlertDefaultSystem({
|
||||
title: "Keluar",
|
||||
message: "Apakah Anda yakin ingin keluar?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Keluar",
|
||||
onPressRight: () => {
|
||||
router.replace("/");
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminAppInformation_BusinessFieldDetail() {
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
Update
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Update Bidang Bisnis" />
|
||||
|
||||
<TextInputCustom
|
||||
label="Nama Bidang Bisnis"
|
||||
placeholder="Masukan Nama Bidang Bisnis"
|
||||
required
|
||||
/>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminAppInformation_BusinessFieldCreate() {
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
Tambah
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Tambah Bidang Bisnis" />
|
||||
|
||||
<TextInputCustom
|
||||
label="Nama Bidang Bisnis"
|
||||
placeholder="Masukan Nama Bidang Bisnis"
|
||||
required
|
||||
/>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
88
app/(application)/admin/app-information/index.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
ScrollableCustom,
|
||||
StackCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminAppInformation_BusinessFieldSection from "@/screens/Admin/App-Information/BusinessFieldSection";
|
||||
import AdminAppInformation_Bank from "@/screens/Admin/App-Information/InformationBankSection";
|
||||
import AdminAppInformation_StickerSection from "@/screens/Admin/App-Information/StickerSection";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminInformation() {
|
||||
const [activeCategory, setActiveCategory] = useState<string | null>("bank");
|
||||
const [activePage, setActivePage] = useState<string>("Informasi Bank");
|
||||
|
||||
const handlePress = (item: any) => {
|
||||
setActiveCategory(item.value);
|
||||
setActivePage(item.label);
|
||||
// tambahkan logika lain seperti filter dsb.
|
||||
};
|
||||
|
||||
const scrollComponent = (
|
||||
<StackCustom>
|
||||
<ScrollableCustom
|
||||
data={listPage}
|
||||
onButtonPress={handlePress}
|
||||
activeId={activeCategory as any}
|
||||
/>
|
||||
</StackCustom>
|
||||
);
|
||||
|
||||
const renderContent = () => {
|
||||
switch (activeCategory) {
|
||||
case "bank":
|
||||
return <AdminAppInformation_Bank />;
|
||||
case "business":
|
||||
return <AdminAppInformation_BusinessFieldSection />;
|
||||
case "sticker":
|
||||
return <AdminAppInformation_StickerSection />;
|
||||
default:
|
||||
return <AdminAppInformation_Bank />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={scrollComponent}>
|
||||
<AdminComp_BoxTitle
|
||||
title={activePage}
|
||||
rightComponent={
|
||||
<AdminActionIconPlus
|
||||
onPress={() => {
|
||||
if (activeCategory === "bank") {
|
||||
router.push("/admin/app-information/information-bank/create");
|
||||
} else if (activeCategory === "business") {
|
||||
router.push("/admin/app-information/business-field/create");
|
||||
} else if (activeCategory === "sticker") {
|
||||
router.push("/admin/app-information/sticker/create");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{renderContent()}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listPage = [
|
||||
{
|
||||
id: "1",
|
||||
label: "Informasi Bank",
|
||||
value: "bank",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
label: "Bidang Bisnis",
|
||||
value: "business",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
label: "Stiker",
|
||||
value: "sticker",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminAppInformation_BankDetail() {
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
Update
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Update Bank" />
|
||||
|
||||
<StackCustom>
|
||||
<TextInputCustom
|
||||
label="Nama Bank"
|
||||
placeholder="Masukan Nama Bank"
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInputCustom
|
||||
label="Nama Rekening"
|
||||
placeholder="Masukan Nama Rekening"
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInputCustom
|
||||
label="Nomor Rekening"
|
||||
placeholder="Masukan Nomor Rekening"
|
||||
required
|
||||
/>
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminAppInformation_BankCreate() {
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
Tambah
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Tambah Daftar Bank" />
|
||||
|
||||
<StackCustom>
|
||||
<TextInputCustom
|
||||
label="Nama Bank"
|
||||
placeholder="Masukan Nama Bank"
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInputCustom
|
||||
label="Nama Rekening"
|
||||
placeholder="Masukan Nama Rekening"
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInputCustom
|
||||
label="Nomor Rekening"
|
||||
placeholder="Masukan Nomor Rekening"
|
||||
required
|
||||
/>
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCenteredOnly,
|
||||
ButtonCustom,
|
||||
CheckboxCustom,
|
||||
CheckboxGroup,
|
||||
LandscapeFrameUploaded,
|
||||
SelectCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { dummyMasterEmotions } from "@/lib/dummy-data/_master/emotions";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminAppInformation_StickerCreate() {
|
||||
const [value, setValue] = useState<string | null>(null);
|
||||
const [selectedEmotions, setSelectedEmotions] = useState<string[]>([]);
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Edit Stiker" />
|
||||
|
||||
<StackCustom gap={"xs"}>
|
||||
<LandscapeFrameUploaded />
|
||||
<ButtonCenteredOnly icon="upload" onPress={() => {}}>
|
||||
Upload
|
||||
</ButtonCenteredOnly>
|
||||
<Spacing />
|
||||
|
||||
<SelectCustom
|
||||
required
|
||||
label="Jenis Kelamin"
|
||||
data={[
|
||||
{ label: "Laki-laki", value: "laki-laki" },
|
||||
{ label: "Perempuan", value: "perempuan" },
|
||||
]}
|
||||
value={value}
|
||||
onChange={(value) => setValue(value as string)}
|
||||
/>
|
||||
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<TextCustom>Pilih Emosi Stiker</TextCustom>
|
||||
<TextCustom color="red">*</TextCustom>
|
||||
</View>
|
||||
<Spacing height={10} />
|
||||
|
||||
<CheckboxGroup
|
||||
value={selectedEmotions}
|
||||
onChange={(value) => setSelectedEmotions(value as string[])}
|
||||
>
|
||||
<StackCustom>
|
||||
{dummyMasterEmotions.map((e) => (
|
||||
<CheckboxCustom
|
||||
size={25}
|
||||
key={e.id}
|
||||
label={<TextCustom>{e.label}</TextCustom>}
|
||||
valueKey={e.id}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</CheckboxGroup>
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
84
app/(application)/admin/app-information/sticker/create.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCenteredOnly,
|
||||
ButtonCustom,
|
||||
CheckboxCustom,
|
||||
CheckboxGroup,
|
||||
LandscapeFrameUploaded,
|
||||
SelectCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { dummyMasterEmotions } from "@/lib/dummy-data/_master/emotions";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminAppInformation_StickerCreate() {
|
||||
const [value, setValue] = useState<string | null>(null);
|
||||
const [selectedEmotions, setSelectedEmotions] = useState<string[]>([]);
|
||||
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
Tambah
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper footerComponent={buttonSubmit}>
|
||||
<StackCustom>
|
||||
<AdminBackButtonAntTitle title="Tambah Stiker" />
|
||||
|
||||
<StackCustom gap={"xs"}>
|
||||
<LandscapeFrameUploaded />
|
||||
<ButtonCenteredOnly icon="upload" onPress={() => {}}>
|
||||
Upload
|
||||
</ButtonCenteredOnly>
|
||||
<Spacing />
|
||||
|
||||
<SelectCustom
|
||||
required
|
||||
label="Jenis Kelamin"
|
||||
data={[
|
||||
{ label: "Laki-laki", value: "laki-laki" },
|
||||
{ label: "Perempuan", value: "perempuan" },
|
||||
]}
|
||||
value={value}
|
||||
onChange={(value) => setValue(value as string)}
|
||||
/>
|
||||
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<TextCustom>Pilih Emosi Stiker</TextCustom>
|
||||
<TextCustom color="red">*</TextCustom>
|
||||
</View>
|
||||
<Spacing height={10} />
|
||||
|
||||
<CheckboxGroup
|
||||
value={selectedEmotions}
|
||||
onChange={(value) => setSelectedEmotions(value as string[])}
|
||||
>
|
||||
<StackCustom>
|
||||
{dummyMasterEmotions.map((e) => (
|
||||
<CheckboxCustom
|
||||
size={25}
|
||||
key={e.id}
|
||||
label={<TextCustom>{e.label}</TextCustom>}
|
||||
valueKey={e.id}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</CheckboxGroup>
|
||||
</StackCustom>
|
||||
</StackCustom>
|
||||
<Spacing/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
89
app/(application)/admin/collaboration/[id]/[status].tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import {
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
Grid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminCollaborationPublish() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
console.log("params:", id, status);
|
||||
const bottomFooter = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
backgroundColor={MainColor.red}
|
||||
textColor="white"
|
||||
onPress={() => {}}
|
||||
>
|
||||
Reject
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title={`Detail ${status}`} />}
|
||||
footerComponent={bottomFooter}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||
>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||
<TextCustom>{item.value}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Judul Proyek",
|
||||
value:
|
||||
"Judul Proyek: Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
{
|
||||
label: "Industri",
|
||||
value: "Kesehatan",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Partisipan ",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
label: "Lokasi",
|
||||
value: "Kuta Selatan, Bali",
|
||||
},
|
||||
{
|
||||
label: "Tujuan Proyek",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
},
|
||||
{
|
||||
label: "Keuntungan",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
},
|
||||
];
|
||||
97
app/(application)/admin/collaboration/[id]/group.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminCollaborationGroup() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("params:", id);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle title={`Detail Group ${id}`} />
|
||||
}
|
||||
>
|
||||
<StackCustom gap={"xs"}>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||
>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||
<TextCustom>{item.value}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<TextCustom align="center">Anggota</TextCustom>
|
||||
|
||||
{Array.from({ length: 10 }).map((_, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||
>
|
||||
<TextCustom bold>Username</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||
<TextCustom>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Admin Group",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Nama Group",
|
||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
{
|
||||
label: "Industri",
|
||||
value: "Kesehatan",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Partisipan ",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
label: "Lokasi",
|
||||
value: "Kuta Selatan, Bali",
|
||||
},
|
||||
{
|
||||
label: "Tujuan Proyek",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
},
|
||||
{
|
||||
label: "Keuntungan",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
},
|
||||
];
|
||||
69
app/(application)/admin/collaboration/group.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminCollaborationGroup() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||
<StackCustom gap={"xs"}>
|
||||
<AdminComp_BoxTitle title="Group" />
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Admin Group"
|
||||
title3="Nama Group"
|
||||
/>
|
||||
<Spacing height={10} />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/collaboration/${index}/group`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={
|
||||
<TextCustom truncate={1}>Username username </TextCustom>
|
||||
}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae
|
||||
mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
37
app/(application)/admin/collaboration/index.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { StackCustom, ViewWrapper } from "@/components";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { Entypo, FontAwesome } from "@expo/vector-icons";
|
||||
|
||||
export default function AdminCollaboration() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 4,
|
||||
icon: <Entypo name="publish" size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Group",
|
||||
value: 7,
|
||||
icon: <FontAwesome name="group" size={25} color={MainColor.yellow} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 7,
|
||||
icon: <FontAwesome name="warning" size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
70
app/(application)/admin/collaboration/publish.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminCollaborationPublish() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||
<StackCustom gap={"xs"}>
|
||||
<AdminComp_BoxTitle title="Publish" />
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Proyek"
|
||||
/>
|
||||
<Spacing height={10} />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/collaboration/${index}/publish`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={
|
||||
<TextCustom truncate={1}>Username username </TextCustom>
|
||||
}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae
|
||||
mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
69
app/(application)/admin/collaboration/reject.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminCollaborationReject() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Collaboration" />}>
|
||||
<StackCustom gap={"xs"}>
|
||||
<AdminComp_BoxTitle title="Reject" />
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Proyek"
|
||||
/>
|
||||
<Spacing height={10} />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/collaboration/${index}/reject`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={
|
||||
<TextCustom truncate={1}>Username username </TextCustom>
|
||||
}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae
|
||||
mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
40
app/(application)/admin/dashboard.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
export default function AdminDashboard() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<StackCustom>
|
||||
<TextCustom bold size={30}>
|
||||
Main Dashboard
|
||||
</TextCustom>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "User",
|
||||
value: 4,
|
||||
icon: <Ionicons name="people" size={30} color={MainColor.yellow} />,
|
||||
},
|
||||
{
|
||||
label: "Portofolio",
|
||||
value: 7,
|
||||
icon: (
|
||||
<Ionicons name="id-card-outline" size={30} color={MainColor.yellow} />
|
||||
),
|
||||
},
|
||||
];
|
||||
259
app/(application)/admin/donation/[id]/[status]/index.tsx
Normal file
@@ -0,0 +1,259 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
ButtonCustom,
|
||||
DrawerCustom,
|
||||
DummyLandscapeImage,
|
||||
MenuDrawerDynamicGrid,
|
||||
ProgressCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON, TEXT_SIZE_LARGE } from "@/constants/constans-value";
|
||||
import AdminDonation_BoxOfDonationStory from "@/screens/Admin/Donation/BoxOfDonationStory";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminDonationDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Penggalang Dana",
|
||||
value: `Bagas Banuna ${id}`,
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Donasi Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Durasi",
|
||||
value: "30 Hari",
|
||||
},
|
||||
{
|
||||
label: "Target Dana",
|
||||
value: "Rp 10.000.000",
|
||||
},
|
||||
{
|
||||
label: "Kategori",
|
||||
value: "Kategori Donasi",
|
||||
},
|
||||
// {
|
||||
// label: "Total Donatur",
|
||||
// value: "-",
|
||||
// },
|
||||
// {
|
||||
// label: "Progress",
|
||||
// value: "0 %",
|
||||
// },
|
||||
// {
|
||||
// label: "Dana Terkumpul",
|
||||
// value: "Rp 0",
|
||||
// },
|
||||
];
|
||||
|
||||
const listPencarianDana = [
|
||||
{
|
||||
label: "Total Dana Dicairkan",
|
||||
value: "Rp 0",
|
||||
},
|
||||
{
|
||||
label: "Sisa Dana",
|
||||
value: "Rp 0",
|
||||
},
|
||||
{
|
||||
label: "Akumulasi Pencairan",
|
||||
value: "0 kali",
|
||||
},
|
||||
{
|
||||
label: "Bank Tujuan",
|
||||
value: "BNI",
|
||||
},
|
||||
{
|
||||
label: "Nomor Rekening",
|
||||
value: "123456789",
|
||||
},
|
||||
];
|
||||
|
||||
const rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
onPress={() => {
|
||||
setOpenDrawer(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title={`Detail Data`}
|
||||
rightComponent={status === "publish" && rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{status === "publish" && (
|
||||
<View>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<TextCustom bold align="center" size={TEXT_SIZE_LARGE}>
|
||||
Pencarian Dana
|
||||
</TextCustom>
|
||||
|
||||
<StackCustom gap={5}>
|
||||
{listPencarianDana.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
<ButtonCustom
|
||||
iconLeft={
|
||||
<Ionicons name="cash-outline" size={ICON_SIZE_BUTTON} />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/${id}/disbursement-of-funds`);
|
||||
}}
|
||||
>
|
||||
Cairkan Dana
|
||||
</ButtonCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<ProgressCustom size="lg" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Jumlah Donatur</TextCustom>}
|
||||
value={<TextCustom>0 orang</TextCustom>}
|
||||
/>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Dana Terkumpul</TextCustom>}
|
||||
value={<TextCustom>Rp 0</TextCustom>}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<DummyLandscapeImage />
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{status === "review" && (
|
||||
<StackCustom>
|
||||
<AdminDonation_BoxOfDonationStory />
|
||||
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/donation/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
)}
|
||||
|
||||
{status === "reject" && (
|
||||
<StackCustom>
|
||||
<AdminDonation_BoxOfDonationStory />
|
||||
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/donation/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
</StackCustom>
|
||||
)}
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
label: "Daftar Donatur",
|
||||
icon: <IconList />,
|
||||
path: `/admin/donation/${id}/list-of-donatur`,
|
||||
},
|
||||
{
|
||||
label: "Daftar Pencarian Dana",
|
||||
icon: <IconList />,
|
||||
path: `/admin/donation/${id}/list-disbursement-of-funds`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
setOpenDrawer(false);
|
||||
router.push(item.path as any);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminDonasiTransactionDetail() {
|
||||
const { id } = useLocalSearchParams();
|
||||
|
||||
const buttonAction = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Terima</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Donatur",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Bank",
|
||||
value: "BCA",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Donasi",
|
||||
value: "Rp. 1.000.000",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Berhasil</BadgeCustom>,
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm:ss"),
|
||||
},
|
||||
{
|
||||
label: "Bukti Transfer",
|
||||
value: (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Detail Transaksi" />}
|
||||
footerComponent={buttonAction}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<GridDetail_4_8
|
||||
key={index}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import {
|
||||
BaseBox,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminDonationDetailDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const listData = [
|
||||
{
|
||||
label: "Nominal",
|
||||
value: "Rp 1.000.000",
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm"),
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Judul Pencairan Dana ${id}`,
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque velit eos facere a dicta nemo repellendus harum laboriosam quos, earum reprehenderit. Nisi sapiente, quo earum quis alias ullam temporibus quidem.`,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle title="Detail Pencairan Dana" />
|
||||
}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<GridDetail_4_8
|
||||
key={index}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
}
|
||||
>
|
||||
Cek Bukti Transaksi
|
||||
</ButtonCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
ButtonCenteredOnly,
|
||||
ButtonCustom,
|
||||
InformationBox,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextAreaCustom,
|
||||
TextCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminDonationDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const handleSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom
|
||||
onPress={() => {
|
||||
router.back();
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Pencairan Dana" />}
|
||||
footerComponent={handleSubmit}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom gap="md">
|
||||
<TextCustom align="center" bold size="large">
|
||||
Dana Tersisa
|
||||
</TextCustom>
|
||||
<TextCustom align="center" bold size="large">
|
||||
Rp 1.000.000
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<TextCustom bold size="large" align="center">
|
||||
Form Pencairan Dana
|
||||
</TextCustom>
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextInputCustom
|
||||
required
|
||||
keyboardType="numeric"
|
||||
label="Nominal"
|
||||
placeholder="0"
|
||||
iconLeft={"Rp"}
|
||||
/>
|
||||
|
||||
<TextInputCustom required label="Judul" placeholder="Masukan judul" />
|
||||
|
||||
<TextAreaCustom
|
||||
required
|
||||
label="Deskripsi"
|
||||
placeholder="Masukan deskripsi"
|
||||
showCount
|
||||
maxLength={500}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
<InformationBox text="Wajib menyertakan bukti transfer" />
|
||||
|
||||
<ButtonCenteredOnly
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(image)/take-picture/${id}`);
|
||||
}}
|
||||
icon="upload"
|
||||
>
|
||||
Upload
|
||||
</ButtonCenteredOnly>
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
CenterCustom,
|
||||
Divider,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminDonasiListOfDisbursementOfFunds() {
|
||||
const { id } = useLocalSearchParams();
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle title="Daftar Pencairan Dana" />
|
||||
}
|
||||
>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Tanggal
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Nominal
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${id}/detail-disbursement-of-funds`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
{dayjs()
|
||||
.add(index + 1, "day")
|
||||
.format("DD-MM-YYYY HH:mm")}
|
||||
</TextCustom>
|
||||
}
|
||||
component3={<TextCustom>Rp. 1.000.000</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
101
app/(application)/admin/donation/[id]/list-of-donatur.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BadgeCustom,
|
||||
CenterCustom,
|
||||
SelectCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminDonasiListOfDonatur() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const searchComponent = (
|
||||
<View style={{ flexDirection: "row", gap: 5 }}>
|
||||
<SelectCustom
|
||||
placeholder="Pilih status transaksi"
|
||||
data={dummyMasterStatusTransaction}
|
||||
onChange={(value) => console.log(value)}
|
||||
styleContainer={{ width: "100%", marginBottom: 0 }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle newComponent={searchComponent} />
|
||||
}
|
||||
>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Donatur
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/donation/${id}/berhasil/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
Bagas Banuna
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={MainColor.green}
|
||||
>
|
||||
Berhasil
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/donation/[id]/reject-input.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
TextAreaCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminDonationRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
title: "Reject",
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/donation/reject/status`);
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Donasi" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
maxLength={1000}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
70
app/(application)/admin/donation/[status]/status.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminDonationStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminComp_BoxTitle
|
||||
title={`Donasi ${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Donasi"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons name="eye" size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
27
app/(application)/admin/donation/category-create.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useRouter } from "expo-router";
|
||||
|
||||
export default function AdminDonationCategoryCreate() {
|
||||
const router = useRouter();
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Tambah Kategori" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom placeholder="Masukkan Kategori" />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
35
app/(application)/admin/donation/category-update.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminDonationCategoryUpdate() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id);
|
||||
|
||||
const router = useRouter();
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Ubah Kategori" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom
|
||||
placeholder="Masukkan Kategori"
|
||||
value={value as any}
|
||||
onChangeText={setValue}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
113
app/(application)/admin/donation/category.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
CenterCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconEdit } from "@/components/_Icon";
|
||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { GridView_3_3_6 } from "@/components/_ShareComponent/GridView_3_3_6";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { View } from "react-native";
|
||||
import { Divider, Switch } from "react-native-paper";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminDonationCategory() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Donasi" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title="Kategori"
|
||||
rightComponent={
|
||||
<AdminActionIconPlus
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/category-create`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<GridView_3_3_6
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={<TextCustom bold>Status</TextCustom>}
|
||||
component3={<TextCustom bold>Kategori</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<View key={index}>
|
||||
<GridView_3_3_6
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/donation/category-update?id=${index}`);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<Switch
|
||||
value={true}
|
||||
onValueChange={(item) => {
|
||||
console.log(item);
|
||||
}}
|
||||
color={MainColor.yellow}
|
||||
|
||||
/>
|
||||
}
|
||||
component3={<TextCustom bold>{item.label}</TextCustom>}
|
||||
/>
|
||||
<Spacing height={10} />
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Kegiatan Sosial",
|
||||
value: "kegiatan_sosial",
|
||||
},
|
||||
{
|
||||
label: "Pendidikan",
|
||||
value: "pendidikan",
|
||||
},
|
||||
{
|
||||
label: "Kesehatan",
|
||||
value: "kesehatan",
|
||||
},
|
||||
{
|
||||
label: "Kebudayaan",
|
||||
value: "kebudayaan",
|
||||
},
|
||||
{
|
||||
label: "Bencana Alami",
|
||||
value: "bencana_alami",
|
||||
},
|
||||
{
|
||||
label: "Lainnya",
|
||||
value: "lainnya",
|
||||
},
|
||||
];
|
||||
49
app/(application)/admin/donation/index.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import {
|
||||
IconList,
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminDonation() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Donasi" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 4,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 7,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 5,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
{
|
||||
label: "Kategori",
|
||||
value: 4,
|
||||
icon: <IconList size={25} color={MainColor.white_gray} />,
|
||||
},
|
||||
];
|
||||
217
app/(application)/admin/event/[id]/[status]/index.tsx
Normal file
@@ -0,0 +1,217 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React from "react";
|
||||
import QRCode from "react-native-qrcode-svg";
|
||||
|
||||
export default function AdminEventDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Pembuat Event",
|
||||
value: `Bagas Banuna ${id}`,
|
||||
},
|
||||
{
|
||||
label: "Judul Event",
|
||||
value: `Event 123`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Lokasi",
|
||||
value: "Lokasi Event",
|
||||
},
|
||||
{
|
||||
label: "Tipe Acara",
|
||||
value: "Tipe Acara",
|
||||
},
|
||||
{
|
||||
label: "Mulai Event",
|
||||
value: dayjs().format("DD/MM/YYYY HH:mm:ss"),
|
||||
},
|
||||
{
|
||||
label: "Event Berakhir",
|
||||
value: dayjs().add(3, "day").format("DD/MM/YYYY HH:mm:ss"),
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
// {
|
||||
// label: "Daftar Tipe Acara",
|
||||
// value: (
|
||||
// <>
|
||||
// <List.Item
|
||||
// title={<TextCustom>Pilihan 1</TextCustom>}
|
||||
// left={(props) => (
|
||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
// )}
|
||||
// />
|
||||
// <List.Item
|
||||
// title={<TextCustom>Pilihan 2</TextCustom>}
|
||||
// left={(props) => (
|
||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
// )}
|
||||
// />
|
||||
// <List.Item
|
||||
// title={<TextCustom>Pilihan 3</TextCustom>}
|
||||
// left={(props) => (
|
||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
// )}
|
||||
// />
|
||||
// <List.Item
|
||||
// title={<TextCustom>Pilihan 4</TextCustom>}
|
||||
// left={(props) => (
|
||||
// <List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
// )}
|
||||
// />
|
||||
// </>
|
||||
// ),
|
||||
// },
|
||||
];
|
||||
|
||||
const rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
onPress={() => {
|
||||
setOpenDrawer(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title={`Detail Data`}
|
||||
rightComponent={
|
||||
(status === "publish" || status === "riwayat") && rightComponent
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
|
||||
<Spacing />
|
||||
</BaseBox>
|
||||
{(status === "publish" || status === "riwayat") && (
|
||||
<BaseBox>
|
||||
<StackCustom style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>QR Code Event</TextCustom>
|
||||
<QRCode
|
||||
value="https://google.com"
|
||||
size={200}
|
||||
// logo={require("@/assets/images/logo-hipmi.png")}
|
||||
// logoSize={70}
|
||||
// logoBackgroundColor="transparent"
|
||||
// logoBorderRadius={50}
|
||||
// color="black"
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
)}
|
||||
|
||||
{status === "review" && (
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/event/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{status === "reject" && (
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/event/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
label: "Daftar Peserta",
|
||||
icon: <IconList />,
|
||||
path: `/admin/event/${id}/list-of-participants`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
setOpenDrawer(false);
|
||||
router.push(item.path as any);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
42
app/(application)/admin/event/[id]/list-of-participants.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { BadgeCustom, BaseBox, Grid, TextCustom, ViewWrapper } from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminEventListOfParticipants() {
|
||||
|
||||
const isPresent = ({id}: {id: number}) => {
|
||||
const check = id % 3 * 3;
|
||||
if (check === 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Daftar Peserta" />}
|
||||
>
|
||||
{Array.from({ length: 10 }).map((item, index) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold>Username {index + 1}</TextCustom>
|
||||
<TextCustom>+6282123456789</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ justifyContent: "center" }}>
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "flex-end" }}
|
||||
color={isPresent({id: index}) ? MainColor.green : MainColor.red}
|
||||
>
|
||||
{isPresent({id: index}) ? "Hadir" : "Tidak Hadir"}
|
||||
</BadgeCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
))}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/event/[id]/reject-input.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
TextAreaCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminEventRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
title: "Reject",
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/event/reject/status`);
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Event" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
maxLength={1000}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
76
app/(application)/admin/event/[status]/status.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminEventStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Event" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title={`${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Event"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/event/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/event/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import { IconArchive } from "@/components/_Icon";
|
||||
import {
|
||||
IconList,
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminVoting() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Event" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 3,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 8,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 4,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
{
|
||||
label: "Riwayat",
|
||||
value: 6,
|
||||
icon: <IconArchive size={25} color={MainColor.placeholder} />,
|
||||
},
|
||||
{
|
||||
label: "Tipe Acara",
|
||||
value: 7,
|
||||
icon: <IconList size={25} color={MainColor.placeholder} />,
|
||||
},
|
||||
];
|
||||
27
app/(application)/admin/event/type-create.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useRouter } from "expo-router";
|
||||
|
||||
export default function AdminEventTypeOfEventCreate() {
|
||||
const router = useRouter();
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Tambah Tipe Acara" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom placeholder="Masukkan Tipe Acara" />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
104
app/(application)/admin/event/type-of-event.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
CenterCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconEdit } from "@/components/_Icon";
|
||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminEventTypeOfEvent() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Event" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title="Tipe Acara"
|
||||
rightComponent={
|
||||
<AdminActionIconPlus
|
||||
onPress={() => {
|
||||
router.push(`/admin/event/type-create`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<GridDetail_4_8
|
||||
label={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
value={<TextCustom bold>Tipe Acara</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
<Spacing />
|
||||
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<View key={index}>
|
||||
<GridDetail_4_8
|
||||
label={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/event/type-update?id=${index}`);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
value={<TextCustom bold>{item.label}</TextCustom>}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Seminar",
|
||||
value: "seminar",
|
||||
},
|
||||
{
|
||||
label: "Workshop",
|
||||
value: "workshop",
|
||||
},
|
||||
{
|
||||
label: "Konferensi",
|
||||
value: "konferensi",
|
||||
},
|
||||
{
|
||||
label: "Lomba",
|
||||
value: "lomba",
|
||||
},
|
||||
{
|
||||
label: "Pameran",
|
||||
value: "pameran",
|
||||
},
|
||||
{
|
||||
label: "Pesta",
|
||||
value: "pesta",
|
||||
},
|
||||
{
|
||||
label: "Pertandingan",
|
||||
value: "pertandingan",
|
||||
},
|
||||
];
|
||||
30
app/(application)/admin/event/type-update.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||
|
||||
export default function AdminEventTypeOfEventUpdate() {
|
||||
const { id } = useLocalSearchParams();
|
||||
console.log("id >", id);
|
||||
|
||||
const router = useRouter();
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Ubah Tipe Acara" />}
|
||||
footerComponent={buttonSubmit}
|
||||
>
|
||||
<TextInputCustom placeholder="Masukkan Tipe Acara" value="" />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
203
app/(application)/admin/forum/[id]/index.tsx
Normal file
@@ -0,0 +1,203 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconView } from "@/components/_Icon/IconComponent";
|
||||
import { IconTrash } from "@/components/_Icon/IconTrash";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import {
|
||||
ICON_SIZE_BUTTON,
|
||||
ICON_SIZE_MEDIUM,
|
||||
ICON_SIZE_XLARGE,
|
||||
} from "@/constants/constans-value";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminForumDetailPosting() {
|
||||
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
||||
const [id, setId] = useState<any>();
|
||||
|
||||
const handlerAction = (item: { value: string; path: string }) => {
|
||||
if (item.value === "delete") {
|
||||
AlertDefaultSystem({
|
||||
title: "Hapus Posting",
|
||||
message: "Apakah Anda yakin ingin menghapus posting ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Hapus",
|
||||
onPressRight: () => {
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Posting berhasil dihapus",
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
router.navigate(item.path as any);
|
||||
}
|
||||
setOpenDrawerAction(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title="Detail Posting"
|
||||
rightComponent={
|
||||
<ActionIcon
|
||||
icon={<IconDot size={16} color={MainColor.darkblue} />}
|
||||
onPress={() => setOpenDrawerPage(true)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom gap={"sm"}>
|
||||
{listDataAction.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
<TextCustom bold>Posting</TextCustom>
|
||||
<TextCustom>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
||||
assumenda aut vero provident!
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{/* <AdminComp_BoxTitle title="Komentar" rightComponent={rightComponent} /> */}
|
||||
<BaseBox>
|
||||
<AdminTitleTable title1="Aksi" title2="Username" title3="Komentar" />
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Ionicons
|
||||
name="ellipsis-vertical-outline"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
setOpenDrawerAction(true);
|
||||
setId(index + 1);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerPage}
|
||||
closeDrawer={() => setOpenDrawerPage(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: (
|
||||
<Ionicons
|
||||
name="list"
|
||||
size={ICON_SIZE_XLARGE}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
),
|
||||
label: "Daftar Report Posting",
|
||||
value: "detail",
|
||||
path: `/admin/forum/${id}/list-report-posting`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
router.navigate(item.path as any);
|
||||
setOpenDrawerPage(false);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerAction}
|
||||
closeDrawer={() => setOpenDrawerAction(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: <IconView />,
|
||||
label: "Detail Komentar",
|
||||
value: "detail",
|
||||
path: `admin/forum/${id}/list-report-comment`,
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<IconTrash size={ICON_SIZE_MEDIUM} color={MainColor.white} />
|
||||
),
|
||||
label: "Hapus Komentar",
|
||||
value: "delete",
|
||||
path: "",
|
||||
color: MainColor.red,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
handlerAction(item as any);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listDataAction = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Username",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Open</BadgeCustom>,
|
||||
},
|
||||
{
|
||||
label: "Komentar",
|
||||
value: "10",
|
||||
},
|
||||
{
|
||||
label: "Total Report",
|
||||
value: "1",
|
||||
},
|
||||
];
|
||||
168
app/(application)/admin/forum/[id]/list-report-comment.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconView } from "@/components/_Icon/IconComponent";
|
||||
import { IconTrash } from "@/components/_Icon/IconTrash";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminForumReportComment() {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title="Report Komentar"
|
||||
rightComponent={
|
||||
<ActionIcon
|
||||
icon={<IconDot size={16} color={MainColor.darkblue} />}
|
||||
onPress={() => setOpenDrawer(true)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom gap={"sm"}>
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
<TextCustom bold>Posting</TextCustom>
|
||||
<TextCustom>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
||||
assumenda aut vero provident!
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<AdminComp_BoxTitle title="Daftar Report Komentar" />
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Kategori Report"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
setOpenDrawerAction(true);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2} align="center">
|
||||
SPAM
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: <IconTrash />,
|
||||
label: "Hapus Komentar",
|
||||
value: "delete",
|
||||
path: "",
|
||||
color: MainColor.red,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
AlertDefaultSystem({
|
||||
title: "Hapus Komentar",
|
||||
message: "Apakah Anda yakin ingin menghapus komentar ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Hapus",
|
||||
onPressRight: () => {
|
||||
setOpenDrawer(false);
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Komentar berhasil dihapus",
|
||||
});
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerAction}
|
||||
closeDrawer={() => setOpenDrawerAction(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
{listDataAction.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Username",
|
||||
},
|
||||
];
|
||||
|
||||
const listDataAction = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Riyusa",
|
||||
},
|
||||
{
|
||||
label: "Kategori Report",
|
||||
value: "SPAM",
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis asperiores quidem deleniti architecto eaque et nostrum, ad consequuntur eveniet quisquam quae voluptatum ducimus! Dolorem nobis modi officia debitis, beatae mollitia.",
|
||||
},
|
||||
];
|
||||
170
app/(application)/admin/forum/[id]/list-report-posting.tsx
Normal file
@@ -0,0 +1,170 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconDot, IconView } from "@/components/_Icon/IconComponent";
|
||||
import { IconTrash } from "@/components/_Icon/IconTrash";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function AdminForumReportPosting() {
|
||||
const [openDrawerPage, setOpenDrawerPage] = useState(false);
|
||||
const [openDrawerAction, setOpenDrawerAction] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title="Report Posting"
|
||||
rightComponent={
|
||||
<ActionIcon
|
||||
icon={<IconDot size={16} color={MainColor.darkblue} />}
|
||||
onPress={() => setOpenDrawerPage(true)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom gap={"sm"}>
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
<TextCustom bold>Posting</TextCustom>
|
||||
<TextCustom>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum
|
||||
numquam eos ab laborum fugiat illo nam velit quibusdam, maxime
|
||||
assumenda aut vero provident!
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<AdminComp_BoxTitle title="Daftar Report Posting" />
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Kategori Report"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 5 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => setOpenDrawerAction(true)}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2} align="center">
|
||||
SPAM
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerPage}
|
||||
closeDrawer={() => setOpenDrawerPage(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: <IconTrash />,
|
||||
label: "Hapus Posting",
|
||||
value: "delete",
|
||||
path: "",
|
||||
color: MainColor.red,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
AlertDefaultSystem({
|
||||
title: "Hapus Posting",
|
||||
message: "Apakah Anda yakin ingin menghapus posting ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Hapus",
|
||||
onPressRight: () => {
|
||||
setOpenDrawerPage(false);
|
||||
Toast.show({
|
||||
type: "success",
|
||||
text1: "Posting berhasil dihapus",
|
||||
});
|
||||
router.back()
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawerAction}
|
||||
closeDrawer={() => setOpenDrawerAction(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
{listDataAction.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Username",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Open</BadgeCustom>,
|
||||
},
|
||||
];
|
||||
|
||||
const listDataAction = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Firman Nusantara",
|
||||
},
|
||||
{
|
||||
label: "Kategori Report",
|
||||
value: "SPAM",
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value:
|
||||
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis asperiores quidem deleniti architecto eaque et nostrum, ad consequuntur eveniet quisquam quae voluptatum ducimus! Dolorem nobis modi officia debitis, beatae mollitia.",
|
||||
},
|
||||
];
|
||||
42
app/(application)/admin/forum/index.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import {
|
||||
IconPublish,
|
||||
IconReport,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminForum() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Forum" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Posting",
|
||||
value: 4,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Report Posting",
|
||||
value: 7,
|
||||
icon: <IconReport size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Report Comment",
|
||||
value: 5,
|
||||
icon: <IconReport size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
61
app/(application)/admin/forum/posting.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import React from "react";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminForumPosting() {
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
||||
<AdminComp_BoxTitle title={"Posting"} rightComponent={rightComponent} />
|
||||
<BaseBox>
|
||||
<AdminTitleTable title1="Aksi" title2="Username" title3="Postingan" />
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(`/admin/forum/${index + 1}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
65
app/(application)/admin/forum/report-comment.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Divider,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminForumReportComment() {
|
||||
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari Komentar"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title="Report Comment"
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Jenis Laporan" />
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconView size={ICON_SIZE_BUTTON} color={MainColor.black} />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/forum/${index + 1}/list-report-comment`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2} align="center">
|
||||
SPAM
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
73
app/(application)/admin/forum/report-posting.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Divider,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminForumReportPosting() {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [id, setId] = useState<any>();
|
||||
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Forum" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title="Report Posting"
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable title1="Aksi" title2="Pelapor" title3="Postingan" />
|
||||
<Spacing />
|
||||
<Divider />
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<IconView size={ICON_SIZE_BUTTON} color={MainColor.black} />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/forum/${id}/list-report-posting`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2} align="center">
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Omnis laborum doloremque eius velit voluptate corrupti vel,
|
||||
provident quaerat tempore animi sed accusamus amet.
|
||||
Temporibus, praesentium? Rem voluptatum nesciunt voluptas
|
||||
repellat.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
244
app/(application)/admin/investment/[id]/[status]/index.tsx
Normal file
@@ -0,0 +1,244 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
ButtonCustom,
|
||||
DrawerCustom,
|
||||
DummyLandscapeImage,
|
||||
MenuDrawerDynamicGrid,
|
||||
ProgressCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import { IconProspectus } from "@/components/_Icon";
|
||||
import { IconDot, IconList } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React from "react";
|
||||
|
||||
export default function AdminInvestmentDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
const [openDrawer, setOpenDrawer] = React.useState(false);
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: `Bagas Banuna ${id}`,
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Donasi Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Dana Dibutuhkan",
|
||||
value: "Rp 10.000.000",
|
||||
},
|
||||
{
|
||||
label: "Harga Perlembar",
|
||||
value: "Rp 2500",
|
||||
},
|
||||
{
|
||||
label: "Total Lembar",
|
||||
value: "2490 lembar",
|
||||
},
|
||||
{
|
||||
label: "ROI",
|
||||
value: "4 %",
|
||||
},
|
||||
{
|
||||
label: "Pembagian Deviden",
|
||||
value: "3 bulan",
|
||||
},
|
||||
{
|
||||
label: "Jadwal Pembagian",
|
||||
value: "Selamanya",
|
||||
},
|
||||
{
|
||||
label: "Pencarian Investor",
|
||||
value: "30 Hari",
|
||||
},
|
||||
];
|
||||
|
||||
const rightComponent = (
|
||||
<ActionIcon
|
||||
icon={<IconDot size={ICON_SIZE_BUTTON} />}
|
||||
onPress={() => {
|
||||
setOpenDrawer(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminBackButtonAntTitle
|
||||
title={`Detail Data`}
|
||||
rightComponent={status === "publish" && rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{status === "publish" && (
|
||||
<BaseBox>
|
||||
<ProgressCustom size="lg" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Sisa Saham</TextCustom>}
|
||||
value={<TextCustom>2490 lembar</TextCustom>}
|
||||
/>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>Validasi Transaksi</TextCustom>}
|
||||
value={<TextCustom>4 Transaksi</TextCustom>}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
)}
|
||||
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<DummyLandscapeImage />
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>File Prospektus</TextCustom>}
|
||||
value={
|
||||
<ButtonCustom
|
||||
iconLeft={
|
||||
<IconProspectus
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color={MainColor.darkblue}
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(file)/${id}`);
|
||||
}}
|
||||
>
|
||||
Preview
|
||||
</ButtonCustom>
|
||||
}
|
||||
/>
|
||||
<GridDetail_4_8
|
||||
label={<TextCustom bold>File Dokumen</TextCustom>}
|
||||
value={
|
||||
<StackCustom>
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<ButtonCustom
|
||||
key={i}
|
||||
iconLeft={
|
||||
<IconProspectus
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color={MainColor.darkblue}
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/(application)/(file)/${id}`);
|
||||
}}
|
||||
>
|
||||
Dokumen {i + 1}
|
||||
</ButtonCustom>
|
||||
))}
|
||||
</StackCustom>
|
||||
}
|
||||
/>
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{status === "review" && (
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/investment/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{status === "reject" && (
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/investment/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ViewWrapper>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
label: "Daftar Investor",
|
||||
icon: <IconList />,
|
||||
path: `/admin/investment/${id}/list-of-investor`,
|
||||
},
|
||||
// {
|
||||
// label: "Daftar Pencarian Dana",
|
||||
// icon: <IconList />,
|
||||
// path: `/admin/donation/${id}/list-disbursement-of-funds`,
|
||||
// },
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
setOpenDrawer(false);
|
||||
router.push(item.path as any);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
BoxButtonOnFooter,
|
||||
ButtonCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
|
||||
export default function AdminInvestmentTransactionDetail() {
|
||||
const { id } = useLocalSearchParams();
|
||||
|
||||
const buttonAction = (
|
||||
<BoxButtonOnFooter>
|
||||
<ButtonCustom onPress={() => router.back()}>Terima</ButtonCustom>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Investor",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Bank",
|
||||
value: "BCA",
|
||||
},
|
||||
{
|
||||
label: "Jumlah Investasi",
|
||||
value: "Rp. 1.000.000",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: <BadgeCustom color={MainColor.green}>Berhasil</BadgeCustom>,
|
||||
},
|
||||
{
|
||||
label: "Tanggal",
|
||||
value: dayjs().format("DD-MM-YYYY HH:mm:ss"),
|
||||
},
|
||||
{
|
||||
label: "Bukti Transfer",
|
||||
value: (
|
||||
<ButtonCustom
|
||||
onPress={() =>
|
||||
router.push(`/(application)/(image)/preview-image/${id}`)
|
||||
}
|
||||
>
|
||||
Cek
|
||||
</ButtonCustom>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title="Detail Transaksi Investor" />}
|
||||
footerComponent={buttonAction}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, index) => (
|
||||
<GridDetail_4_8
|
||||
key={index}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
107
app/(application)/admin/investment/[id]/list-of-investor.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BadgeCustom,
|
||||
CenterCustom,
|
||||
SelectCustom,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import { IconView } from "@/components/_Icon/IconComponent";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminInvestmentListOfInvestor() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const searchComponent = (
|
||||
<View style={{ flexDirection: "row", gap: 5 }}>
|
||||
<SelectCustom
|
||||
placeholder="Pilih status transaksi"
|
||||
data={dummyMasterStatusTransaction}
|
||||
onChange={(value) => console.log(value)}
|
||||
styleContainer={{ width: "100%", marginBottom: 0 }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
const headerComponent = (
|
||||
<StackCustom gap={"xs"}>
|
||||
<AdminBackButtonAntTitle title="Daftar Investor" />
|
||||
{searchComponent}
|
||||
</StackCustom>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={headerComponent}
|
||||
>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<TextCustom bold align="center">
|
||||
Aksi
|
||||
</TextCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center">
|
||||
Investor
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<TextCustom bold align="center">
|
||||
Status
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<View key={index}>
|
||||
<GridViewCustomSpan
|
||||
span1={3}
|
||||
span2={5}
|
||||
span3={4}
|
||||
component1={
|
||||
<CenterCustom>
|
||||
<ActionIcon
|
||||
icon={<IconView size={ICON_SIZE_BUTTON} color="black" />}
|
||||
onPress={() => {
|
||||
router.push(
|
||||
`/admin/investment/${id}/berhasil/transaction-detail`
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</CenterCustom>
|
||||
}
|
||||
component2={
|
||||
<TextCustom bold align="center" truncate>
|
||||
Bagas Banuna
|
||||
</TextCustom>
|
||||
}
|
||||
component3={
|
||||
<BadgeCustom
|
||||
style={{ alignSelf: "center" }}
|
||||
color={MainColor.green}
|
||||
>
|
||||
Berhasil
|
||||
</BadgeCustom>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</View>
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/investment/[id]/reject-input.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
TextAreaCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminInvestmentRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
title: "Reject",
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/investment/reject/status`);
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Investasi" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
maxLength={1000}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
70
app/(application)/admin/investment/[status]/status.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminInvestmentStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminComp_BoxTitle
|
||||
title={`Investasi ${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Investasi"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons name="eye" size={ICON_SIZE_BUTTON} color="black" />
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/investment/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
43
app/(application)/admin/investment/index.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import {
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminInvestment() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Investasi" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 3,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 5,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 8,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
129
app/(application)/admin/job/[id]/[status]/index.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DummyLandscapeImage,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
|
||||
export default function AdminJobDetailStatus() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Judul Proyek: ${id}Lorem ipsum dolor sit amet consectetur adipisicing elit.`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Konten",
|
||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
// {
|
||||
// label: "Poster",
|
||||
// value: (
|
||||
// <ButtonCustom
|
||||
// href={`/(application)/()/${id}`}
|
||||
// >
|
||||
// Lihat Poster
|
||||
// </ButtonCustom>
|
||||
// ),
|
||||
// },
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title={`Detail Data`} />}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<Grid key={i}>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{ justifyContent: "center", paddingRight: 10 }}
|
||||
>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={8} style={{ justifyContent: "center" }}>
|
||||
<TextCustom>{item.value}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
|
||||
<TextCustom bold>Poster</TextCustom>
|
||||
|
||||
<DummyLandscapeImage />
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{status === "review" && (
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/job/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{status === "reject" && (
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/job/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/job/[id]/reject-input.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
TextAreaCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminJobRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
title: "Reject",
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/job/reject/status`);
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Job" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
maxLength={1000}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
76
app/(application)/admin/job/[status]/status.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminJobStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Job Vacancy" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title={`${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Pekerjaan"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/job/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
43
app/(application)/admin/job/index.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import {
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminJob() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Job Vacancy" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 4,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 7,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 5,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
];
|
||||
11
app/(application)/admin/maps.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { MapCustom, ViewWrapper } from "@/components";
|
||||
|
||||
export default function AdminMaps() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<MapCustom height={"100%"} />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
20
app/(application)/admin/notification/index.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { BackButton, TextCustom, ViewWrapper } from "@/components";
|
||||
import { Stack } from "expo-router";
|
||||
|
||||
export default function AdminNotification() {
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Admin Notifikasi",
|
||||
headerLeft: () => <BackButton />,
|
||||
headerRight: () => <></>,
|
||||
}}
|
||||
/>
|
||||
|
||||
<ViewWrapper>
|
||||
<TextCustom>Notification</TextCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
117
app/(application)/admin/user-access.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import {
|
||||
ButtonCustom,
|
||||
Divider,
|
||||
Grid,
|
||||
SearchInput,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_MEDIUM } from "@/constants/constans-value";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
export default function AdminUserAccess() {
|
||||
const rightComponent = () => {
|
||||
return (
|
||||
<>
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari User"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={
|
||||
<AdminComp_BoxTitle
|
||||
title="User Access"
|
||||
rightComponent={rightComponent()}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>Aksi</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>Username</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "center" }}>
|
||||
<TextCustom bold>Nomor</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<Divider />
|
||||
|
||||
<StackCustom>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<Grid key={index}>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{
|
||||
alignItems: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
<TextCustom bold>
|
||||
<ButtonCustom
|
||||
iconLeft={
|
||||
<Ionicons
|
||||
name={
|
||||
index % 2 === 0
|
||||
? "checkmark-outline"
|
||||
: "close-circle-outline"
|
||||
}
|
||||
size={ICON_SIZE_MEDIUM}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {}}
|
||||
backgroundColor={
|
||||
index % 2 === 0 ? MainColor.green : MainColor.red
|
||||
}
|
||||
>
|
||||
<TextCustom size={"small"} color={"black"}>
|
||||
{index % 2 === 0 ? "Berikan Akses" : "Hapus Akses"}
|
||||
</TextCustom>
|
||||
</ButtonCustom>
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
<TextCustom bold truncate>
|
||||
Useraname
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={4}
|
||||
style={{
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
<TextCustom bold truncate>
|
||||
08123456789
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
173
app/(application)/admin/voting/[id]/[status]/index.tsx
Normal file
@@ -0,0 +1,173 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
CircleContainer,
|
||||
Grid,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview";
|
||||
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { List } from "react-native-paper";
|
||||
|
||||
export default function AdminVotingDetail() {
|
||||
const { id, status } = useLocalSearchParams();
|
||||
|
||||
const colorBadge = () => {
|
||||
if (status === "publish") {
|
||||
return MainColor.green;
|
||||
} else if (status === "review") {
|
||||
return MainColor.orange;
|
||||
} else if (status === "reject") {
|
||||
return MainColor.red;
|
||||
} else {
|
||||
return MainColor.placeholder;
|
||||
}
|
||||
};
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Username",
|
||||
value: "Bagas Banuna",
|
||||
},
|
||||
{
|
||||
label: "Judul",
|
||||
value: `Judul Proyek: ${id}Lorem ipsum dolor sit amet consectetur adipisicing elit.`,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<BadgeCustom color={colorBadge()}>
|
||||
{_.startCase(status as string)}
|
||||
</BadgeCustom>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Mulai Voting",
|
||||
value: dayjs().format("DD/MM/YYYY"),
|
||||
},
|
||||
{
|
||||
label: "Voting Berakhir",
|
||||
value: dayjs().format("DD/MM/YYYY"),
|
||||
},
|
||||
|
||||
{
|
||||
label: "Deskripsi",
|
||||
value: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
|
||||
},
|
||||
{
|
||||
label: "Daftar Pilhan",
|
||||
value: (
|
||||
<>
|
||||
<List.Item
|
||||
title={<TextCustom>Pilihan 1</TextCustom>}
|
||||
left={(props) => (
|
||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
)}
|
||||
/>
|
||||
<List.Item
|
||||
title={<TextCustom>Pilihan 2</TextCustom>}
|
||||
left={(props) => (
|
||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
)}
|
||||
/>
|
||||
<List.Item
|
||||
title={<TextCustom>Pilihan 3</TextCustom>}
|
||||
left={(props) => (
|
||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
)}
|
||||
/>
|
||||
<List.Item
|
||||
title={<TextCustom>Pilihan 4</TextCustom>}
|
||||
left={(props) => (
|
||||
<List.Icon {...props} icon="circle" color={MainColor.yellow} />
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
headerComponent={<AdminBackButtonAntTitle title={`Detail Data`} />}
|
||||
>
|
||||
<BaseBox>
|
||||
<StackCustom>
|
||||
{listData.map((item, i) => (
|
||||
<GridDetail_4_8
|
||||
key={i}
|
||||
label={<TextCustom bold>{item.label}</TextCustom>}
|
||||
value={<TextCustom>{item.value}</TextCustom>}
|
||||
/>
|
||||
))}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
|
||||
{status === "publish" && (
|
||||
<BaseBox>
|
||||
<TextCustom bold align="center">
|
||||
Hasil Voting
|
||||
</TextCustom>
|
||||
<Spacing />
|
||||
<Grid>
|
||||
|
||||
{Array.from({length: 4}).map((_, index) => (
|
||||
<Grid.Col key={index} span={3} style={{ paddingRight: 3, paddingLeft: 3 }}>
|
||||
<StackCustom gap={"sm"}>
|
||||
<CircleContainer value={index % 3 * 3} style={{ alignSelf: "center" }} />
|
||||
<TextCustom size="small" align="center">
|
||||
Pilihan {index + 1}
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
)}
|
||||
|
||||
{status === "review" && (
|
||||
<AdminButtonReview
|
||||
onPublish={() => {
|
||||
AlertDefaultSystem({
|
||||
title: "Publish",
|
||||
message: "Apakah anda yakin ingin mempublikasikan data ini?",
|
||||
textLeft: "Cancel",
|
||||
textRight: "Publish",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
router.back();
|
||||
},
|
||||
});
|
||||
}}
|
||||
onReject={() => {
|
||||
router.push(`/admin/voting/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{status === "reject" && (
|
||||
<AdminButtonReject
|
||||
title="Tambah Catatan"
|
||||
onReject={() => {
|
||||
router.push(`/admin/voting/${id}/reject-input`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Spacing />
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
55
app/(application)/admin/voting/[id]/reject-input.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
AlertDefaultSystem,
|
||||
BoxButtonOnFooter,
|
||||
TextAreaCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||
import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminVotingRejectInput() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [value, setValue] = useState(id as string);
|
||||
const buttonSubmit = (
|
||||
<BoxButtonOnFooter>
|
||||
<AdminButtonReject
|
||||
title="Reject"
|
||||
onReject={() =>
|
||||
AlertDefaultSystem({
|
||||
title: "Reject",
|
||||
message: "Apakah anda yakin ingin menolak data ini?",
|
||||
textLeft: "Batal",
|
||||
textRight: "Ya",
|
||||
onPressLeft: () => {
|
||||
router.back();
|
||||
},
|
||||
onPressRight: () => {
|
||||
console.log("value:", value);
|
||||
router.replace(`/admin/voting/reject/status`);
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper
|
||||
footerComponent={buttonSubmit}
|
||||
headerComponent={<AdminBackButtonAntTitle title="Penolakan Voting" />}
|
||||
>
|
||||
<TextAreaCustom
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
placeholder="Masukan alasan"
|
||||
required
|
||||
showCount
|
||||
maxLength={1000}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
76
app/(application)/admin/voting/[status]/status.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
SearchInput,
|
||||
Spacing,
|
||||
TextCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage";
|
||||
import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle";
|
||||
import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||
import { Octicons } from "@expo/vector-icons";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminVotingStatus() {
|
||||
const { status } = useLocalSearchParams();
|
||||
const rightComponent = (
|
||||
<SearchInput
|
||||
containerStyle={{ width: "100%", marginBottom: 0 }}
|
||||
placeholder="Cari"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper headerComponent={<AdminTitlePage title="Voting" />}>
|
||||
<AdminComp_BoxTitle
|
||||
title={`${_.startCase(status as string)}`}
|
||||
rightComponent={rightComponent}
|
||||
/>
|
||||
|
||||
<BaseBox>
|
||||
<AdminTitleTable
|
||||
title1="Aksi"
|
||||
title2="Username"
|
||||
title3="Judul Voting"
|
||||
/>
|
||||
<Spacing />
|
||||
<Divider />
|
||||
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<AdminTableValue
|
||||
key={index}
|
||||
value1={
|
||||
<ActionIcon
|
||||
icon={
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={ICON_SIZE_BUTTON}
|
||||
color="black"
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
router.push(`/admin/voting/${index}/${status}`);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
value2={<TextCustom truncate={1}>Username username</TextCustom>}
|
||||
value3={
|
||||
<TextCustom truncate={2}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||
Blanditiis asperiores quidem deleniti architecto eaque et
|
||||
nostrum, ad consequuntur eveniet quisquam quae voluptatum
|
||||
ducimus! Dolorem nobis modi officia debitis, beatae mollitia.
|
||||
</TextCustom>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</BaseBox>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
49
app/(application)/admin/voting/index.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Spacing, StackCustom, ViewWrapper } from "@/components";
|
||||
import { IconArchive } from "@/components/_Icon";
|
||||
import {
|
||||
IconPublish,
|
||||
IconReject,
|
||||
IconReview,
|
||||
} from "@/components/_Icon/IconComponent";
|
||||
import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard";
|
||||
import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminVoting() {
|
||||
return (
|
||||
<>
|
||||
<ViewWrapper>
|
||||
<AdminTitlePage title="Voting" />
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
{listData.map((item, i) => (
|
||||
<AdminComp_BoxDashboard key={i} item={item} />
|
||||
))}
|
||||
</StackCustom>
|
||||
</ViewWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const listData = [
|
||||
{
|
||||
label: "Publish",
|
||||
value: 4,
|
||||
icon: <IconPublish size={25} color={MainColor.green} />,
|
||||
},
|
||||
{
|
||||
label: "Review",
|
||||
value: 7,
|
||||
icon: <IconReview size={25} color={MainColor.orange} />,
|
||||
},
|
||||
{
|
||||
label: "Reject",
|
||||
value: 5,
|
||||
icon: <IconReject size={25} color={MainColor.red} />,
|
||||
},
|
||||
{
|
||||
label: "Riwayat",
|
||||
value: 5,
|
||||
icon: <IconArchive size={25} color={MainColor.white_gray} />,
|
||||
},
|
||||
];
|
||||
@@ -1,32 +1,15 @@
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { Stack } from "expo-router";
|
||||
import AppRoot from "@/screens/RootLayout/AppRoot";
|
||||
import "react-native-gesture-handler";
|
||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
export default function RootLayout() {
|
||||
return (
|
||||
<>
|
||||
<SafeAreaProvider>
|
||||
<Stack
|
||||
screenOptions={{
|
||||
headerStyle: { backgroundColor: MainColor.darkblue },
|
||||
headerTitleStyle: { color: MainColor.yellow, fontWeight: "bold" },
|
||||
headerTitleAlign: "center",
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="index" options={{ title: "" }} />
|
||||
<Stack.Screen name="+not-found" options={{ title: "" }} />
|
||||
<Stack.Screen
|
||||
name="verification"
|
||||
options={{ title: "", headerBackVisible: false }}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="register"
|
||||
options={{ title: "", headerBackVisible: false }}
|
||||
/>
|
||||
<Stack.Screen name="(application)" options={{ headerShown: false }} />
|
||||
</Stack>
|
||||
<AppRoot />
|
||||
</SafeAreaProvider>
|
||||
<Toast />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
BIN
assets/images/constants/logo-hipmi.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 51 KiB |
BIN
assets/images/old-icon.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/images/splash-icon-back.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 51 KiB |
107
bun.lock
@@ -13,12 +13,14 @@
|
||||
"@react-navigation/native-stack": "^7.3.21",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/react-native-vector-icons": "^6.4.18",
|
||||
"axios": "^1.11.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"expo": "53.0.17",
|
||||
"expo-blur": "~14.1.5",
|
||||
"expo-camera": "~16.1.10",
|
||||
"expo-clipboard": "~7.1.5",
|
||||
"expo-constants": "~17.1.7",
|
||||
"expo-dev-client": "~5.2.4",
|
||||
"expo-document-picker": "~13.1.6",
|
||||
"expo-file-system": "~18.1.11",
|
||||
"expo-font": "~13.3.2",
|
||||
@@ -42,9 +44,12 @@
|
||||
"react-native-otp-entry": "^1.8.5",
|
||||
"react-native-pager-view": "6.7.1",
|
||||
"react-native-paper": "^5.14.5",
|
||||
"react-native-qrcode-svg": "^6.3.15",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.11.1",
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-toast-message": "^2.3.3",
|
||||
"react-native-vector-icons": "^10.2.0",
|
||||
"react-native-web": "~0.20.0",
|
||||
"react-native-webview": "13.13.5",
|
||||
@@ -587,8 +592,12 @@
|
||||
|
||||
"async-limiter": ["async-limiter@1.0.1", "", {}, "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="],
|
||||
|
||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||
|
||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||
|
||||
"axios": ["axios@1.11.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA=="],
|
||||
|
||||
"babel-jest": ["babel-jest@29.7.0", "", { "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg=="],
|
||||
|
||||
"babel-plugin-istanbul": ["babel-plugin-istanbul@6.1.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" } }, "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA=="],
|
||||
@@ -621,6 +630,8 @@
|
||||
|
||||
"big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
|
||||
|
||||
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
|
||||
|
||||
"bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.x" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="],
|
||||
|
||||
"bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="],
|
||||
@@ -683,6 +694,8 @@
|
||||
|
||||
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
|
||||
|
||||
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
||||
|
||||
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
||||
|
||||
"compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="],
|
||||
@@ -707,6 +720,12 @@
|
||||
|
||||
"css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="],
|
||||
|
||||
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
|
||||
|
||||
"css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="],
|
||||
|
||||
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],
|
||||
@@ -719,6 +738,8 @@
|
||||
|
||||
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||
|
||||
"decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="],
|
||||
|
||||
"decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="],
|
||||
|
||||
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
|
||||
@@ -735,14 +756,26 @@
|
||||
|
||||
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
||||
|
||||
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||
|
||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||
|
||||
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||
|
||||
"detect-libc": ["detect-libc@1.0.3", "", { "bin": "bin/detect-libc.js" }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||
|
||||
"dijkstrajs": ["dijkstrajs@1.0.3", "", {}, "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="],
|
||||
|
||||
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
|
||||
|
||||
"dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
|
||||
@@ -759,6 +792,8 @@
|
||||
|
||||
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"env-editor": ["env-editor@0.4.2", "", {}, "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA=="],
|
||||
|
||||
"error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="],
|
||||
@@ -839,6 +874,14 @@
|
||||
|
||||
"expo-constants": ["expo-constants@17.1.7", "", { "dependencies": { "@expo/config": "~11.0.12", "@expo/env": "~1.0.7" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-byBjGsJ6T6FrLlhOBxw4EaiMXrZEn/MlUYIj/JAd+FS7ll5X/S4qVRbIimSJtdW47hXMq0zxPfJX6njtA56hHA=="],
|
||||
|
||||
"expo-dev-client": ["expo-dev-client@5.2.4", "", { "dependencies": { "expo-dev-launcher": "5.1.16", "expo-dev-menu": "6.1.14", "expo-dev-menu-interface": "1.10.0", "expo-manifests": "~0.16.6", "expo-updates-interface": "~1.1.0" }, "peerDependencies": { "expo": "*" } }, "sha512-s/N/nK5LPo0QZJpV4aPijxyrzV4O49S3dN8D2fljqrX2WwFZzWwFO6dX1elPbTmddxumdcpczsdUPY+Ms8g43g=="],
|
||||
|
||||
"expo-dev-launcher": ["expo-dev-launcher@5.1.16", "", { "dependencies": { "ajv": "8.11.0", "expo-dev-menu": "6.1.14", "expo-manifests": "~0.16.6", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-tbCske9pvbozaEblyxoyo/97D6od9Ma4yAuyUnXtRET1CKAPKYS+c4fiZ+I3B4qtpZwN3JNFUjG3oateN0y6Hg=="],
|
||||
|
||||
"expo-dev-menu": ["expo-dev-menu@6.1.14", "", { "dependencies": { "expo-dev-menu-interface": "1.10.0" }, "peerDependencies": { "expo": "*" } }, "sha512-yonNMg2GHJZtuisVowdl1iQjZfYP85r1D1IO+ar9D9zlrBPBJhq2XEju52jd1rDmDkmDuEhBSbPNhzIcsBNiPg=="],
|
||||
|
||||
"expo-dev-menu-interface": ["expo-dev-menu-interface@1.10.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-NxtM/qot5Rh2cY333iOE87dDg1S8CibW+Wu4WdLua3UMjy81pXYzAGCZGNOeY7k9GpNFqDPNDXWyBSlk9r2pBg=="],
|
||||
|
||||
"expo-document-picker": ["expo-document-picker@13.1.6", "", { "peerDependencies": { "expo": "*" } }, "sha512-8FTQPDOkyCvFN/i4xyqzH7ELW4AsB6B3XBZQjn1FEdqpozo6rpNJRr7sWFU/93WrLgA9FJEKpKbyr6XxczK6BA=="],
|
||||
|
||||
"expo-file-system": ["expo-file-system@18.1.11", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-HJw/m0nVOKeqeRjPjGdvm+zBi5/NxcdPf8M8P3G2JFvH5Z8vBWqVDic2O58jnT1OFEy0XXzoH9UqFu7cHg9DTQ=="],
|
||||
@@ -853,10 +896,14 @@
|
||||
|
||||
"expo-image-picker": ["expo-image-picker@16.1.4", "", { "dependencies": { "expo-image-loader": "~5.1.0" }, "peerDependencies": { "expo": "*" } }, "sha512-bTmmxtw1AohUT+HxEBn2vYwdeOrj1CLpMXKjvi9FKSoSbpcarT4xxI0z7YyGwDGHbrJqyyic3I9TTdP2J2b4YA=="],
|
||||
|
||||
"expo-json-utils": ["expo-json-utils@0.15.0", "", {}, "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ=="],
|
||||
|
||||
"expo-keep-awake": ["expo-keep-awake@14.1.4", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-wU9qOnosy4+U4z/o4h8W9PjPvcFMfZXrlUoKTMBW7F4pLqhkkP/5G4EviPZixv4XWFMjn1ExQ5rV6BX8GwJsWA=="],
|
||||
|
||||
"expo-linking": ["expo-linking@7.1.7", "", { "dependencies": { "expo-constants": "~17.1.7", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-ZJaH1RIch2G/M3hx2QJdlrKbYFUTOjVVW4g39hfxrE5bPX9xhZUYXqxqQtzMNl1ylAevw9JkgEfWbBWddbZ3UA=="],
|
||||
|
||||
"expo-manifests": ["expo-manifests@0.16.6", "", { "dependencies": { "@expo/config": "~11.0.12", "expo-json-utils": "~0.15.0" }, "peerDependencies": { "expo": "*" } }, "sha512-1A+do6/mLUWF9xd3uCrlXr9QFDbjbfqAYmUy8UDLOjof1lMrOhyeC4Yi6WexA/A8dhZEpIxSMCKfn7G4aHAh4w=="],
|
||||
|
||||
"expo-modules-autolinking": ["expo-modules-autolinking@2.1.13", "", { "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.1.0", "commander": "^7.2.0", "find-up": "^5.0.0", "glob": "^10.4.2", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-+SaiYkdP3LXOFm/26CHMHBof9Xq/0MHNDzL/K0OwPgHLhZ6wpDWIDYWRHNueWYtGpAeLw2XAhR0HX4FNtU09qw=="],
|
||||
|
||||
"expo-modules-core": ["expo-modules-core@2.4.2", "", { "dependencies": { "invariant": "^2.2.4" } }, "sha512-RCb0wniYCJkxwpXrkiBA/WiNGxzYsEpL0sB50gTnS/zEfX3DImS2npc4lfZ3hPZo1UF9YC6OSI9Do+iacV0NUg=="],
|
||||
@@ -871,6 +918,8 @@
|
||||
|
||||
"expo-system-ui": ["expo-system-ui@5.0.10", "", { "dependencies": { "@react-native/normalize-colors": "0.79.5", "debug": "^4.3.2" }, "peerDependencies": { "expo": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-BTXbSyJr80yuN6VO4XQKZj7BjesZQLHgOYZ0bWyf4VB19GFZq7ZnZOEc/eoKk1B3eIocOMKUfNCrg/Wn8Kfcuw=="],
|
||||
|
||||
"expo-updates-interface": ["expo-updates-interface@1.1.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-DeB+fRe0hUDPZhpJ4X4bFMAItatFBUPjw/TVSbJsaf3Exeami+2qbbJhWkcTMoYHOB73nOIcaYcWXYJnCJXO0w=="],
|
||||
|
||||
"expo-web-browser": ["expo-web-browser@14.2.0", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-6S51d8pVlDRDsgGAp8BPpwnxtyKiMWEFdezNz+5jVIyT+ctReW42uxnjRgtsdn5sXaqzhaX+Tzk/CWaKCyC0hw=="],
|
||||
|
||||
"exponential-backoff": ["exponential-backoff@3.1.2", "", {}, "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA=="],
|
||||
@@ -911,12 +960,16 @@
|
||||
|
||||
"flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="],
|
||||
|
||||
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
|
||||
|
||||
"fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="],
|
||||
|
||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||
|
||||
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
||||
|
||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
||||
|
||||
"freeport-async": ["freeport-async@2.0.0", "", {}, "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ=="],
|
||||
|
||||
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||
@@ -1183,6 +1236,8 @@
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="],
|
||||
|
||||
"memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="],
|
||||
|
||||
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
|
||||
@@ -1263,6 +1318,8 @@
|
||||
|
||||
"npm-package-arg": ["npm-package-arg@11.0.3", "", { "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } }, "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw=="],
|
||||
|
||||
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
||||
|
||||
"nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="],
|
||||
|
||||
"ob1": ["ob1@0.82.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-n9S8e4l5TvkrequEAMDidl4yXesruWTNTzVkeaHSGywoTOIwTzZzKw7Z670H3eaXDZui5MJXjWGNzYowVZIxCA=="],
|
||||
@@ -1335,7 +1392,7 @@
|
||||
|
||||
"plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="],
|
||||
|
||||
"pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
|
||||
"pngjs": ["pngjs@5.0.0", "", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="],
|
||||
|
||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||
|
||||
@@ -1359,8 +1416,12 @@
|
||||
|
||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||
|
||||
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"qrcode": ["qrcode@1.5.4", "", { "dependencies": { "dijkstrajs": "^1.0.1", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, "bin": { "qrcode": "bin/qrcode" } }, "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg=="],
|
||||
|
||||
"qrcode-terminal": ["qrcode-terminal@0.11.0", "", { "bin": "bin/qrcode-terminal.js" }, "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ=="],
|
||||
|
||||
"query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="],
|
||||
@@ -1407,12 +1468,18 @@
|
||||
|
||||
"react-native-paper": ["react-native-paper@5.14.5", "", { "dependencies": { "@callstack/react-theme-provider": "^3.0.9", "color": "^3.1.2", "use-latest-callback": "^0.2.3" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-safe-area-context": "*" } }, "sha512-eaIH5bUQjJ/mYm4AkI6caaiyc7BcHDwX6CqNDi6RIxfxfWxROsHpll1oBuwn/cFvknvA8uEAkqLk/vzVihI3AQ=="],
|
||||
|
||||
"react-native-qrcode-svg": ["react-native-qrcode-svg@6.3.15", "", { "dependencies": { "prop-types": "^15.8.0", "qrcode": "^1.5.4", "text-encoding": "^0.7.0" }, "peerDependencies": { "react": "*", "react-native": ">=0.63.4", "react-native-svg": ">=14.0.0" } }, "sha512-vLuNImGfstE8u+rlF4JfFpq65nPhmByuDG6XUPWh8yp8MgLQX11rN5eQ8nb/bf4OB+V8XoLTJB/AZF2g7jQSSQ=="],
|
||||
|
||||
"react-native-reanimated": ["react-native-reanimated@3.17.5", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "invariant": "^2.2.4", "react-native-is-edge-to-edge": "1.1.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-SxBK7wQfJ4UoWoJqQnmIC7ZjuNgVb9rcY5Xc67upXAFKftWg0rnkknTw6vgwnjRcvYThrjzUVti66XoZdDJGtw=="],
|
||||
|
||||
"react-native-safe-area-context": ["react-native-safe-area-context@5.4.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-JaEThVyJcLhA+vU0NU8bZ0a1ih6GiF4faZ+ArZLqpYbL6j7R3caRqj+mE3lEtKCuHgwjLg3bCxLL1GPUJZVqUA=="],
|
||||
|
||||
"react-native-screens": ["react-native-screens@4.11.1", "", { "dependencies": { "react-freeze": "^1.0.0", "react-native-is-edge-to-edge": "^1.1.7", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-F0zOzRVa3ptZfLpD0J8ROdo+y1fEPw+VBFq1MTY/iyDu08al7qFUO5hLMd+EYMda5VXGaTFCa8q7bOppUszhJw=="],
|
||||
|
||||
"react-native-svg": ["react-native-svg@15.11.2", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-+YfF72IbWQUKzCIydlijV1fLuBsQNGMT6Da2kFlo1sh+LE3BIm/2Q7AR1zAAR6L0BFLi1WaQPLfFUC9bNZpOmw=="],
|
||||
|
||||
"react-native-toast-message": ["react-native-toast-message@2.3.3", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-4IIUHwUPvKHu4gjD0Vj2aGQzqPATiblL1ey8tOqsxOWRPGGu52iIbL8M/mCz4uyqecvPdIcMY38AfwRuUADfQQ=="],
|
||||
|
||||
"react-native-vector-icons": ["react-native-vector-icons@10.2.0", "", { "dependencies": { "prop-types": "^15.7.2", "yargs": "^16.1.1" }, "bin": { "fa-upgrade.sh": "bin/fa-upgrade.sh", "fa5-upgrade": "bin/fa5-upgrade.sh", "fa6-upgrade": "bin/fa6-upgrade.sh", "generate-icon": "bin/generate-icon.js" } }, "sha512-n5HGcxUuVaTf9QJPs/W22xQpC2Z9u0nb0KgLPnVltP8vdUvOp6+R26gF55kilP/fV4eL4vsAHUqUjewppJMBOQ=="],
|
||||
|
||||
"react-native-web": ["react-native-web@0.20.0", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-OOSgrw+aON6R3hRosCau/xVxdLzbjEcsLysYedka0ZON4ZZe6n9xgeN9ZkoejhARM36oTlUgHIQqxGutEJ9Wxg=="],
|
||||
@@ -1441,6 +1508,8 @@
|
||||
|
||||
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
||||
|
||||
"require-main-filename": ["require-main-filename@2.0.0", "", {}, "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="],
|
||||
|
||||
"requireg": ["requireg@0.2.2", "", { "dependencies": { "nested-error-stacks": "~2.0.1", "rc": "~1.2.7", "resolve": "~1.7.1" } }, "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg=="],
|
||||
|
||||
"resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
|
||||
@@ -1485,6 +1554,8 @@
|
||||
|
||||
"server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="],
|
||||
|
||||
"set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="],
|
||||
|
||||
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
|
||||
|
||||
"set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="],
|
||||
@@ -1595,6 +1666,8 @@
|
||||
|
||||
"test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
|
||||
|
||||
"text-encoding": ["text-encoding@0.7.0", "", {}, "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA=="],
|
||||
|
||||
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
|
||||
|
||||
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
|
||||
@@ -1697,6 +1770,8 @@
|
||||
|
||||
"which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
|
||||
|
||||
"which-module": ["which-module@2.0.1", "", {}, "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="],
|
||||
|
||||
"which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
|
||||
|
||||
"wonka": ["wonka@6.3.5", "", {}, "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw=="],
|
||||
@@ -1849,6 +1924,8 @@
|
||||
|
||||
"cosmiconfig/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": "bin/js-yaml.js" }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
||||
|
||||
"css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
|
||||
|
||||
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||
@@ -1859,6 +1936,8 @@
|
||||
|
||||
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||
|
||||
"expo-dev-launcher/ajv": ["ajv@8.11.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg=="],
|
||||
|
||||
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
|
||||
"expo-modules-autolinking/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||
@@ -1907,6 +1986,8 @@
|
||||
|
||||
"ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
||||
|
||||
"parse-png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
|
||||
|
||||
"path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||
|
||||
"pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
||||
@@ -1915,6 +1996,8 @@
|
||||
|
||||
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
|
||||
"qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="],
|
||||
|
||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||
|
||||
"react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="],
|
||||
@@ -2021,6 +2104,8 @@
|
||||
|
||||
"cosmiconfig/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
|
||||
"expo-dev-launcher/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
|
||||
"expo-modules-autolinking/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||
@@ -2043,6 +2128,14 @@
|
||||
|
||||
"ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
|
||||
|
||||
"qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="],
|
||||
|
||||
"qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
|
||||
|
||||
"qrcode/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="],
|
||||
|
||||
"qrcode/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="],
|
||||
|
||||
"react-native-paper/color/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
|
||||
|
||||
"react-native-vector-icons/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="],
|
||||
@@ -2081,6 +2174,14 @@
|
||||
|
||||
"ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
|
||||
|
||||
"qrcode/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"qrcode/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
|
||||
|
||||
"qrcode/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
|
||||
|
||||
"qrcode/yargs/yargs-parser/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
|
||||
|
||||
"react-native-paper/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"react-native-vector-icons/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
@@ -2096,5 +2197,9 @@
|
||||
"log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"qrcode/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||
|
||||
"qrcode/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
|
||||
}
|
||||
}
|
||||
|
||||
59
components/ActionIcon/ActionIcon.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { Href, router } from "expo-router";
|
||||
import { DimensionValue, TouchableOpacity } from "react-native";
|
||||
|
||||
type SizeType = "xs" | "sm" | "md" | "lg" | "xl" | number | string | undefined;
|
||||
|
||||
export default function ActionIcon({
|
||||
href,
|
||||
onPress,
|
||||
icon,
|
||||
size = "md",
|
||||
}: {
|
||||
href?: Href;
|
||||
onPress?: () => void;
|
||||
icon: React.ReactNode;
|
||||
size?: SizeType;
|
||||
}) {
|
||||
const sizeMap = {
|
||||
xs: 22,
|
||||
sm: 26,
|
||||
md: 30,
|
||||
lg: 34,
|
||||
xl: 38,
|
||||
};
|
||||
|
||||
const getSize = (size: SizeType): DimensionValue => {
|
||||
if (!size) return sizeMap.md; // Default to 'md' if size is undefined
|
||||
if (typeof size === 'string' && size in sizeMap) {
|
||||
return sizeMap[size as keyof typeof sizeMap];
|
||||
}
|
||||
return size as DimensionValue;
|
||||
};
|
||||
|
||||
const iconSize = getSize(size);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.7}
|
||||
style={{
|
||||
backgroundColor: MainColor.yellow,
|
||||
padding: 5,
|
||||
borderRadius: 50,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
}}
|
||||
onPress={() => {
|
||||
if (href) {
|
||||
router.push(href);
|
||||
} else {
|
||||
onPress?.();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
@@ -3,8 +3,9 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import Grid from "../Grid/GridCustom";
|
||||
import TextCustom from "../Text/TextCustom";
|
||||
import BaseBox from "./BaseBox";
|
||||
import React from "react";
|
||||
|
||||
export default function InformationBox({ text }: { text: string }) {
|
||||
export default function InformationBox({ text }: { text: React.ReactNode | string }) {
|
||||
return (
|
||||
<>
|
||||
<BaseBox paddingTop={5} paddingBottom={5}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccentColor } from "@/constants/color-palet";
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
import { MaterialIcons } from "@expo/vector-icons"; // Bisa diganti dengan ikon lain
|
||||
import React, { useContext } from "react";
|
||||
import { Animated, Text, TouchableOpacity, View } from "react-native";
|
||||
@@ -17,7 +17,7 @@ const CheckboxGroupContext =
|
||||
// Tipe props
|
||||
// Tambahkan prop baru: groupValueKey
|
||||
interface CheckboxProps {
|
||||
label?: string;
|
||||
label?: string | React.ReactNode;
|
||||
description?: string;
|
||||
error?: string;
|
||||
value?: boolean; // controlled value (untuk standalone)
|
||||
@@ -39,7 +39,7 @@ const CheckboxCustom: React.FC<CheckboxProps> = ({
|
||||
onChange,
|
||||
disabled: propDisabled,
|
||||
size = 20,
|
||||
color = AccentColor.softblue,
|
||||
color = MainColor.yellow,
|
||||
style,
|
||||
component,
|
||||
valueKey,
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import React from "react";
|
||||
import { StyleSheet, TextInput, View } from "react-native";
|
||||
import { StyleProp, StyleSheet, TextInput, View, ViewStyle } from "react-native";
|
||||
|
||||
interface CircularInputProps {
|
||||
value: string | number;
|
||||
onChange?: (value: string) => void;
|
||||
value?: string | number
|
||||
onChange?: (value: string | number) => void;
|
||||
icon?: React.ReactNode;
|
||||
style?: StyleProp<ViewStyle>
|
||||
}
|
||||
|
||||
const CircularInput: React.FC<CircularInputProps> = ({ value, onChange }) => {
|
||||
const CircularInput: React.FC<CircularInputProps> = ({ value, onChange, icon, style }) => {
|
||||
return (
|
||||
<View style={styles.circleContainer}>
|
||||
<TextInput
|
||||
value={String(value)}
|
||||
onChangeText={onChange}
|
||||
style={styles.input}
|
||||
keyboardType="numeric"
|
||||
maxLength={2} // Batasan maksimal karakter
|
||||
/>
|
||||
<View style={[styles.circleContainer, style]}>
|
||||
{icon ? (
|
||||
icon
|
||||
) : (
|
||||
<TextInput
|
||||
value={String(value)}
|
||||
onChangeText={onChange}
|
||||
style={styles.input}
|
||||
keyboardType="numeric"
|
||||
maxLength={2} // Batasan maksimal karakter
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@ import { AccentColor } from "@/constants/color-palet";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function Divider({
|
||||
color = AccentColor.blue,
|
||||
size = 1,
|
||||
color = AccentColor.white,
|
||||
size = 0.5,
|
||||
marginTop= 12,
|
||||
marginBottom= 12,
|
||||
}: {
|
||||
|
||||
157
components/Drawer/DrawerAdmin.tsx
Normal file
@@ -0,0 +1,157 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import {
|
||||
Animated,
|
||||
Dimensions,
|
||||
InteractionManager,
|
||||
PanResponder,
|
||||
StyleSheet,
|
||||
} from "react-native";
|
||||
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
// Lebar drawer (bisa di-pass sebagai prop)
|
||||
const DRAWER_WIDTH = Dimensions.get("window").width * 0.8; // 80% lebar layar
|
||||
|
||||
interface DrawerAdminProps {
|
||||
children?: React.ReactNode;
|
||||
width?: number; // lebar drawer
|
||||
isVisible: boolean;
|
||||
onClose: () => void; // ganti nama dari closeDrawer agar lebih jelas
|
||||
}
|
||||
|
||||
export default function DrawerAdmin({
|
||||
children,
|
||||
width = DRAWER_WIDTH,
|
||||
isVisible,
|
||||
onClose,
|
||||
}: DrawerAdminProps) {
|
||||
const drawerAnim = useRef(new Animated.Value(-width)).current; // mulai dari kiri (tersembunyi)
|
||||
|
||||
// Efek untuk handle animasi saat isVisible berubah
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
Animated.timing(drawerAnim, {
|
||||
toValue: 0,
|
||||
duration: 300,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
} else {
|
||||
Animated.timing(drawerAnim, {
|
||||
toValue: -width,
|
||||
duration: 300,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
}, [isVisible, width, onClose, drawerAnim]);
|
||||
|
||||
const panResponder = useRef(
|
||||
PanResponder.create({
|
||||
onMoveShouldSetPanResponder: (_, gestureState) => {
|
||||
return Math.abs(gestureState.dx) > 10; // deteksi gesek horizontal
|
||||
},
|
||||
onPanResponderMove: (_, gestureState) => {
|
||||
let newAnim = gestureState.dx; // geser ke kanan = dx positif → drawerAnim negatif
|
||||
newAnim = Math.max(-width, Math.min(0, newAnim)); // batas antara -width dan 0
|
||||
drawerAnim.setValue(newAnim);
|
||||
},
|
||||
onPanResponderRelease: (_, gestureState) => {
|
||||
if (gestureState.dx > 100) {
|
||||
// gesek kencang ke kiri → tutup
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
onClose();
|
||||
});
|
||||
} else {
|
||||
// kembali ke posisi terbuka penuh
|
||||
Animated.spring(drawerAnim, {
|
||||
toValue: 0,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
},
|
||||
})
|
||||
).current;
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Overlay Gelap */}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.overlay,
|
||||
{
|
||||
opacity: drawerAnim.interpolate({
|
||||
inputRange: [-width, 0],
|
||||
outputRange: [0, 0.6],
|
||||
extrapolate: "clamp",
|
||||
}),
|
||||
},
|
||||
]}
|
||||
onTouchStart={() => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
onClose();
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Left Drawer */}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.drawer,
|
||||
{
|
||||
width,
|
||||
transform: [{ translateX: drawerAnim }],
|
||||
},
|
||||
]}
|
||||
{...panResponder.panHandlers}
|
||||
>
|
||||
{/* Handle Bar (opsional) */}
|
||||
<SafeAreaView
|
||||
edges={["top", "bottom"]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
{/* <Spacing/> */}
|
||||
</SafeAreaView>
|
||||
</Animated.View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: "black",
|
||||
zIndex: 998,
|
||||
},
|
||||
drawer: {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
// borderRadius: 20, // opsional
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 2, height: 0 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 5,
|
||||
elevation: 5,
|
||||
zIndex: 999,
|
||||
padding: 20,
|
||||
},
|
||||
handleBar: {
|
||||
width: 10,
|
||||
height: 5,
|
||||
backgroundColor: MainColor.yellow,
|
||||
borderRadius: 5,
|
||||
alignSelf: "flex-start",
|
||||
marginBottom: 20,
|
||||
},
|
||||
});
|
||||
@@ -7,7 +7,8 @@ import { Href } from "expo-router";
|
||||
type IMenuDrawerItemProps = {
|
||||
icon: React.ReactNode;
|
||||
label: string;
|
||||
path?: Href;
|
||||
value?: string;
|
||||
path?: Href | string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
|
||||
276
components/Drawer/NavbarMenu.tsx
Normal file
@@ -0,0 +1,276 @@
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router, usePathname } from "expo-router";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Animated,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
|
||||
export interface NavbarItem {
|
||||
label: string;
|
||||
icon?: keyof typeof Ionicons.glyphMap;
|
||||
color?: string;
|
||||
link?: string;
|
||||
links?: {
|
||||
label: string;
|
||||
link: string;
|
||||
}[];
|
||||
initiallyOpened?: boolean;
|
||||
}
|
||||
|
||||
interface NavbarMenuProps {
|
||||
items: NavbarItem[];
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export default function NavbarMenu({ items, onClose }: NavbarMenuProps) {
|
||||
const pathname = usePathname();
|
||||
const [activeLink, setActiveLink] = useState<string | null>(null);
|
||||
const [openKeys, setOpenKeys] = useState<string[]>([]); // Untuk kontrol dropdown
|
||||
|
||||
// Normalisasi path: hapus trailing slash
|
||||
const normalizePath = (path: string) => path.replace(/\/+$/, "");
|
||||
const normalizedPathname = pathname ? normalizePath(pathname) : "";
|
||||
|
||||
// Set activeLink saat pathname berubah
|
||||
useEffect(() => {
|
||||
if (normalizedPathname) {
|
||||
setActiveLink(normalizedPathname);
|
||||
}
|
||||
}, [normalizedPathname]);
|
||||
|
||||
// Toggle dropdown
|
||||
const toggleOpen = (label: string) => {
|
||||
setOpenKeys((prev) =>
|
||||
prev.includes(label) ? prev.filter((key) => key !== label) : [label]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
// flex: 1,
|
||||
// backgroundColor: MainColor.black,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
paddingVertical: 10, // Opsional: tambahkan padding
|
||||
}}
|
||||
// showsVerticalScrollIndicator={false} // Opsional: sembunyikan indikator scroll
|
||||
>
|
||||
{items.map((item) => (
|
||||
<MenuItem
|
||||
key={item.label}
|
||||
item={item}
|
||||
onClose={onClose}
|
||||
activeLink={activeLink}
|
||||
setActiveLink={setActiveLink}
|
||||
isOpen={openKeys.includes(item.label)}
|
||||
toggleOpen={() => toggleOpen(item.label)}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Komponen Item Menu
|
||||
function MenuItem({
|
||||
item,
|
||||
onClose,
|
||||
activeLink,
|
||||
setActiveLink,
|
||||
isOpen,
|
||||
toggleOpen,
|
||||
}: {
|
||||
item: NavbarItem;
|
||||
onClose?: () => void;
|
||||
activeLink: string | null;
|
||||
setActiveLink: (link: string | null) => void;
|
||||
isOpen: boolean;
|
||||
toggleOpen: () => void;
|
||||
}) {
|
||||
const isActive = activeLink === item.link;
|
||||
const animatedHeight = useRef(new Animated.Value(0)).current;
|
||||
|
||||
// Animasi saat isOpen berubah
|
||||
React.useEffect(() => {
|
||||
Animated.timing(animatedHeight, {
|
||||
toValue: isOpen ? (item.links ? item.links.length * 40 : 0) : 0,
|
||||
duration: 200,
|
||||
useNativeDriver: false,
|
||||
}).start();
|
||||
}, [isOpen, item.links, animatedHeight]);
|
||||
|
||||
// Jika ada submenu
|
||||
if (item.links && item.links.length > 0) {
|
||||
return (
|
||||
<View>
|
||||
{/* Parent Item */}
|
||||
<TouchableOpacity style={styles.parentItem} onPress={toggleOpen}>
|
||||
<Ionicons
|
||||
name={item.icon}
|
||||
size={16}
|
||||
color={MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text style={styles.parentText}>{item.label}</Text>
|
||||
<Ionicons
|
||||
name={isOpen ? "chevron-up" : "chevron-down"}
|
||||
size={16}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Submenu (Animated) */}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.submenu,
|
||||
// {
|
||||
// backgroundColor: "red",
|
||||
// },
|
||||
{
|
||||
height: animatedHeight,
|
||||
opacity: animatedHeight.interpolate({
|
||||
inputRange: [0, item.links.length * 40],
|
||||
outputRange: [0, 1],
|
||||
extrapolate: "clamp",
|
||||
}),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item.links.map((subItem, index) => {
|
||||
const isSubActive = activeLink === subItem.link;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[styles.subItem, isSubActive && styles.subItemActive]}
|
||||
onPress={() => {
|
||||
setActiveLink(subItem.link);
|
||||
onClose?.();
|
||||
router.push(subItem.link as any);
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name="radio-button-on-outline"
|
||||
size={16}
|
||||
color={isSubActive ? MainColor.yellow : MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.subText,
|
||||
isSubActive && { color: MainColor.yellow },
|
||||
]}
|
||||
>
|
||||
{subItem.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Menu tanpa submenu
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.singleItem, isActive && styles.singleItemActive]}
|
||||
onPress={() => {
|
||||
setActiveLink(item.link || null);
|
||||
onClose?.();
|
||||
router.push(item.link as any);
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name={item.icon}
|
||||
size={16}
|
||||
color={isActive ? MainColor.yellow : MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.singleText,
|
||||
{ color: isActive ? MainColor.yellow : MainColor.white },
|
||||
]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
// Styles
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginBottom: 5,
|
||||
},
|
||||
parentItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 10,
|
||||
// backgroundColor: AccentColor.darkblue,
|
||||
borderRadius: 8,
|
||||
marginBottom: 5,
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
parentText: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
marginLeft: 10,
|
||||
color: MainColor.white,
|
||||
},
|
||||
singleItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 10,
|
||||
// backgroundColor: AccentColor.darkblue,
|
||||
borderRadius: 8,
|
||||
marginBottom: 5,
|
||||
},
|
||||
singleItemActive: {
|
||||
backgroundColor: AccentColor.blue,
|
||||
},
|
||||
singleText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
marginLeft: 10,
|
||||
color: MainColor.white,
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
textAlign: "center",
|
||||
paddingRight: 10,
|
||||
},
|
||||
submenu: {
|
||||
overflow: "hidden",
|
||||
marginLeft: 30,
|
||||
marginTop: 5,
|
||||
},
|
||||
subItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
borderRadius: 6,
|
||||
marginBottom: 4,
|
||||
},
|
||||
subItemActive: {
|
||||
backgroundColor: AccentColor.blue,
|
||||
},
|
||||
subText: {
|
||||
color: MainColor.white,
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
},
|
||||
});
|
||||
279
components/Drawer/SidebarMenu.tsx
Normal file
@@ -0,0 +1,279 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Animated,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router, usePathname } from "expo-router";
|
||||
|
||||
// Lebar sidebar
|
||||
const SIDEBAR_WIDTH = Dimensions.get("window").width * 0.8;
|
||||
|
||||
interface SidebarItem {
|
||||
label: string;
|
||||
icon?: keyof typeof Ionicons.glyphMap;
|
||||
color?: string;
|
||||
link?: string;
|
||||
links?: {
|
||||
label: string;
|
||||
link: string;
|
||||
}[];
|
||||
initiallyOpened?: boolean;
|
||||
}
|
||||
|
||||
interface SidebarMenuProps {
|
||||
items: SidebarItem[];
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export default function SidebarMenu({ items, onClose }: SidebarMenuProps) {
|
||||
const pathname = usePathname();
|
||||
const [activeLink, setActiveLink] = useState<string | null>(null);
|
||||
const [openKeys, setOpenKeys] = useState<string[]>([]); // Untuk kontrol dropdown
|
||||
|
||||
// Normalisasi path: hapus trailing slash
|
||||
const normalizePath = (path: string) => path.replace(/\/+$/, "");
|
||||
const normalizedPathname = pathname ? normalizePath(pathname) : "";
|
||||
|
||||
// Set activeLink saat pathname berubah
|
||||
useEffect(() => {
|
||||
if (normalizedPathname) {
|
||||
setActiveLink(normalizedPathname);
|
||||
}
|
||||
}, [normalizedPathname]);
|
||||
|
||||
// Auto-buka dropdown jika submenu aktif
|
||||
useEffect(() => {
|
||||
const activeItem = items.find((item) =>
|
||||
item.links?.some((sub) => sub.link === normalizedPathname)
|
||||
);
|
||||
if (activeItem && !openKeys.includes(activeItem.label)) {
|
||||
setOpenKeys([activeItem.label]);
|
||||
}
|
||||
}, [normalizedPathname, items, openKeys]);
|
||||
|
||||
// Toggle dropdown
|
||||
const toggleOpen = (label: string) => {
|
||||
setOpenKeys((prev) =>
|
||||
prev.includes(label) ? prev.filter((key) => key !== label) : [label]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{items.map((item) => (
|
||||
<MenuItem
|
||||
key={item.label}
|
||||
item={item}
|
||||
onClose={onClose}
|
||||
activeLink={activeLink}
|
||||
setActiveLink={setActiveLink}
|
||||
isOpen={openKeys.includes(item.label)}
|
||||
toggleOpen={() => toggleOpen(item.label)}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Komponen Item Menu
|
||||
function MenuItem({
|
||||
item,
|
||||
onClose,
|
||||
activeLink,
|
||||
setActiveLink,
|
||||
isOpen,
|
||||
toggleOpen,
|
||||
}: {
|
||||
item: SidebarItem;
|
||||
onClose?: () => void;
|
||||
activeLink: string | null;
|
||||
setActiveLink: (link: string | null) => void;
|
||||
isOpen: boolean;
|
||||
toggleOpen: () => void;
|
||||
}) {
|
||||
const animatedHeight = useRef(new Animated.Value(0)).current;
|
||||
|
||||
// Animasi saat isOpen berubah
|
||||
React.useEffect(() => {
|
||||
Animated.timing(animatedHeight, {
|
||||
toValue: isOpen ? (item.links ? item.links.length * 40 : 0) : 0,
|
||||
duration: 200,
|
||||
useNativeDriver: false,
|
||||
}).start();
|
||||
}, [isOpen, item.links]);
|
||||
|
||||
// Cek apakah menu ini aktif
|
||||
const isActive = activeLink === item.link;
|
||||
|
||||
// Cek apakah ada submenu aktif
|
||||
const hasActiveSubItem = item.links?.some((sub) => sub.link === activeLink);
|
||||
|
||||
// Jika ada submenu
|
||||
if (item.links && item.links.length > 0) {
|
||||
return (
|
||||
<View>
|
||||
{/* Parent Item */}
|
||||
<TouchableOpacity style={styles.parentItem} onPress={toggleOpen}>
|
||||
<Ionicons
|
||||
name={item.icon}
|
||||
size={20}
|
||||
color={MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text style={styles.parentText}>{item.label}</Text>
|
||||
<Ionicons
|
||||
name={isOpen ? "chevron-up" : "chevron-down"}
|
||||
size={16}
|
||||
color={MainColor.white}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Submenu (Animated) */}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.submenu,
|
||||
{
|
||||
height: animatedHeight,
|
||||
opacity: animatedHeight.interpolate({
|
||||
inputRange: [0, item.links.length * 40],
|
||||
outputRange: [0, 1],
|
||||
extrapolate: "clamp",
|
||||
}),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item.links.map((subItem, index) => {
|
||||
const isSubActive = activeLink === subItem.link;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[styles.subItem, isSubActive && styles.subItemActive]}
|
||||
onPress={() => {
|
||||
setActiveLink(subItem.link);
|
||||
onClose?.();
|
||||
router.push(subItem.link as any);
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name="caret-forward-sharp"
|
||||
size={16}
|
||||
color={isSubActive ? MainColor.yellow : MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.subText,
|
||||
isSubActive && { color: MainColor.yellow },
|
||||
]}
|
||||
>
|
||||
{subItem.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Menu tanpa submenu
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.singleItem, isActive && styles.singleItemActive]}
|
||||
onPress={() => {
|
||||
setActiveLink(item.link || null);
|
||||
onClose?.();
|
||||
router.push(item.link as any);
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name={item.icon}
|
||||
size={20}
|
||||
color={isActive ? MainColor.yellow : MainColor.white}
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.singleText,
|
||||
{ color: isActive ? MainColor.yellow : MainColor.white },
|
||||
]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
// Styles
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginTop: 20,
|
||||
},
|
||||
parentItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 10,
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
borderRadius: 8,
|
||||
marginBottom: 5,
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
parentText: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
marginLeft: 10,
|
||||
color: MainColor.white,
|
||||
},
|
||||
singleItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 10,
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
borderRadius: 8,
|
||||
marginBottom: 5,
|
||||
},
|
||||
singleItemActive: {
|
||||
backgroundColor: AccentColor.blue,
|
||||
},
|
||||
singleText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
marginLeft: 10,
|
||||
color: MainColor.white,
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
textAlign: "center",
|
||||
paddingRight: 10,
|
||||
},
|
||||
submenu: {
|
||||
overflow: "hidden",
|
||||
marginLeft: 30,
|
||||
marginTop: 5,
|
||||
},
|
||||
subItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
borderRadius: 6,
|
||||
marginBottom: 4,
|
||||
},
|
||||
subItemActive: {
|
||||
backgroundColor: AccentColor.blue,
|
||||
},
|
||||
subText: {
|
||||
color: MainColor.white,
|
||||
fontSize: 14,
|
||||
},
|
||||
});
|
||||
@@ -5,9 +5,11 @@ import {
|
||||
FlatList,
|
||||
Modal,
|
||||
Pressable,
|
||||
StyleProp,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
ViewStyle,
|
||||
} from "react-native";
|
||||
|
||||
type SelectItem = {
|
||||
@@ -24,6 +26,7 @@ type SelectProps = {
|
||||
disabled?: boolean; // <-- tambahkan prop disabled
|
||||
onChange: (value: string | number) => void;
|
||||
borderRadius?: number;
|
||||
styleContainer?: StyleProp<ViewStyle>;
|
||||
};
|
||||
|
||||
const SelectCustom: React.FC<SelectProps> = ({
|
||||
@@ -35,6 +38,7 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
disabled = false, // <-- default false
|
||||
onChange,
|
||||
borderRadius = 8,
|
||||
styleContainer,
|
||||
}) => {
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
|
||||
@@ -43,7 +47,7 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
const hasError = required && value === null; // <-- check if empty and required
|
||||
|
||||
return (
|
||||
<View style={GStyles.inputContainerArea}>
|
||||
<View style={[GStyles.inputContainerArea, styleContainer]}>
|
||||
{label && (
|
||||
<Text style={GStyles.inputLabel}>
|
||||
{label}
|
||||
@@ -52,7 +56,7 @@ const SelectCustom: React.FC<SelectProps> = ({
|
||||
)}
|
||||
<Pressable
|
||||
style={[
|
||||
{ borderRadius },
|
||||
{ borderRadius, },
|
||||
hasError ? GStyles.inputErrorBorder : null,
|
||||
GStyles.inputContainerInput,
|
||||
disabled && GStyles.disabledBox,
|
||||
|
||||
@@ -22,7 +22,7 @@ interface TextCustomProps {
|
||||
style?: StyleProp<TextStyle>;
|
||||
bold?: boolean;
|
||||
semiBold?: boolean;
|
||||
size?: "default" | "large" | "small" | "xlarge";
|
||||
size?: "default" | "large" | "small" | "xlarge" | number
|
||||
color?: "default" | "yellow" | "red" | "gray" | "green" | "black"
|
||||
align?: TextAlign; // Prop untuk alignment
|
||||
truncate?: boolean | number;
|
||||
@@ -54,6 +54,7 @@ const TextCustom: React.FC<TextCustomProps> = ({
|
||||
if (size === "large") selectedStyles.push(styles.large);
|
||||
else if (size === "xlarge") selectedStyles.push(styles.xlarge);
|
||||
else if (size === "small") selectedStyles.push(styles.small);
|
||||
else if (typeof size === "number") selectedStyles.push({ fontSize: size });
|
||||
|
||||
// Color
|
||||
if (color === "yellow") selectedStyles.push(styles.yellow);
|
||||
@@ -105,7 +106,7 @@ export const styles = StyleSheet.create({
|
||||
fontSize: TEXT_SIZE_MEDIUM,
|
||||
color: MainColor.white,
|
||||
fontFamily: "Poppins-Regular",
|
||||
lineHeight: 20,
|
||||
// lineHeight: 20,
|
||||
},
|
||||
bold: {
|
||||
fontFamily: "Poppins-Bold",
|
||||
|
||||
@@ -2,11 +2,11 @@ import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
export default function IconArchive({ color }: { color?: string }) {
|
||||
export default function IconArchive({ color, size }: { color?: string; size?: number }) {
|
||||
return (
|
||||
<Ionicons
|
||||
name="archive"
|
||||
size={ICON_SIZE_SMALL}
|
||||
size={size || ICON_SIZE_SMALL}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
);
|
||||
|
||||
131
components/_Icon/IconComponent.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_MEDIUM } from "@/constants/constans-value";
|
||||
import {
|
||||
Entypo,
|
||||
FontAwesome,
|
||||
FontAwesome6,
|
||||
Ionicons,
|
||||
Octicons,
|
||||
} from "@expo/vector-icons";
|
||||
|
||||
export const IconPublish = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Entypo
|
||||
name="publish"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconReview = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<FontAwesome6
|
||||
name="person-circle-check"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconReject = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<FontAwesome
|
||||
name="warning"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconReport = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Octicons
|
||||
name="report"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconView = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Octicons
|
||||
name="eye"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconDot = ({ size, color }: { size?: number; color?: string }) => {
|
||||
return (
|
||||
<>
|
||||
<Ionicons
|
||||
name="ellipsis-vertical"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.darkblue}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconList = ({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Ionicons
|
||||
name="list"
|
||||
size={size || ICON_SIZE_MEDIUM}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||
import { FontAwesome5 } from "@expo/vector-icons";
|
||||
|
||||
export default function IconEdit() {
|
||||
export default function IconEdit({
|
||||
size,
|
||||
color,
|
||||
}: {
|
||||
size: number;
|
||||
color: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<FontAwesome5 name="edit" size={ICON_SIZE_SMALL} color="white" />
|
||||
<FontAwesome5
|
||||
name="edit"
|
||||
size={size || ICON_SIZE_SMALL}
|
||||
color={color || MainColor.white}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
21
components/_ShareComponent/Admin/ActionIconPlus.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import ActionIcon from "@/components/ActionIcon/ActionIcon";
|
||||
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { View } from "react-native";
|
||||
|
||||
export default function AdminActionIconPlus({
|
||||
onPress,
|
||||
}: {
|
||||
onPress?: () => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
<ActionIcon
|
||||
icon={<Ionicons name="add" size={ICON_SIZE_SMALL} color="black" />}
|
||||
onPress={onPress}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
13
components/_ShareComponent/Admin/BackButton.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import ActionIcon from "@/components/ActionIcon/ActionIcon";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
|
||||
export default function AdminBackButton() {
|
||||
return (
|
||||
<ActionIcon
|
||||
icon={<Ionicons name="arrow-back" size={16} color={MainColor.darkblue} />}
|
||||
onPress={() => router.back()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
41
components/_ShareComponent/Admin/BackButtonAntTitle.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import TextCustom from "@/components/Text/TextCustom";
|
||||
import AdminBackButton from "./BackButton";
|
||||
|
||||
export default function AdminBackButtonAntTitle({
|
||||
title,
|
||||
rightComponent,
|
||||
newComponent,
|
||||
}: {
|
||||
title?: string;
|
||||
rightComponent?: React.ReactNode;
|
||||
newComponent?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Grid>
|
||||
<Grid.Col span={2} style={{ justifyContent: "center" }}>
|
||||
<AdminBackButton />
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={newComponent ? 10 : 8}
|
||||
style={{ alignItems: "center", justifyContent: "center" }}
|
||||
>
|
||||
{newComponent ? (
|
||||
newComponent
|
||||
) : (
|
||||
<TextCustom bold size={"large"} align="center">
|
||||
{title}
|
||||
</TextCustom>
|
||||
)}
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={newComponent ? 0 : 2}
|
||||
style={{ alignItems: "flex-end" }}
|
||||
>
|
||||
{rightComponent}
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
46
components/_ShareComponent/Admin/BoxDashboard.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import BaseBox from "@/components/Box/BaseBox";
|
||||
import CircleContainer from "@/components/Container/CircleContainer";
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import StackCustom from "@/components/Stack/StackCustom";
|
||||
import TextCustom from "@/components/Text/TextCustom";
|
||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||
|
||||
interface BoxDashboardProps {
|
||||
item: {
|
||||
label: string;
|
||||
value: string | number;
|
||||
icon: React.ReactNode;
|
||||
};
|
||||
}
|
||||
|
||||
export default function AdminComp_BoxDashboard({ item }: BoxDashboardProps) {
|
||||
return (
|
||||
<>
|
||||
<BaseBox
|
||||
backgroundColor={MainColor.soft_darkblue}
|
||||
paddingTop={5}
|
||||
paddingBottom={5}
|
||||
>
|
||||
<Grid containerStyle={{ marginBlock: 0 }}>
|
||||
<Grid.Col
|
||||
span={9}
|
||||
style={{
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
>
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom bold>{item.label}</TextCustom>
|
||||
<TextCustom size={50}>{item.value}</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{ alignItems: "flex-start", justifyContent: "center" }}
|
||||
>
|
||||
<CircleContainer style={{ backgroundColor: MainColor.white, borderColor: AccentColor.blue }} icon={item.icon} />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
</>
|
||||
);
|
||||
}
|
||||
45
components/_ShareComponent/Admin/BoxTitlePage.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import BaseBox from "@/components/Box/BaseBox";
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import TextCustom from "@/components/Text/TextCustom";
|
||||
import { TEXT_SIZE_LARGE } from "@/constants/constans-value";
|
||||
|
||||
export default function AdminComp_BoxTitle({
|
||||
title,
|
||||
rightComponent,
|
||||
}: {
|
||||
title: string;
|
||||
rightComponent?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<BaseBox
|
||||
style={{ flexDirection: "row", justifyContent: "space-between" }}
|
||||
paddingTop={5}
|
||||
paddingBottom={5}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={rightComponent ? 6 : 12} style={{ justifyContent: "center" }}>
|
||||
<TextCustom
|
||||
// style={{ alignSelf: "center" }}
|
||||
bold
|
||||
size={TEXT_SIZE_LARGE}
|
||||
>
|
||||
{title}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
{rightComponent && (
|
||||
<Grid.Col
|
||||
span={6}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "flex-end",
|
||||
}}
|
||||
>
|
||||
{rightComponent}
|
||||
</Grid.Col>
|
||||
)}
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
</>
|
||||
);
|
||||
}
|
||||
24
components/_ShareComponent/Admin/ButtonReject.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IconReject } from "@/components/_Icon/IconComponent";
|
||||
import ButtonCustom from "@/components/Button/ButtonCustom";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminButtonReject({
|
||||
title,
|
||||
onReject,
|
||||
}: {
|
||||
title: string;
|
||||
onReject: () => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ButtonCustom
|
||||
iconLeft={<IconReject />}
|
||||
backgroundColor={MainColor.red}
|
||||
textColor="white"
|
||||
onPress={onReject}
|
||||
>
|
||||
{title}
|
||||
</ButtonCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
39
components/_ShareComponent/Admin/ButtonReview.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { IconPublish, IconReject } from "@/components/_Icon/IconComponent";
|
||||
import ButtonCustom from "@/components/Button/ButtonCustom";
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
|
||||
export default function AdminButtonReview({
|
||||
onPublish,
|
||||
onReject,
|
||||
}: {
|
||||
onPublish: () => void;
|
||||
onReject: () => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Grid>
|
||||
<Grid.Col span={6} style={{ paddingRight: 10 }}>
|
||||
<ButtonCustom
|
||||
iconLeft={<IconPublish />}
|
||||
backgroundColor={MainColor.green}
|
||||
textColor="white"
|
||||
onPress={onPublish}
|
||||
>
|
||||
Publish
|
||||
</ButtonCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ paddingLeft: 10 }}>
|
||||
<ButtonCustom
|
||||
iconLeft={<IconReject />}
|
||||
backgroundColor={MainColor.red}
|
||||
textColor="white"
|
||||
onPress={onReject}
|
||||
>
|
||||
Reject
|
||||
</ButtonCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
28
components/_ShareComponent/Admin/TableTitle.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import TextCustom from "@/components/Text/TextCustom";
|
||||
|
||||
export default function AdminTitleTable({
|
||||
title1,
|
||||
title2,
|
||||
title3,
|
||||
}: {
|
||||
title1: string;
|
||||
title2: string;
|
||||
title3: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Grid>
|
||||
<Grid.Col span={3} style={{ alignItems: "center", justifyContent: "center" }}>
|
||||
<TextCustom bold align="center">{title1}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={3} style={{ alignItems: "center", justifyContent: "center" }}>
|
||||
<TextCustom bold align="center">{title2}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6} style={{ alignItems: "center", justifyContent: "center" }}>
|
||||
<TextCustom bold align="center">{title3}</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
56
components/_ShareComponent/Admin/TableValue.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import Grid from "@/components/Grid/GridCustom";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
export default function AdminTableValue({
|
||||
value1,
|
||||
value2,
|
||||
value3,
|
||||
}: {
|
||||
value1: React.ReactNode;
|
||||
value2: React.ReactNode;
|
||||
value3: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<View style={{ paddingVertical: 5 }}>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
{value1}
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
{value2}
|
||||
</Grid.Col>
|
||||
<Grid.Col
|
||||
span={6}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
{value3}
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Divider />
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||