import React, { useCallback, useEffect, useRef, useState } from 'react'; import { View, Image, Text, StyleSheet, Dimensions, ScrollView, BackHandler, Alert, TouchableOpacity, ImageBackground } from 'react-native'; import { useNavigation, NavigationProp } from '@react-navigation/native'; import { ProgressChart } from 'react-native-chart-kit'; import { SvgUri } from 'react-native-svg'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { addStorage, cfg } from '@/components/lib/cfg'; import { DB } from '@/components/lib/db'; import { Asset } from 'expo-asset'; import config from '../../components/data/config.json'; import TimeLive from '@/components/Time'; import { useAppContext } from '@/components/AppContext'; import { useFocusEffect } from 'expo-router'; import { formatRupiah } from '@/components/Helper'; import LinearGradient from 'react-native-linear-gradient'; import { Ionicons } from '@expo/vector-icons'; import lang from '../../components/data/lang.json'; const screenWidth = Dimensions.get("window").width; const HomeScreen = () => { const {loadData:profileLoad}:any = useAppContext(); const profileScreenRef = useRef(null); const navigation = useNavigation>(); const [greeting, setGreeting] = useState(''); const [employeeData, setEmployeeData] = useState({job_title:'', name: '', work_email: '', work_phone: '' }); const [orderData, setOrderData] = useState([0]); const [visitData, setVisitData] = useState([0]); const [svgData, setSvgData] = useState(''); const [order, setOrder] = useState(0) const [invoice, setInvoice] = useState(0) const [order2, setOrder2] = useState(0) const [invoice2, setInvoice2] = useState(0) useEffect(() => { const loadSvg = async () => { const asset = Asset.fromModule(require('../../assets/images/bg/SORT_bg_Home.svg')); await asset.downloadAsync(); const response = await fetch(asset.uri); const svgText = await response.text(); setSvgData(svgText); }; loadSvg(); setGreeting(getGreeting()); getEmployeeData(); animateProgress(); const backAction = () => { Alert.alert( "Konfirmasi Keluar", "Apakah Anda yakin ingin keluar dari aplikasi?", [ { text: "Tidak", onPress: () => null, style: "cancel" }, { text: "Ya", onPress: () => { (async function(){ await AsyncStorage.clear(); navigation.reset({ index:0, routes:[{name:'index'}] }) BackHandler.exitApp() })(); } } ] ); return true; }; (async function(){ let [ord, inv]:any = await DB(`SELECT * FROM total_order`); let [ord2, inv2]: any = await DB(`SELECT * FROM total_order_count`); setInvoice(Number(inv.total)) setOrder(Number(ord.total)) setInvoice2(Number(inv2.total)) setOrder2(Number(ord2.total)) setOrderData([Math.min(100, ((Number(ord2.total) / (Number(ord2.total) + Number(inv2.total)) )) )]); setVisitData([Math.min(100, ((Number(inv2.total) / (Number(ord2.total) + Number(inv2.total)))))]); })(); const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction); return () => backHandler.remove(); }, [setSvgData, setInvoice,setOrder]); const getEmployeeData = async () => { try { const jsonValue = await AsyncStorage.getItem('login'); if (jsonValue !== null) { const data = JSON.parse(jsonValue); setEmployeeData(data[0]); } } catch (e) { console.error(e); } }; const getGreeting = () => { const hour = new Date().getHours(); if (hour < 12) { return 'Good Morning'; } else if (hour < 15) { return 'Good Afternoon'; } else if (hour < 18) { return 'Good Evening'; } else { return 'Good Night'; } }; const animateProgress = () => { let orderProgress = 0; let visitProgress = 0; const interval = setInterval(() => { orderProgress += 0.05; visitProgress += 0.05; setOrderData([Math.min(orderProgress, 0.75)]); setVisitData([Math.min(visitProgress, 0.65)]); if (orderProgress >= 0.75 && visitProgress >= 0.65) { clearInterval(interval); } }, 100); }; const orderConfig = { backgroundGradientFrom: '#fff', backgroundGradientTo: '#fff', color: (opacity = 1) => `rgba(255, 205, 26, ${opacity})`, }; const visitConfig = { backgroundGradientFrom: '#fff', backgroundGradientTo: '#fff', color: (opacity = 1) => `rgba(26, 255, 146, ${opacity})`, }; const renderMenuItems = () => { const menuItems = [ // { img: require('../../assets/images/icons/icon_sort_BuatPesanan.png') , action: "order", text: "BUAT\n PESANAN", uri: "https://www.svgrepo.com/show/375440/google-cloud-marketplace.svg" }, { img: require('../../assets/images/icons/icon_sort_StokBarang1.png') , action: "stock", text: "STOCK\n ITEMS", uri: "https://www.svgrepo.com/show/375469/os-inventory-management.svg" }, { img: require('../../assets/images/icons/icon_sort_ListPesanan.png') , action: "history", text: "ORDER\n HISTORY", uri: "https://www.svgrepo.com/show/375491/retail-api.svg" }, { img: require('../../assets/images/icons/icon_sort_Pelunasan.png') , action: "pelunasan", text: "PAYMENT", uri: "https://www.svgrepo.com/show/375438/gce-systems-management.svg" }, { img: require('../../assets/images/icons/icon_sort_OrderLunas.png') , action: "orderlunas", text: "PAID ORDERS", uri: "https://www.svgrepo.com/show/375438/gce-systems-management.svg" }, { img: require('../../assets/images/icons/icon_sort_OrderBelumLunas.png') , action: "orderbelumlunas", text: "UNPAID ORDERS", uri: "https://www.svgrepo.com/show/375438/gce-systems-management.svg" }, { img: require('../../assets/images/icons/icon_sort_ListCustomer.png') , action: "customer", text: "CUSTOMER\n LIST", uri: "https://www.svgrepo.com/show/375359/cloud-for-marketing.svg" }, // { img: require('../../assets/images/icons/icon_sort_Profil.png') , action: "profile", text: "PROFILE", uri: "https://www.svgrepo.com/show/375473/permissions.svg" }, // { img: require('../../assets/images/icons/icon_sort_Pengaturan.png') , action: "setting", text: "PENGATURAN", uri: "https://www.svgrepo.com/show/375438/gce-systems-management.svg" } ]; const numColumns = 3 ; const menuRows = []; for (let i = 0; i < menuItems.length; i += numColumns) { const items = menuItems.slice(i, i + numColumns); menuRows.push( {items.map((item, index) => ( { // profileLoad() navigation.navigate(item.action); }} key={`item-${i}-${index}`}> {item.text} ))} ); } return menuRows; }; const getData = async () => { DB('SELECT * FROM res_partner').then((data: any) => { cfg.dataPilihan.customer = data; }) } const getDataMaster: any = { uom: function () { return new Promise(async (resolve, reject) => { let uom = await DB(` SELECT C .NAME ->> 'en_US' kat, u.create_uid, u.NAME, u.factor FROM "public".uom_uom u LEFT JOIN "public".uom_category C ON C.create_uid = u.create_uid WHERE C.name->>'en_US' = 'Rokok' ORDER BY u.factor DESC `); addStorage("master oum", uom); cfg.dataPilihan.uom = uom; resolve(uom); }) }, uomkat: function () { return new Promise(async (resolve, reject) => { let uom = await DB(` SELECT create_uid, name FROM uom_category `); cfg.dataPilihan.uomkat = uom; addStorage('master uomkat', uom) resolve(uom); }) }, tax: function () { return new Promise(async (resolve, reject) => { let uom = await DB(` SELECT id, country_id, type_tax_use, amount_type, name, amount FROm account_tax `); cfg.dataPilihan.tax = uom; addStorage('master tax', uom) resolve(uom); }) } , product: function () { return new Promise(async (resolve, reject) => { let uom = await DB(` SELECT P .ID, P.NAME ->> 'en_US' AS NAME, P.list_price * factor AS list_price, P.uom_id, u.factor FROM product_template P LEFT JOIN product_tag_product_template_rel T ON P.ID = T.product_template_id LEFT JOIN product_tag pt ON T.product_tag_id = pt.ID LEFT JOIN uom_uom u ON u.id = p.uom_id WHERE pt.NAME ->> 'en_US' = 'rokok' ORDER BY id ASC; `); cfg.dataPilihan.product = uom; addStorage('master product', uom) resolve(uom); }) } } cfg.action['home'] = function () { getDataMaster.tax(); getData(); }; function capitalizeWords(str:any) { return str.split(' ').map((word:any) => { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }).join(' '); } useEffect(() => { getDataMaster.product(); getDataMaster.tax(); getData(); },[]) return ( Hi, {employeeData.name.toUpperCase()} ! {lang.en.login.selamat_datang} navigation.navigate('setting')} name="ellipsis-vertical" size={30} color={config.color.primary} /> Total Sales 67 `rgba(255, 215, 255, ${opacity})`, }} hideLegend={true} style={{backgroundColor: 'transparent'}} /> 60% Total Visit 13 `rgba(255, 255, 255, ${opacity})`, }} hideLegend={true} style={{backgroundColor: 'transparent'}} /> 30% 🏆 RANK 1 TOTAL ORDER Rp {formatRupiah(order.toString())} TOTAL COLLECTED Rp {formatRupiah(invoice.toString())} {/* Synchronize File */} {renderMenuItems()} navigation.navigate('home')} style={{ width: 140}}> Home navigation.navigate('order')} activeOpacity={1} style={{ justifyContent: "center", height: 60, flexDirection: "column", alignItems: "center" }}> navigation.navigate('profile')} style={{ width: 140}}> Profile ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f0f0f0', }, header: { flexDirection: 'row', alignItems: 'center', marginBottom : 10, }, avatar: { width: 55, height: 55, borderRadius: 40, }, info: { flex:1, marginLeft: 20, }, name: { fontSize: 25, fontWeight: 'bold', color: "white", }, greeting: { color: "white", fontSize: 16, fontWeight:'600' }, trophyRow: { flex: 1, flexDirection:'column', alignItems: 'flex-end', paddingHorizontal:20 }, gaugeRow: { padding: 10, flexDirection: 'row', }, card: { width: 280, height: 140, marginBottom: 10, padding: 10, marginHorizontal: 10, borderRadius: 10, shadowColor: '#000', shadowOpacity: 0.2, shadowOffset: { width: 0, height: 2 }, shadowRadius: 5, }, chartCenterText: { position: 'absolute', width:'100%', left:10, top: '45%', flexDirection:'column', justifyContent:'center', alignItems:'center' }, stats: { flexDirection: 'column', alignItems: 'center', padding: 15, marginHorizontal: 20, marginTop: 0, borderRadius: 10, shadowColor: '#000', shadowOpacity: 0.2, shadowOffset: { width: 0, height: 2 }, shadowRadius: 5, }, stat: { flex: 1, alignItems: 'center', }, statLabel: { color: 'white', fontWeight: '500', fontSize: 12, }, statValue: { fontSize: 18, fontWeight:'700', color:'white' }, syncRow: { paddingTop: 15, marginHorizontal: 10, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, bio: { paddingHorizontal: 20, fontSize: 17, fontWeight: '700', color: '#333', }, menuRow: { paddingTop: 5, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, cardMenu: { width: (screenWidth/3)-20, margin: 1, borderRadius: 10, shadowColor: '#000', shadowOpacity: 0.2, shadowRadius: 5, }, menu: { alignItems: 'center', fontSize: screenWidth > 411 ? 14 : 18, }, }); export default HomeScreen;