import { BlurView } from "expo-blur"; import * as Haptics from "expo-haptics"; import { useRouter } from "expo-router"; import React, { memo, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { Platform, Pressable, StyleSheet, View } from "react-native"; import { IconButton, Text, useTheme } from "react-native-paper"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { logImEXEvent } from "../../firebase/firebase.analytics"; import { setCameraJobId } from "../../redux/app/app.actions"; import { openImagePicker } from "../../redux/photos/photos.actions"; const mapStateToProps = createStructuredSelector({}); const mapDispatchToProps = (dispatch) => ({ setCameraJobId: (id) => dispatch(setCameraJobId(id)), openImagePicker: (id) => dispatch(openImagePicker(id)), }); function JobListItemComponent({ openImagePicker, item }) { const { t } = useTranslation(); const router = useRouter(); const theme = useTheme(); const onPress = useCallback(() => { Haptics.selectionAsync(); logImEXEvent("imexmobile_view_job_detail"); router.navigate({ pathname: `/jobs/${item.id}`, params: { title: item.ro_number || t("general.labels.na"), }, }); }, [item.id, item.ro_number, router, t]); const handleUpload = useCallback(() => { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); openImagePicker(item.id); }, [openImagePicker, item.id]); const ownerName = `${item.ownr_fn || ""} ${item.ownr_ln || ""}`.trim(); const company = item.ownr_co_nm || ""; const vehicle = `${item.v_model_yr || ""} ${item.v_make_desc || ""} ${ item.v_model_desc || "" }`.trim(); const roNumber = item.ro_number || t("general.labels.na"); return ( [styles.pressable, pressed && { opacity: 0.85 }]} > {/* Translucent overlay for glass effect */} {roNumber} • {ownerName} {ownerName && company ? " • " : ""} {company} {!!vehicle && ( {vehicle} )} ); } const styles = StyleSheet.create({ pressable: { marginHorizontal: 12, marginVertical: 6, }, outerShadow: { borderRadius: 20, shadowColor: "#000", shadowOpacity: 0.12, shadowRadius: 8, shadowOffset: { width: 0, height: 4 }, elevation: 3, }, blurContainer: { overflow: "hidden", borderRadius: 20, }, glassCard: { padding: 14, borderRadius: 20, borderWidth: StyleSheet.hairlineWidth, backdropFilter: "blur(20px)", // web only }, cardContents: { flex: 1, flexDirection: "row", display: "flex", alignItems: "center", }, headerRow: { flexDirection: "row", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 4, }, leftHeader: { flex: 1, paddingRight: 8, }, roNumber: { fontSize: 18, fontWeight: "600", letterSpacing: 0.5, }, ownerInfo: { marginTop: 2, fontSize: 15, fontWeight: "500", opacity: 0.9, }, uploadButton: { margin: 0, }, body: { marginTop: 2, }, ownerText: { fontWeight: "600", }, }); const JobListItem = memo( JobListItemComponent, (prev, next) => prev.item.id === next.item.id ); export default connect(mapStateToProps, mapDispatchToProps)(JobListItem);