Fix backend
This commit is contained in:
parent
cc49e676ca
commit
92aa1cb2bb
4 changed files with 84 additions and 25 deletions
|
|
@ -11,7 +11,7 @@
|
|||
"buildType": "apk"
|
||||
},
|
||||
"env": {
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br"
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br/api"
|
||||
}
|
||||
},
|
||||
"preview": {
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
"buildType": "apk"
|
||||
},
|
||||
"env": {
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br"
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br/api"
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
"buildType": "app-bundle"
|
||||
},
|
||||
"env": {
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br"
|
||||
"EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br/api"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ const styles = StyleSheet.create({
|
|||
borderColor: COLORS.borderLight,
|
||||
},
|
||||
statValue: {
|
||||
fontSize: 20,
|
||||
fontSize: 18,
|
||||
fontWeight: "800",
|
||||
color: COLORS.text,
|
||||
marginBottom: 2,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ function getMonthOptions() {
|
|||
return Array.from({ length: 12 }, (_, i) => {
|
||||
const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
|
||||
const value = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
|
||||
const label = d.toLocaleDateString("pt-BR", { month: "long", year: "numeric" });
|
||||
const label = d.toLocaleDateString("pt-BR", {
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
return { value, label: label.charAt(0).toUpperCase() + label.slice(1) };
|
||||
});
|
||||
}
|
||||
|
|
@ -60,7 +63,12 @@ type CompanyReport = { name: string; rides: number; km: number; total: number };
|
|||
function buildCompanyReports(rides: RideDB[]): CompanyReport[] {
|
||||
const map = new Map<string, CompanyReport>();
|
||||
for (const r of rides) {
|
||||
const prev = map.get(r.company) ?? { name: r.company, rides: 0, km: 0, total: 0 };
|
||||
const prev = map.get(r.company) ?? {
|
||||
name: r.company,
|
||||
rides: 0,
|
||||
km: 0,
|
||||
total: 0,
|
||||
};
|
||||
map.set(r.company, {
|
||||
...prev,
|
||||
rides: prev.rides + 1,
|
||||
|
|
@ -109,8 +117,10 @@ function buildPdfHtml(
|
|||
)
|
||||
.join("");
|
||||
|
||||
const generated = new Date().toLocaleDateString("pt-BR") +
|
||||
" às " + new Date().toLocaleTimeString("pt-BR");
|
||||
const generated =
|
||||
new Date().toLocaleDateString("pt-BR") +
|
||||
" às " +
|
||||
new Date().toLocaleTimeString("pt-BR");
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html><head>
|
||||
|
|
@ -145,9 +155,11 @@ function buildPdfHtml(
|
|||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
${logoSrc
|
||||
${
|
||||
logoSrc
|
||||
? `<img class="logo" src="${logoSrc}" alt="TopTran"/>`
|
||||
: `<span class="logo-text">TopTran</span>`}
|
||||
: `<span class="logo-text">TopTran</span>`
|
||||
}
|
||||
<div class="header-info">
|
||||
<h2>Relatório de Corridas</h2>
|
||||
<p>${monthLabel}</p>
|
||||
|
|
@ -219,11 +231,16 @@ export default function RelatorioPage() {
|
|||
const companies = buildCompanyReports(rides);
|
||||
const totalKm = rides.reduce((s, r) => s + r.km, 0);
|
||||
const totalEarnings = rides.reduce((s, r) => s + r.total, 0);
|
||||
const monthLabel = MONTH_OPTIONS.find((o) => o.value === selectedMonth)?.label ?? selectedMonth;
|
||||
const monthLabel =
|
||||
MONTH_OPTIONS.find((o) => o.value === selectedMonth)?.label ??
|
||||
selectedMonth;
|
||||
|
||||
const handleExport = async () => {
|
||||
if (rides.length === 0) {
|
||||
Alert.alert("Sem dados", "Não há corridas registradas em " + monthLabel + ".");
|
||||
Alert.alert(
|
||||
"Sem dados",
|
||||
"Não há corridas registradas em " + monthLabel + ".",
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
|
@ -253,13 +270,20 @@ export default function RelatorioPage() {
|
|||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={() => router.back()} style={styles.backButton} activeOpacity={0.7}>
|
||||
<TouchableOpacity
|
||||
onPress={() => router.back()}
|
||||
style={styles.backButton}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Text style={styles.backIcon}>←</Text>
|
||||
<Text style={styles.backLabel}>Voltar</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView contentContainerStyle={styles.scroll} showsVerticalScrollIndicator={false}>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scroll}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<View style={styles.titleSection}>
|
||||
<Text style={styles.title}>Relatório</Text>
|
||||
<Text style={styles.subtitle}>Análise de ganhos por período</Text>
|
||||
|
|
@ -268,7 +292,11 @@ export default function RelatorioPage() {
|
|||
{/* Filtro de mês */}
|
||||
<View style={styles.filterCard}>
|
||||
<Text style={styles.cardLabel}>Período</Text>
|
||||
<Select value={selectedMonth} onValueChange={setSelectedMonth} items={MONTH_OPTIONS} />
|
||||
<Select
|
||||
value={selectedMonth}
|
||||
onValueChange={setSelectedMonth}
|
||||
items={MONTH_OPTIONS}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Cards de resumo */}
|
||||
|
|
@ -294,7 +322,9 @@ export default function RelatorioPage() {
|
|||
|
||||
{companies.length === 0 ? (
|
||||
<View style={styles.emptyCard}>
|
||||
<Text style={styles.emptyText}>Nenhuma corrida em {monthLabel}.</Text>
|
||||
<Text style={styles.emptyText}>
|
||||
Nenhuma corrida em {monthLabel}.
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
|
|
@ -308,7 +338,9 @@ export default function RelatorioPage() {
|
|||
</View>
|
||||
<View style={styles.companyStats}>
|
||||
<Text style={styles.companyKm}>{c.km.toFixed(1)} km</Text>
|
||||
<Text style={styles.companyTotal}>R$ {c.total.toFixed(2)}</Text>
|
||||
<Text style={styles.companyTotal}>
|
||||
R$ {c.total.toFixed(2)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
|
|
@ -319,7 +351,9 @@ export default function RelatorioPage() {
|
|||
</View>
|
||||
<View style={styles.companyStats}>
|
||||
<Text style={styles.companyKm}>{totalKm.toFixed(1)} km</Text>
|
||||
<Text style={styles.totalAmount}>R$ {totalEarnings.toFixed(2)}</Text>
|
||||
<Text style={styles.totalAmount}>
|
||||
R$ {totalEarnings.toFixed(2)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
|
|
@ -327,7 +361,10 @@ export default function RelatorioPage() {
|
|||
|
||||
{/* Botão exportar */}
|
||||
<TouchableOpacity
|
||||
style={[styles.exportButton, exporting && styles.exportButtonDisabled]}
|
||||
style={[
|
||||
styles.exportButton,
|
||||
exporting && styles.exportButtonDisabled,
|
||||
]}
|
||||
onPress={handleExport}
|
||||
disabled={exporting}
|
||||
activeOpacity={0.85}
|
||||
|
|
@ -364,7 +401,12 @@ const styles = StyleSheet.create({
|
|||
scroll: { padding: SPACING.lg, paddingBottom: 48 },
|
||||
|
||||
titleSection: { marginTop: SPACING.md, marginBottom: SPACING.xl },
|
||||
title: { fontSize: 28, fontWeight: "800", color: COLORS.text, marginBottom: 4 },
|
||||
title: {
|
||||
fontSize: 28,
|
||||
fontWeight: "800",
|
||||
color: COLORS.text,
|
||||
marginBottom: 4,
|
||||
},
|
||||
subtitle: { fontSize: 14, color: COLORS.textTertiary },
|
||||
|
||||
filterCard: {
|
||||
|
|
@ -384,7 +426,11 @@ const styles = StyleSheet.create({
|
|||
marginBottom: SPACING.sm,
|
||||
},
|
||||
|
||||
summaryRow: { flexDirection: "row", gap: SPACING.sm, marginBottom: SPACING.xl },
|
||||
summaryRow: {
|
||||
flexDirection: "row",
|
||||
gap: SPACING.sm,
|
||||
marginBottom: SPACING.xl,
|
||||
},
|
||||
summaryCard: {
|
||||
flex: 1,
|
||||
backgroundColor: COLORS.surface,
|
||||
|
|
@ -395,7 +441,12 @@ const styles = StyleSheet.create({
|
|||
alignItems: "center",
|
||||
},
|
||||
summaryCardAccent: { borderColor: COLORS.success },
|
||||
summaryValue: { fontSize: 20, fontWeight: "800", color: COLORS.text, marginBottom: 2 },
|
||||
summaryValue: {
|
||||
fontSize: 18,
|
||||
fontWeight: "800",
|
||||
color: COLORS.text,
|
||||
marginBottom: 2,
|
||||
},
|
||||
summaryValueAccent: { color: COLORS.success },
|
||||
summaryLabel: {
|
||||
fontSize: 10,
|
||||
|
|
@ -449,7 +500,11 @@ const styles = StyleSheet.create({
|
|||
borderRadius: BORDER_RADIUS.sm,
|
||||
overflow: "hidden",
|
||||
},
|
||||
companyStats: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" },
|
||||
companyStats: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
},
|
||||
companyKm: { fontSize: 13, color: COLORS.textSecondary },
|
||||
companyTotal: { fontSize: 18, fontWeight: "800", color: COLORS.text },
|
||||
|
||||
|
|
@ -473,5 +528,9 @@ const styles = StyleSheet.create({
|
|||
alignItems: "center",
|
||||
},
|
||||
exportButtonDisabled: { backgroundColor: COLORS.borderLight },
|
||||
exportButtonText: { fontSize: 15, fontWeight: "700", color: COLORS.background },
|
||||
exportButtonText: {
|
||||
fontSize: 15,
|
||||
fontWeight: "700",
|
||||
color: COLORS.background,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Reference in a new issue