Compare commits
11 Commits
amalia/05-
...
amalia/17-
| Author | SHA1 | Date | |
|---|---|---|---|
| 772551a917 | |||
| 555b9e4037 | |||
| d4b4db4251 | |||
| 17d92cba25 | |||
| e1b62be6da | |||
| b2b125c410 | |||
| 1cfecbbdd5 | |||
| 21006e8eee | |||
| 91231d60e4 | |||
| 7174e27be1 | |||
| 9d4b931aa6 |
@@ -1,6 +1,6 @@
|
|||||||
# Desa+
|
# Desa+
|
||||||
|
|
||||||
Desa+ adalah aplikasi mobile berbasis React Native yang dikembangkan dengan Expo untuk membantu pengelolaan dan komunikasi di lingkungan desa/kelurahan. Aplikasi ini menyediakan berbagai fitur untuk memudahkan administrasi desa, komunikasi antar warga, dan pengelolaan informasi penting.
|
Desa+ (Desa Plus) adalah aplikasi mobile berbasis React Native yang dikembangkan dengan Expo untuk membantu pengelolaan dan komunikasi di lingkungan desa/kelurahan. Aplikasi ini menyediakan berbagai fitur untuk memudahkan administrasi desa, komunikasi antar warga, dan pengelolaan informasi penting.
|
||||||
|
|
||||||
## Fitur Utama
|
## Fitur Utama
|
||||||
|
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ android {
|
|||||||
applicationId 'mobiledarmasaba.app'
|
applicationId 'mobiledarmasaba.app'
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 6
|
versionCode 16
|
||||||
versionName "1.0.2"
|
versionName "2.1.0"
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
debug {
|
debug {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 904 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -1,9 +1,9 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||||
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="android:statusBarColor">#ffffff</item>
|
<item name="android:statusBarColor">#ffffff</item>
|
||||||
|
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
||||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default {
|
|||||||
ios: {
|
ios: {
|
||||||
supportsTablet: true,
|
supportsTablet: true,
|
||||||
bundleIdentifier: "mobiledarmasaba.app",
|
bundleIdentifier: "mobiledarmasaba.app",
|
||||||
buildNumber: "8",
|
buildNumber: "9",
|
||||||
infoPlist: {
|
infoPlist: {
|
||||||
ITSAppUsesNonExemptEncryption: false,
|
ITSAppUsesNonExemptEncryption: false,
|
||||||
CFBundleDisplayName: "Desa+"
|
CFBundleDisplayName: "Desa+"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import AppHeader from "@/components/AppHeader";
|
|||||||
import BorderBottomItem from "@/components/borderBottomItem";
|
import BorderBottomItem from "@/components/borderBottomItem";
|
||||||
import Skeleton from "@/components/skeleton";
|
import Skeleton from "@/components/skeleton";
|
||||||
import Text from '@/components/Text';
|
import Text from '@/components/Text';
|
||||||
|
import ErrorView from "@/components/ErrorView";
|
||||||
import { ConstEnv } from "@/constants/ConstEnv";
|
import { ConstEnv } from "@/constants/ConstEnv";
|
||||||
import { isImageFile } from "@/constants/FileExtensions";
|
import { isImageFile } from "@/constants/FileExtensions";
|
||||||
import Styles from "@/constants/Styles";
|
import Styles from "@/constants/Styles";
|
||||||
@@ -65,6 +66,7 @@ export default function DetailAnnouncement() {
|
|||||||
const [loadingOpen, setLoadingOpen] = useState(false)
|
const [loadingOpen, setLoadingOpen] = useState(false)
|
||||||
const [preview, setPreview] = useState(false)
|
const [preview, setPreview] = useState(false)
|
||||||
const [chooseFile, setChooseFile] = useState<FileData>()
|
const [chooseFile, setChooseFile] = useState<FileData>()
|
||||||
|
const [isError, setIsError] = useState(false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the image preview modal for the selected image file
|
* Opens the image preview modal for the selected image file
|
||||||
@@ -79,6 +81,7 @@ export default function DetailAnnouncement() {
|
|||||||
|
|
||||||
async function handleLoad(loading: boolean) {
|
async function handleLoad(loading: boolean) {
|
||||||
try {
|
try {
|
||||||
|
setIsError(false)
|
||||||
setLoading(loading)
|
setLoading(loading)
|
||||||
const hasil = await decryptToken(String(token?.current))
|
const hasil = await decryptToken(String(token?.current))
|
||||||
const response: ApiResponse = await apiGetAnnouncementOne({ id: id, user: hasil })
|
const response: ApiResponse = await apiGetAnnouncementOne({ id: id, user: hasil })
|
||||||
@@ -87,10 +90,12 @@ export default function DetailAnnouncement() {
|
|||||||
setDataMember(response.member)
|
setDataMember(response.member)
|
||||||
setDataFile(response.file)
|
setDataFile(response.file)
|
||||||
} else {
|
} else {
|
||||||
|
setIsError(true)
|
||||||
Toast.show({ type: 'small', text1: response.message })
|
Toast.show({ type: 'small', text1: response.message })
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
setIsError(true)
|
||||||
const message = error?.response?.data?.message || "Gagal mengambil data"
|
const message = error?.response?.data?.message || "Gagal mengambil data"
|
||||||
|
|
||||||
Toast.show({ type: 'small', text1: message })
|
Toast.show({ type: 'small', text1: message })
|
||||||
@@ -206,104 +211,110 @@ export default function DetailAnnouncement() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View style={[Styles.p15, Styles.mb50]}>
|
{isError && !loading ? (
|
||||||
<View style={[Styles.wrapPaper, Styles.borderAll, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
<View style={[Styles.mv50]}>
|
||||||
{
|
<ErrorView />
|
||||||
loading ?
|
|
||||||
<View>
|
|
||||||
<View style={[Styles.rowOnly]}>
|
|
||||||
<Skeleton width={30} height={30} borderRadius={10} />
|
|
||||||
<View style={[Styles.flex1, Styles.ph05]}>
|
|
||||||
<Skeleton width={100} widthType="percent" height={30} borderRadius={10} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
</View>
|
|
||||||
:
|
|
||||||
<>
|
|
||||||
<View style={[Styles.rowOnly, Styles.alignStart]}>
|
|
||||||
<MaterialIcons name="campaign" size={25} color={colors.text} style={[Styles.mr05]} />
|
|
||||||
<Text style={[Styles.textDefaultSemiBold, Styles.w90, Styles.mt02]}>{data?.title}</Text>
|
|
||||||
</View>
|
|
||||||
<View style={[Styles.mt10]}>
|
|
||||||
{
|
|
||||||
hasHtmlTags(data?.desc) ?
|
|
||||||
<RenderHTML
|
|
||||||
contentWidth={contentWidth}
|
|
||||||
source={{ html: data?.desc }}
|
|
||||||
baseStyle={{ color: colors.text }}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<Text>{data?.desc}</Text>
|
|
||||||
}
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
{
|
) : (
|
||||||
dataFile.length > 0 && (
|
<View style={[Styles.p15, Styles.mb50]}>
|
||||||
<View style={[Styles.wrapPaper, Styles.borderAll, Styles.mt10, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
<View style={[Styles.wrapPaper, Styles.borderAll, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
||||||
<View style={[Styles.mb05]}>
|
{
|
||||||
<Text style={[Styles.textDefaultSemiBold]}>File</Text>
|
loading ?
|
||||||
</View>
|
<View>
|
||||||
{dataFile.map((item, index) => (
|
<View style={[Styles.rowOnly]}>
|
||||||
<BorderBottomItem
|
<Skeleton width={30} height={30} borderRadius={10} />
|
||||||
key={`${item.id}-${index}`}
|
<View style={[Styles.flex1, Styles.ph05]}>
|
||||||
borderType={index === dataFile.length - 1 ? 'none' : 'bottom'}
|
<Skeleton width={100} widthType="percent" height={30} borderRadius={10} />
|
||||||
icon={<MaterialCommunityIcons
|
</View>
|
||||||
name={isImageFile(item.extension) ? "file-image-outline" : "file-document-outline"}
|
|
||||||
size={25}
|
|
||||||
color={colors.text}
|
|
||||||
/>}
|
|
||||||
title={item.name + '.' + item.extension}
|
|
||||||
titleWeight="normal"
|
|
||||||
onPress={() => {
|
|
||||||
isImageFile(item.extension) ?
|
|
||||||
handleChooseFile(item)
|
|
||||||
: openFile(item)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<View style={[Styles.wrapPaper, Styles.borderAll, Styles.mt10, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
|
||||||
{
|
|
||||||
loading ?
|
|
||||||
arrSkeleton.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<View key={index}>
|
|
||||||
<Skeleton width={30} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
|
||||||
</View>
|
</View>
|
||||||
)
|
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
||||||
})
|
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
||||||
:
|
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
||||||
Object.keys(dataMember).map((v: any, i: any) => {
|
</View>
|
||||||
return (
|
:
|
||||||
<View key={i} style={[Styles.mb05]}>
|
<>
|
||||||
<Text style={[Styles.textDefaultSemiBold]}>{dataMember[v]?.[0].group}</Text>
|
<View style={[Styles.rowOnly, Styles.alignStart]}>
|
||||||
|
<MaterialIcons name="campaign" size={25} color={colors.text} style={[Styles.mr05]} />
|
||||||
|
<Text style={[Styles.textDefaultSemiBold, Styles.w90, Styles.mt02]}>{data?.title}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[Styles.mt10]}>
|
||||||
{
|
{
|
||||||
dataMember[v].map((item: any, x: any) => {
|
hasHtmlTags(data?.desc) ?
|
||||||
return (
|
<RenderHTML
|
||||||
<View key={x} style={[Styles.rowItemsCenter, Styles.w90]}>
|
contentWidth={contentWidth}
|
||||||
<Entypo name="dot-single" size={24} color={colors.text} />
|
source={{ html: data?.desc }}
|
||||||
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode='tail'>{item.division}</Text>
|
baseStyle={{ color: colors.text }}
|
||||||
</View>
|
/>
|
||||||
)
|
:
|
||||||
})
|
<Text>{data?.desc}</Text>
|
||||||
}
|
}
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
)
|
</>
|
||||||
})
|
}
|
||||||
|
|
||||||
|
</View>
|
||||||
|
{
|
||||||
|
dataFile.length > 0 && (
|
||||||
|
<View style={[Styles.wrapPaper, Styles.borderAll, Styles.mt10, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
||||||
|
<View style={[Styles.mb05]}>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold]}>File</Text>
|
||||||
|
</View>
|
||||||
|
{dataFile.map((item, index) => (
|
||||||
|
<BorderBottomItem
|
||||||
|
key={`${item.id}-${index}`}
|
||||||
|
borderType={index === dataFile.length - 1 ? 'none' : 'bottom'}
|
||||||
|
icon={<MaterialCommunityIcons
|
||||||
|
name={isImageFile(item.extension) ? "file-image-outline" : "file-document-outline"}
|
||||||
|
size={25}
|
||||||
|
color={colors.text}
|
||||||
|
/>}
|
||||||
|
title={item.name + '.' + item.extension}
|
||||||
|
titleWeight="normal"
|
||||||
|
onPress={() => {
|
||||||
|
isImageFile(item.extension) ?
|
||||||
|
handleChooseFile(item)
|
||||||
|
: openFile(item)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
<View style={[Styles.wrapPaper, Styles.borderAll, Styles.mt10, { backgroundColor: colors.card, borderColor: colors.icon + '20' }]}>
|
||||||
|
{
|
||||||
|
loading ?
|
||||||
|
arrSkeleton.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<View key={index}>
|
||||||
|
<Skeleton width={30} widthType="percent" height={10} borderRadius={10} />
|
||||||
|
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
||||||
|
<Skeleton width={100} widthType="percent" height={10} borderRadius={10} />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
:
|
||||||
|
Object.keys(dataMember).map((v: any, i: any) => {
|
||||||
|
return (
|
||||||
|
<View key={i} style={[Styles.mb05]}>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold]}>{dataMember[v]?.[0].group}</Text>
|
||||||
|
{
|
||||||
|
dataMember[v].map((item: any, x: any) => {
|
||||||
|
return (
|
||||||
|
<View key={x} style={[Styles.rowItemsCenter, Styles.w90]}>
|
||||||
|
<Entypo name="dot-single" size={24} color={colors.text} />
|
||||||
|
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode='tail'>{item.division}</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<ImageViewing
|
<ImageViewing
|
||||||
|
|||||||
42
components/ErrorView.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import Text from '@/components/Text';
|
||||||
|
import Styles from '@/constants/Styles';
|
||||||
|
import { useTheme } from '@/providers/ThemeProvider';
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
|
import React from 'react';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
|
||||||
|
interface ErrorViewProps {
|
||||||
|
title?: string;
|
||||||
|
message?: string;
|
||||||
|
icon?: keyof typeof MaterialCommunityIcons.glyphMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ErrorView component to display error or empty states.
|
||||||
|
* Used when data is not found, deleted, or an error occurs during fetching.
|
||||||
|
*/
|
||||||
|
export default function ErrorView({
|
||||||
|
title = "Terjadi Kesalahan",
|
||||||
|
message = "Data tidak ditemukan atau sudah dihapus.",
|
||||||
|
icon = "alert-circle-outline"
|
||||||
|
}: ErrorViewProps) {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[Styles.flex1, Styles.contentItemCenter, Styles.ph20]}>
|
||||||
|
<View style={[Styles.mb10]}>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={icon}
|
||||||
|
size={40}
|
||||||
|
color={colors.dimmed}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={[Styles.textDefaultSemiBold, { color: colors.text, textAlign: 'center' }]}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Text style={[Styles.textMediumNormal, { color: colors.dimmed, textAlign: 'center', marginTop: 4 }]}>
|
||||||
|
{message}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,10 +7,6 @@ import Text from "../Text";
|
|||||||
export default function ReportChartDocument({ data }: { data: { label: string; value: number; }[] }) {
|
export default function ReportChartDocument({ data }: { data: { label: string; value: number; }[] }) {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const maxValue = Math.max(...data.map(i => i.value))
|
const maxValue = Math.max(...data.map(i => i.value))
|
||||||
const barData = [
|
|
||||||
{ value: 23, label: 'Gambar', },
|
|
||||||
{ value: 12, label: 'Dokumen' },
|
|
||||||
];
|
|
||||||
const width = Dimensions.get("window").width;
|
const width = Dimensions.get("window").width;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export default function CaraouselHome2({ refreshing }: { refreshing: boolean })
|
|||||||
backgroundColor: colors.primary
|
backgroundColor: colors.primary
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
resizeMode="cover"
|
resizeMode="stretch"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }
|
|||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [data, setData] = useState<Props>([])
|
const [data, setData] = useState<Props>([])
|
||||||
const [maxValue, setMaxValue] = useState(5)
|
const [maxValue, setMaxValue] = useState(5)
|
||||||
|
const [chartKey, setChartKey] = useState(0)
|
||||||
const barData = [
|
const barData = [
|
||||||
{ value: 23, label: 'Gambar', frontColor: '#fac858' },
|
{ value: 23, label: 'Gambar', frontColor: '#fac858' },
|
||||||
{ value: 12, label: 'Dokumen', frontColor: '#92cc76' },
|
{ value: 12, label: 'Dokumen', frontColor: '#92cc76' },
|
||||||
@@ -32,8 +33,8 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }
|
|||||||
setLoading(loading)
|
setLoading(loading)
|
||||||
const hasil = await decryptToken(String(token?.current))
|
const hasil = await decryptToken(String(token?.current))
|
||||||
const response = await apiGetDataHome({ cat: "dokumen", user: hasil })
|
const response = await apiGetDataHome({ cat: "dokumen", user: hasil })
|
||||||
const maxValue = response.data.reduce((max: number, obj: { value: number; }) => Math.max(max, obj.value), -Infinity);
|
const maxVal = response.data.reduce((max: number, obj: { value: number; }) => Math.max(max, Number(obj.value)), 0);
|
||||||
const roundUp = Math.ceil(maxValue / 10) * 10
|
const roundUp = maxVal > 0 ? Math.ceil(maxVal / 10) * 10 : 10;
|
||||||
setMaxValue(roundUp)
|
setMaxValue(roundUp)
|
||||||
const convertedArray = response.data.map((item: { color: any; label: any; value: any; }) => ({
|
const convertedArray = response.data.map((item: { color: any; label: any; value: any; }) => ({
|
||||||
frontColor: item.color,
|
frontColor: item.color,
|
||||||
@@ -41,6 +42,7 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }
|
|||||||
value: Number(item.value)
|
value: Number(item.value)
|
||||||
}));
|
}));
|
||||||
setData(convertedArray)
|
setData(convertedArray)
|
||||||
|
setChartKey((prev: number) => prev + 1)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -49,8 +51,9 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (refreshing)
|
if (refreshing) {
|
||||||
handleData(false)
|
handleData(false)
|
||||||
|
}
|
||||||
}, [refreshing]);
|
}, [refreshing]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -64,6 +67,7 @@ export default function ChartDokumenHome({ refreshing }: { refreshing: boolean }
|
|||||||
loading ? <Skeleton width={100} height={200} borderRadius={10} widthType="percent" />
|
loading ? <Skeleton width={100} height={200} borderRadius={10} widthType="percent" />
|
||||||
:
|
:
|
||||||
<BarChart
|
<BarChart
|
||||||
|
key={chartKey}
|
||||||
showFractionalValues={false}
|
showFractionalValues={false}
|
||||||
showYAxisIndices
|
showYAxisIndices
|
||||||
noOfSections={4}
|
noOfSections={4}
|
||||||
|
|||||||
@@ -490,17 +490,17 @@ const Styles = StyleSheet.create({
|
|||||||
wrapItemDiscussion: {
|
wrapItemDiscussion: {
|
||||||
padding: 15,
|
padding: 15,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
borderColor: '#d6d8f6',
|
// borderColor: '#d6d8f6',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
},
|
},
|
||||||
wrapItemBorderBottom: {
|
wrapItemBorderBottom: {
|
||||||
padding: 10,
|
padding: 10,
|
||||||
borderColor: '#d6d8f6',
|
// borderColor: '#d6d8f6',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
},
|
},
|
||||||
wrapItemBorderAll: {
|
wrapItemBorderAll: {
|
||||||
padding: 10,
|
padding: 10,
|
||||||
borderColor: '#d6d8f6',
|
// borderColor: '#d6d8f6',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginBottom: 5
|
marginBottom: 5
|
||||||
|
|||||||
3
eas.json
@@ -28,7 +28,8 @@
|
|||||||
"buildType": "app-bundle"
|
"buildType": "app-bundle"
|
||||||
},
|
},
|
||||||
"ios": {
|
"ios": {
|
||||||
"simulator": false
|
"simulator": false,
|
||||||
|
"image": "latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -394,7 +394,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
||||||
PRODUCT_NAME = Desa;
|
PRODUCT_NAME = "Desa";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
||||||
PRODUCT_NAME = Desa;
|
PRODUCT_NAME = "Desa";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.0.5</string>
|
<string>2.1.0</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>7</string>
|
<string>9</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||