diff --git a/package-lock.json b/package-lock.json index 9dde4b6..ced27b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "1.0.0", "dependencies": { "@react-native-async-storage/async-storage": "2.2.0", - "@react-navigation/bottom-tabs": "^6.5.11", - "@react-navigation/native": "^6.1.9", - "@react-navigation/native-stack": "^6.9.17", + "@react-navigation/bottom-tabs": "^7.15.11", + "@react-navigation/native": "^7.2.2", + "@react-navigation/native-stack": "^7.14.12", "@supabase/supabase-js": "^2.99.1", "expo": "~54.0.33", "expo-constants": "~18.0.13", @@ -71,7 +71,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -2973,44 +2972,46 @@ "license": "MIT" }, "node_modules/@react-navigation/bottom-tabs": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.6.1.tgz", - "integrity": "sha512-9oD4cypEBjPuaMiu9tevWGiQ4w/d6l3HNhcJ1IjXZ24xvYDSs0mqjUcdt8SWUolCvRrYc/DmNBLlT83bk0bHTw==", + "version": "7.15.11", + "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.15.11.tgz", + "integrity": "sha512-+WtNbd6fJgbViDNjmBUUP7eTgGH+zBtrl3jHuNnfUfXTs9YGuI5q3SiHIc9a5gY3voBOxbOXEiHJyW4xea7nAw==", "license": "MIT", "dependencies": { - "@react-navigation/elements": "^1.3.31", + "@react-navigation/elements": "^2.9.15", "color": "^4.2.3", - "warn-once": "^0.1.0" + "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { - "@react-navigation/native": "^6.0.0", - "react": "*", + "@react-navigation/native": "^7.2.2", + "react": ">= 18.2.0", "react-native": "*", - "react-native-safe-area-context": ">= 3.0.0", - "react-native-screens": ">= 3.0.0" + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" } }, "node_modules/@react-navigation/core": { - "version": "6.4.17", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.17.tgz", - "integrity": "sha512-Nd76EpomzChWAosGqWOYE3ItayhDzIEzzZsT7PfGcRFDgW5miHV2t4MZcq9YIK4tzxZjVVpYbIynOOQQd1e0Cg==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.17.2.tgz", + "integrity": "sha512-Rt2OZwcgOmjv401uLGAKaRM6xo0fiBce/A7LfRHI1oe5FV+KooWcgAoZ2XOtgKj6UzVMuQWt3b2e6rxo/mDJRA==", "license": "MIT", "dependencies": { - "@react-navigation/routers": "^6.1.9", + "@react-navigation/routers": "^7.5.3", "escape-string-regexp": "^4.0.0", - "nanoid": "^3.1.23", + "fast-deep-equal": "^3.1.3", + "nanoid": "^3.3.11", "query-string": "^7.1.3", - "react-is": "^16.13.0", - "use-latest-callback": "^0.2.1" + "react-is": "^19.1.0", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" }, "peerDependencies": { - "react": "*" + "react": ">= 18.2.0" } }, "node_modules/@react-navigation/core/node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -3026,49 +3027,62 @@ } }, "node_modules/@react-navigation/elements": { - "version": "1.3.31", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.31.tgz", - "integrity": "sha512-bUzP4Awlljx5RKEExw8WYtif8EuQni2glDaieYROKTnaxsu9kEIA515sXQgUDZU4Ob12VoL7+z70uO3qrlfXcQ==", + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.15.tgz", + "integrity": "sha512-cyz/pPiyyC6gaTVLsGFc1g0MYgrmuCFqklAWGXMWPscr5YU3ui94vPI4vnZwcsEy0T758TQWLzmS5XudZeRKcA==", "license": "MIT", + "dependencies": { + "color": "^4.2.3", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" + }, "peerDependencies": { - "@react-navigation/native": "^6.0.0", - "react": "*", + "@react-native-masked-view/masked-view": ">= 0.2.0", + "@react-navigation/native": "^7.2.2", + "react": ">= 18.2.0", "react-native": "*", - "react-native-safe-area-context": ">= 3.0.0" + "react-native-safe-area-context": ">= 4.0.0" + }, + "peerDependenciesMeta": { + "@react-native-masked-view/masked-view": { + "optional": true + } } }, "node_modules/@react-navigation/native": { - "version": "6.1.18", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.18.tgz", - "integrity": "sha512-mIT9MiL/vMm4eirLcmw2h6h/Nm5FICtnYSdohq4vTLA2FF/6PNhByM7s8ffqoVfE5L0uAa6Xda1B7oddolUiGg==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.2.2.tgz", + "integrity": "sha512-kem1Ko2BcbAjmbQIv66dNmr6EtfDut3QU0qjsVhMnLLhktwyXb6FzZYp8gTrUb6AvkAbaJoi+BF5Pl55pAUa5w==", "license": "MIT", - "peer": true, "dependencies": { - "@react-navigation/core": "^6.4.17", + "@react-navigation/core": "^7.17.2", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", - "nanoid": "^3.1.23" + "nanoid": "^3.3.11", + "use-latest-callback": "^0.2.4" }, "peerDependencies": { - "react": "*", + "react": ">= 18.2.0", "react-native": "*" } }, "node_modules/@react-navigation/native-stack": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.11.0.tgz", - "integrity": "sha512-U5EcUB9Q2NQspCFwYGGNJm0h6wBCOv7T30QjndmvlawLkNt7S7KWbpWyxS9XBHSIKF57RgWjfxuJNTgTstpXxw==", + "version": "7.14.12", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.14.12.tgz", + "integrity": "sha512-dUfpkrVeVKKV8iqXsmoUp3Rv0iH3YaB3eZwScru/FlcqAp/r3/qA6zEXkGX9hZK+/ziWAPFrf1frBSNbgOYSFQ==", "license": "MIT", "dependencies": { - "@react-navigation/elements": "^1.3.31", - "warn-once": "^0.1.0" + "@react-navigation/elements": "^2.9.15", + "color": "^4.2.3", + "sf-symbols-typescript": "^2.1.0", + "warn-once": "^0.1.1" }, "peerDependencies": { - "@react-navigation/native": "^6.0.0", - "react": "*", + "@react-navigation/native": "^7.2.2", + "react": ">= 18.2.0", "react-native": "*", - "react-native-safe-area-context": ">= 3.0.0", - "react-native-screens": ">= 3.0.0" + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" } }, "node_modules/@react-navigation/native/node_modules/nanoid": { @@ -3090,18 +3104,18 @@ } }, "node_modules/@react-navigation/routers": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz", - "integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.3.tgz", + "integrity": "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg==", "license": "MIT", "dependencies": { - "nanoid": "^3.1.23" + "nanoid": "^3.3.11" } }, "node_modules/@react-navigation/routers/node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -3334,9 +3348,8 @@ "version": "19.1.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz", "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==", - "devOptional": true, + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -4034,7 +4047,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4497,7 +4509,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/debug": { @@ -4806,7 +4818,6 @@ "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.33.tgz", "integrity": "sha512-3yOEfAKqo+gqHcV8vKcnq0uA5zxlohnhA3fu4G43likN8ct5ZZ3LjAh9wDdKteEkoad3tFPvwxmXW711S5OHUw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.23", @@ -4945,7 +4956,6 @@ "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz", "integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==", "license": "MIT", - "peer": true, "dependencies": { "fontfaceobserver": "^2.1.0" }, @@ -8040,7 +8050,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8060,7 +8069,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -8081,9 +8089,9 @@ } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", + "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", "license": "MIT" }, "node_modules/react-native": { @@ -8091,7 +8099,6 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz", "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==", "license": "MIT", - "peer": true, "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.81.5", @@ -8159,7 +8166,6 @@ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "*", "react-native": "*" @@ -8170,7 +8176,6 @@ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz", "integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==", "license": "MIT", - "peer": true, "dependencies": { "react-freeze": "^1.0.0", "react-native-is-edge-to-edge": "^1.2.1", @@ -8302,7 +8307,6 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8729,6 +8733,15 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/sf-symbols-typescript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz", + "integrity": "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -9262,7 +9275,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -9488,6 +9500,15 @@ "react": ">=16.8" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", diff --git a/package.json b/package.json index aa3a2f8..1b4bc7d 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ }, "dependencies": { "@react-native-async-storage/async-storage": "2.2.0", - "@react-navigation/bottom-tabs": "^6.5.11", - "@react-navigation/native": "^6.1.9", - "@react-navigation/native-stack": "^6.9.17", + "@react-navigation/bottom-tabs": "^7.15.11", + "@react-navigation/native": "^7.2.2", + "@react-navigation/native-stack": "^7.14.12", "@supabase/supabase-js": "^2.99.1", "expo": "~54.0.33", "expo-constants": "~18.0.13", diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 81d9093..326732d 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -303,45 +303,64 @@ export default function Dashboard() { )} {activeTab === 'appointments' && ( - + {activeAppointments.length > 0 ? ( activeAppointments.map((a) => { const svc = shop.services.find((s) => s.id === a.serviceId); const barber = shop.barbers.find((b) => b.id === a.barberId); + + const dateParts = a.date.split(' '); + const dateObj = new Date(dateParts[0]); + const time = dateParts[1] || ''; + const day = dateObj.getDate(); + const monthNames = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; + const month = monthNames[dateObj.getMonth()] || ''; + return ( - - - - {svc?.name ?? 'Serviço'} - {barber?.name} · {a.date} - - - {a.status} - - - - Alterar status: - - {['pendente', 'confirmado', 'concluido', 'cancelado'].map((s) => ( - - ))} + + + {day} + {month} + + {time} - + + + + {svc?.name ?? 'Serviço'} + {barber?.name} · {currency(a.total)} + + + {a.status} + + + + + Alterar status: + + {['pendente', 'confirmado', 'concluido', 'cancelado'].map((s) => ( + + ))} + + + + ); }) ) : ( - - Nenhum agendamento ativo - + + 📅 + Nenhum agendamento ativo. + )} )} @@ -384,31 +403,48 @@ export default function Dashboard() { )} {activeTab === 'history' && ( - + Histórico de Agendamentos {historyAppointments.length > 0 ? ( historyAppointments.map((a) => { const svc = shop.services.find((s) => s.id === a.serviceId); const barber = shop.barbers.find((b) => b.id === a.barberId); + + const dateParts = a.date.split(' '); + const dateObj = new Date(dateParts[0]); + const time = dateParts[1] || ''; + const day = dateObj.getDate(); + const monthNames = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; + const month = monthNames[dateObj.getMonth()] || ''; + return ( - - - - {svc?.name ?? 'Serviço'} - {barber?.name ?? 'Barbeiro'} · {a.date} - {currency(a.total)} + + + {day} + {month} + + {time} - - {a.status === 'concluido' ? 'Concluído' : 'Cancelado'} - - + + + + {svc?.name ?? 'Serviço'} + {barber?.name ?? 'Barbeiro'} · {currency(a.total)} + + + {a.status === 'concluido' ? 'Concluído' : 'Cancelado'} + + + + ); }) ) : ( - + + 📅 Ainda não há registos concluídos ou cancelados. - + )} )} @@ -850,4 +886,81 @@ const styles = StyleSheet.create({ padding: 24, alignItems: 'center', }, + agendaContainer: { + gap: 12, + }, + agendaTicket: { + flexDirection: 'row', + backgroundColor: '#fff', + borderRadius: 24, + overflow: 'hidden', + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.05, + shadowRadius: 10, + elevation: 3, + marginBottom: 8, + }, + agendaDateBox: { + backgroundColor: '#0f172a', + paddingVertical: 16, + paddingHorizontal: 12, + alignItems: 'center', + justifyContent: 'center', + minWidth: 85, + }, + agendaDay: { + color: '#fff', + fontSize: 28, + fontWeight: '900', + lineHeight: 32, + }, + agendaMonth: { + color: '#818cf8', + fontSize: 14, + fontWeight: '800', + textTransform: 'uppercase', + marginBottom: 8, + }, + agendaTimeWrapper: { + backgroundColor: 'rgba(255,255,255,0.1)', + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 8, + }, + agendaTime: { + color: '#fff', + fontSize: 12, + fontWeight: '700', + }, + agendaContent: { + flex: 1, + padding: 16, + justifyContent: 'center', + }, + agendaHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + marginBottom: 4, + }, + agendaShopName: { + fontSize: 16, + fontWeight: '900', + color: '#0f172a', + marginRight: 8, + }, + emptyAgendaState: { + alignItems: 'center', + padding: 40, + backgroundColor: '#fff', + borderRadius: 28, + borderWidth: 1, + borderColor: '#e2e8f0', + borderStyle: 'dashed', + gap: 16, + }, + emptyAgendaIcon: { + fontSize: 48, + }, }); diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx index 6c84793..19ae346 100644 --- a/src/pages/Profile.tsx +++ b/src/pages/Profile.tsx @@ -232,44 +232,70 @@ export default function Profile() { )} {activeTab === 'agenda' && ( - - Minha Agenda + + Próximos Agendamentos {myAppointments.length ? myAppointments.map((appointment) => { const shop = shops.find((s) => s.id === appointment.shopId); const service = shop?.services.find((s) => s.id === appointment.serviceId); const canReview = appointment.status === 'concluido' && !reviewedAppointments.has(appointment.id); + + const dateParts = appointment.date.split(' '); + const dateObj = new Date(dateParts[0]); + const time = dateParts[1] || ''; + const day = dateObj.getDate(); + const monthNames = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; + const month = monthNames[dateObj.getMonth()] || ''; return ( - - - {shop?.name || 'Barbearia'} - {statusLabel[appointment.status]} + + + {day} + {month} + + {time} + - {appointment.date} - {!!service && {service.name} · {service.duration} min} - {currency(appointment.total)} - {canReview ? ( - - ) : appointment.status === 'concluido' ? ( - Avaliado - ) : null} - + + + {shop?.name || 'Barbearia'} + + {statusLabel[appointment.status]} + + + {!!service && {service.name}} + + {currency(appointment.total)} + {canReview ? ( + { + setReviewTarget({ + appointmentId: appointment.id, + shopId: appointment.shopId, + shopName: shop?.name || 'Barbearia', + }); + }} + > + Avaliar + + ) : appointment.status === 'concluido' ? ( + ✓ Avaliado + ) : null} + + + ); }) : ( - - Sem agendamentos futuros. - + + 📅 + Não tens marcações agendadas. + + )} )} @@ -521,6 +547,114 @@ const styles = StyleSheet.create({ fontSize: 12, fontWeight: '900', textTransform: 'uppercase', - marginTop: 10, + }, + agendaContainer: { + gap: 12, + }, + agendaTicket: { + flexDirection: 'row', + backgroundColor: '#fff', + borderRadius: 24, + overflow: 'hidden', + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.05, + shadowRadius: 10, + elevation: 3, + marginBottom: 8, + }, + agendaDateBox: { + backgroundColor: '#0f172a', + paddingVertical: 16, + paddingHorizontal: 12, + alignItems: 'center', + justifyContent: 'center', + minWidth: 85, + }, + agendaDay: { + color: '#fff', + fontSize: 28, + fontWeight: '900', + lineHeight: 32, + }, + agendaMonth: { + color: '#818cf8', + fontSize: 14, + fontWeight: '800', + textTransform: 'uppercase', + marginBottom: 8, + }, + agendaTimeWrapper: { + backgroundColor: 'rgba(255,255,255,0.1)', + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 8, + }, + agendaTime: { + color: '#fff', + fontSize: 12, + fontWeight: '700', + }, + agendaContent: { + flex: 1, + padding: 16, + justifyContent: 'center', + }, + agendaHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + marginBottom: 4, + }, + agendaShopName: { + fontSize: 16, + fontWeight: '900', + color: '#0f172a', + flex: 1, + marginRight: 8, + }, + agendaBadge: { + transform: [{ scale: 0.9 }], + }, + agendaService: { + fontSize: 14, + color: '#64748b', + fontWeight: '600', + marginBottom: 12, + }, + agendaFooter: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + agendaTotal: { + fontSize: 16, + fontWeight: '900', + color: '#6366f1', + }, + reviewMiniButton: { + backgroundColor: '#818cf8', + paddingHorizontal: 12, + paddingVertical: 6, + borderRadius: 12, + }, + reviewMiniButtonText: { + color: '#fff', + fontSize: 11, + fontWeight: '900', + textTransform: 'uppercase', + }, + emptyAgendaState: { + alignItems: 'center', + padding: 40, + backgroundColor: '#fff', + borderRadius: 28, + borderWidth: 1, + borderColor: '#e2e8f0', + borderStyle: 'dashed', + gap: 16, + }, + emptyAgendaIcon: { + fontSize: 48, }, });