Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 40 additions & 16 deletions app/(report)/negativePoints.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import { Container } from '@/components/general/container';
import { Header } from '@/components/general/header';
import { NegativeFeedbackList } from '@/components/report/NegativeFeedbackList';
import { View } from 'react-native';
import { CardItemFeedback } from '@/components/report/CardItemFeedback';
import { CardListSkeleton } from '@/components/report/cardListSkeleton';
import { getReport } from '@/services/reports';
import { AIReportDetail } from '@/types/Report';
import { useLocalSearchParams } from 'expo-router';
import { useEffect, useState } from 'react';
import { ScrollView, View } from 'react-native';

export default function NegativePoints () {
return(
<Container>
<View>
<Header
title="Pontos negativos"
showBackButton
showNotificationButton
/>
export default function NegativePoints() {
const { report_id } = useLocalSearchParams<{ report_id: string }>();
const [report, setReport] = useState<AIReportDetail | null>(null);
const [loading, setLoading] = useState(true);

<NegativeFeedbackList handlePress={() => ''} />
</View>
</Container>
)
}
useEffect(() => {
if (!report_id) return;
getReport(report_id)
.then(setReport)
.finally(() => setLoading(false));
}, [report_id]);

return (
<Container>
<ScrollView showsVerticalScrollIndicator={false}>
<Header title="Pontos negativos" showBackButton showNotificationButton />
<View className="mt-10">
{loading ? (
<CardListSkeleton />
) : report ? (
<CardItemFeedback
icon={'warning'}
typeCard="negative"
text={report.melhorias_detalhado}
chages=""
automaticChanges={false}
handlePress={() => {}}
/>
) : null}
</View>
</ScrollView>
</Container>
);
}
56 changes: 40 additions & 16 deletions app/(report)/positivePoints.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import { Container } from '@/components/general/container';
import { Header } from '@/components/general/header';
import { PositiveFeedbackList } from '@/components/report/PositiveFeedbackList';
import { View } from 'react-native';
import { CardItemFeedback } from '@/components/report/CardItemFeedback';
import { CardListSkeleton } from '@/components/report/cardListSkeleton';
import { getReport } from '@/services/reports';
import { AIReportDetail } from '@/types/Report';
import { useLocalSearchParams } from 'expo-router';
import { useEffect, useState } from 'react';
import { ScrollView, View } from 'react-native';

export default function PositivePoints () {
return(
<Container>
<View>
<Header
title="Pontos positivos"
showBackButton
showNotificationButton
/>
export default function PositivePoints() {
const { report_id } = useLocalSearchParams<{ report_id: string }>();
const [report, setReport] = useState<AIReportDetail | null>(null);
const [loading, setLoading] = useState(true);

<PositiveFeedbackList handlePress={() => ''} />
</View>
</Container>
)
}
useEffect(() => {
if (!report_id) return;
getReport(report_id)
.then(setReport)
.finally(() => setLoading(false));
}, [report_id]);

return (
<Container>
<ScrollView showsVerticalScrollIndicator={false}>
<Header title="Pontos positivos" showBackButton showNotificationButton />
<View className="mt-10">
{loading ? (
<CardListSkeleton />
) : report ? (
<CardItemFeedback
icon={'analytics'}
typeCard="positive"
text={report.pontos_positivos_detalhado}
chages=""
automaticChanges={false}
handlePress={() => {}}
/>
) : null}
</View>
</ScrollView>
</Container>
);
}
56 changes: 40 additions & 16 deletions app/(report)/recomendations.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import { Container } from '@/components/general/container';
import { Header } from '@/components/general/header';
import { RecommendationFeedbackList } from '@/components/report/RecommendationFeedbackList';
import { View } from 'react-native';
import { CardItemFeedback } from '@/components/report/CardItemFeedback';
import { CardListSkeleton } from '@/components/report/cardListSkeleton';
import { getReport } from '@/services/reports';
import { AIReportDetail } from '@/types/Report';
import { useLocalSearchParams } from 'expo-router';
import { useEffect, useState } from 'react';
import { ScrollView, View } from 'react-native';

export default function Recomendations () {
return(
<Container>
<View>
<Header
title="Recomendações"
showBackButton
showNotificationButton
/>
export default function Recomendations() {
const { report_id } = useLocalSearchParams<{ report_id: string }>();
const [report, setReport] = useState<AIReportDetail | null>(null);
const [loading, setLoading] = useState(true);

<RecommendationFeedbackList handlePress={() => ''} />
</View>
</Container>
)
}
useEffect(() => {
if (!report_id) return;
getReport(report_id)
.then(setReport)
.finally(() => setLoading(false));
}, [report_id]);

return (
<Container>
<ScrollView showsVerticalScrollIndicator={false}>
<Header title="Recomendações" showBackButton showNotificationButton />
<View className="mt-10">
{loading ? (
<CardListSkeleton />
) : report ? (
<CardItemFeedback
icon={'bulb'}
typeCard="recomendation"
text={report.recomendacoes_detalhado}
chages=""
automaticChanges={false}
handlePress={() => {}}
/>
) : null}
</View>
</ScrollView>
</Container>
);
}
60 changes: 49 additions & 11 deletions app/(report)/report.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,65 @@
import { Container } from '@/components/general/container';
import GeneralButton from '@/components/general/generalButton';
import { Header } from '@/components/general/header';
import { CardList } from '@/components/report/CardList';
import { CardListSkeleton } from '@/components/report/cardListSkeleton';
import { ChatButton } from '@/components/report/chatButton';
import { useState } from 'react';
import { View } from 'react-native';
import { generateReport, getReportsByEnterprise } from '@/services/reports';
import { AIReportSummary } from '@/types/Report';
import { useEffect, useState } from 'react';
import { Text, View } from 'react-native';

const ENTERPRISE_ID = 'caa68f64-b68e-4327-90f0-264ca1bb73e2';

export default function Report() {
const [loading, setLoading] = useState(false)
const [report, setReport] = useState<AIReportSummary | null>(null);
const [loading, setLoading] = useState(true);
const [generating, setGenerating] = useState(false);

useEffect(() => {
fetchLatestReport();
}, []);

const handlePress = ()=> {
setLoading //to do
const fetchLatestReport = async () => {
try {
setLoading(true);
const reports = await getReportsByEnterprise(ENTERPRISE_ID);
if (reports.length > 0) {
setReport(reports[reports.length - 1]);
}
} finally {
setLoading(false);
}

return (
};

const handleGenerate = async () => {
try {
setGenerating(true);
const newReport = await generateReport(ENTERPRISE_ID);
setReport(newReport);
} finally {
setGenerating(false);
}
};

return (
<Container>
<View>
<Header title="Relatório" showBackButton showNotificationButton />
<ChatButton text='ChatBot' handlePress={handlePress}/>
{loading ? (
<CardListSkeleton />
<CardListSkeleton />
) : report ? (
<CardList report={report} />
) : (
<CardList />
<View className="mt-16 items-center gap-6 px-8">
<Text className="text-center text-dark font-semibold text-base">
Nenhum relatório gerado ainda. Gere o primeiro relatório do seu negócio.
</Text>
<GeneralButton
text="Gerar Relatório"
handlePress={handleGenerate}
loading={generating}
/>
</View>
)}
</View>
</Container>
Expand Down
80 changes: 39 additions & 41 deletions components/report/CardList.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,43 @@
import { AIReportSummary } from '@/types/Report'
import { router } from 'expo-router'
import { View } from 'react-native'
import { CardItem } from './CardItem'

export const CardList = ()=> {
const handlePresPositive = ()=> {
router.navigate('/(report)/positivePoints')
}
const handlePresNegative = ()=> {
router.navigate('/(report)/negativePoints')
}
const handlePresRecomendation = ()=> {
router.navigate('/(report)/recomendations')
}
return(
<View className="mt-10 gap-8">
<CardItem
icon={'analytics'}
topics={[
{id:1, text:'a sopa está boa'},
{id: 2, text:'parabéns pela salada'}]}
typeCard="positive"
handlePress={handlePresPositive}
/>
<CardItem
icon={'warning'}
topics={[
{id:1, text:'o feijão está ruim'},
{id: 2, text:'suco com muito açucar'},
{id: 3, text:'café muito forte'},
]}
typeCard="negative"
handlePress={handlePresNegative}
/>
<CardItem
icon={'bulb'}
topics={[
{id:1, text:'Data festiva próxima, sugiro adicionar comidas típicas'},
]}
typeCard="recomendation"
handlePress={handlePresRecomendation}
/>
</View>
)
}
type Props = {
report: AIReportSummary
}

export const CardList = ({ report }: Props) => {
const handlePressPositive = () => {
router.navigate({ pathname: '/positivePoints' as any, params: { report_id: report.id_relatorio } })
}
const handlePressNegative = () => {
router.navigate({ pathname: '/negativePoints' as any, params: { report_id: report.id_relatorio } })
}
const handlePressRecomendation = () => {
router.navigate({ pathname: '/recomendations' as any, params: { report_id: report.id_relatorio } })
}

return (
<View className="mt-10 gap-8">
<CardItem
icon={'analytics'}
topics={[{ id: 1, text: report.pontos_positivos_resumo }]}
typeCard="positive"
handlePress={handlePressPositive}
/>
<CardItem
icon={'warning'}
topics={[{ id: 2, text: report.melhorias_resumo }]}
typeCard="negative"
handlePress={handlePressNegative}
/>
<CardItem
icon={'bulb'}
topics={[{ id: 3, text: report.recomendacoes_resumo }]}
typeCard="recomendation"
handlePress={handlePressRecomendation}
/>
</View>
)
}
2 changes: 1 addition & 1 deletion constants/api.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const API_URL =
process.env.EXPO_PUBLIC_API_URL ?? 'http://localhost:8000';
process.env.EXPO_PUBLIC_API_URL ?? 'https://mandaca-backend-production.onrender.com';
17 changes: 17 additions & 0 deletions services/reports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { API_URL } from '@/constants/api'
import { AIReportDetail, AIReportSummary } from '@/types/Report'

export const generateReport = async (empresaId: string): Promise<AIReportDetail> => {
const res = await fetch(`${API_URL}/reports/generate/${empresaId}`, { method: 'POST' })
return res.json()
}

export const getReportsByEnterprise = async (empresaId: string): Promise<AIReportSummary[]> => {
const res = await fetch(`${API_URL}/reports/by-enterprise/${empresaId}`)
return res.json()
}

export const getReport = async (reportId: string): Promise<AIReportDetail> => {
const res = await fetch(`${API_URL}/reports/${reportId}`)
return res.json()
}
15 changes: 15 additions & 0 deletions types/Report.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export type AIReportSummary = {
id_relatorio: string
empresa_id: string
contexto_id: string
pontos_positivos_resumo: string
melhorias_resumo: string
recomendacoes_resumo: string
criado_em: string
}

export type AIReportDetail = AIReportSummary & {
pontos_positivos_detalhado: string
melhorias_detalhado: string
recomendacoes_detalhado: string
}
Loading