diff --git a/app/[store]/error.tsx b/app/[store]/error.tsx new file mode 100644 index 00000000..bb9dfa32 --- /dev/null +++ b/app/[store]/error.tsx @@ -0,0 +1,163 @@ +'use client' + +interface ErrorProps { + error: Error & { digest?: string } + reset: () => void +} + +export default function StoreError({ error, reset }: ErrorProps) { + return ( + + + + + Error - Fasttify + + + +
+ + + FASTTIFY + +
+ +
+
+

Esta tienda no existe.

+ + + +
+
+

Crear tu tienda online

+

Comienza con una prueba gratuita de 3 días, luego continúa desde $29/mes los próximos 3 meses.

+ Regístrate ahora +
+ +
+

Vender en persona

+

Obtén las características que necesitas para administrar tu negocio ya sea que estés empezando o creciendo.

+ Prueba gratuita +
+ +
+

Explorar Fasttify

+

Con 100+ actualizaciones de productos, puedes ser más productivo, creativo y poderoso en el comercio.

+ Explorar características +
+
+ + {% if error.show_details %} +
+ Detalles técnicos:
+ Tipo: {{ error.type }}
+ Mensaje: {{ error.message }}
+ Código: {{ error.status_code }} +
+ {% endif %} +
+
+ + + + + ` + } + + /** + * Template para plantillas no encontradas + */ + private getTemplateNotFoundTemplate(): string { + return ` + + + + + + {{ page.title }} + + + +
+ + + FASTTIFY + +
+ +
+
+

Esta tienda está siendo configurada.

+

Estará disponible pronto. Mientras tanto, puedes explorar otras opciones.

+ + + +
+
+

¿Eres el propietario?

+

Completa la configuración de tu tienda para que esté disponible para tus clientes.

+ Ir al panel de administración +
+ +
+

Crear tu tienda online

+

Comienza con una prueba gratuita de 3 días, luego continúa desde $29/mes los próximos 3 meses.

+ Regístrate ahora +
+ +
+

Obtener ayuda

+

Nuestro equipo de soporte está disponible 24/7 para ayudarte con cualquier pregunta o problema.

+ Contactar soporte +
+
+ + {% if error.show_details %} +
+ Detalles técnicos:
+ Tipo: {{ error.type }}
+ Mensaje: {{ error.message }}
+ Código: {{ error.status_code }} +
+ {% endif %} +
+
+ + + + + ` + } + + /** + * Template para errores de renderizado + */ + private getRenderErrorTemplate(): string { + return ` + + + + + + {{ page.title }} + + + +
+ + + FASTTIFY + +
+ +
+
+

Algo salió mal temporalmente.

+

Estamos trabajando para solucionarlo. Puedes intentar de nuevo en unos momentos.

+ + + +
+
+

Intentar de nuevo

+

A veces estos errores se resuelven automáticamente. Recarga la página para intentar de nuevo.

+ Recargar ahora +
+ +
+

Contactar soporte

+

Si el problema persiste, nuestro equipo de soporte puede ayudarte a resolverlo rápidamente.

+ Obtener ayuda +
+ +
+

Estado del servicio

+

Verifica si hay mantenimientos programados o problemas conocidos en nuestro servicio.

+ Ver estado +
+
+ + {% if error.show_details %} +
+ Detalles técnicos:
+ Tipo: {{ error.type }}
+ Mensaje: {{ error.message }}
+ Código: {{ error.status_code }} +
+ {% endif %} +
+
+ + + + + ` + } + + /** + * Template para errores de datos + */ + private getDataErrorTemplate(): string { + return ` + + + + + + {{ page.title }} + + + +
+ + + FASTTIFY + +
+ +
+
+

Error de conexión.

+

No pudimos cargar los datos necesarios. Revisa tu conexión e inténtalo de nuevo.

+ + + +
+
+

Verificar conexión

+

Asegúrate de que tu dispositivo esté conectado a internet y que la conexión sea estable.

+ Reintentar ahora +
+ +
+

Estado del servicio

+

Verifica si hay mantenimientos programados o interrupciones conocidas en nuestros servicios.

+ Ver estado del servicio +
+ +
+

Contactar soporte

+

Si el problema persiste, nuestro equipo técnico puede ayudarte a resolverlo.

+ Obtener ayuda +
+
+ + {% if error.show_details %} +
+ Detalles técnicos:
+ Tipo: {{ error.type }}
+ Mensaje: {{ error.message }}
+ Código: {{ error.status_code }} +
+ {% endif %} +
+
+ + + + + ` + } + + /** + * Obtiene mensajes amigables para cada tipo de error + */ + private getFriendlyMessage(errorType: TemplateError['type']): string { + const messages = { + STORE_NOT_FOUND: 'Lo sentimos, la tienda que buscas no existe o ha sido desactivada.', + TEMPLATE_NOT_FOUND: 'Esta tienda está siendo configurada y estará disponible pronto.', + RENDER_ERROR: + 'Experimentamos un problema técnico temporal. Nuestro equipo ya está trabajando en solucionarlo.', + DATA_ERROR: + 'Hubo un problema al cargar los datos de la tienda. Inténtalo de nuevo en unos momentos.', + } + + return messages[errorType] || 'Se produjo un error inesperado.' + } + + /** + * Obtiene sugerencias para cada tipo de error + */ + private getErrorSuggestions(errorType: TemplateError['type']): string[] { + const suggestions = { + STORE_NOT_FOUND: [ + 'Verificar que la URL de la tienda esté escrita correctamente', + 'Contactar al propietario de la tienda si crees que debería existir', + 'Explorar otras tiendas en Fasttify', + ], + TEMPLATE_NOT_FOUND: [ + 'La tienda está en proceso de configuración', + 'Vuelve a intentar en unos minutos', + 'Contacta al propietario si el problema persiste', + ], + RENDER_ERROR: [ + 'Recargar la página', + 'Intentar navegar a otra sección', + 'Contactar soporte si el problema persiste', + ], + DATA_ERROR: [ + 'Verificar tu conexión a internet', + 'Intentar de nuevo en unos momentos', + 'Contactar soporte si el error continúa', + ], + } + + return suggestions[errorType] || ['Intentar de nuevo más tarde'] + } + + /** + * Obtiene títulos para cada tipo de error + */ + private getErrorTitle(errorType: TemplateError['type']): string { + const titles = { + STORE_NOT_FOUND: 'Tienda No Encontrada - Fasttify', + TEMPLATE_NOT_FOUND: 'Tienda en Construcción - Fasttify', + RENDER_ERROR: 'Error Temporal - Fasttify', + DATA_ERROR: 'Error de Conexión - Fasttify', + } + + return titles[errorType] || 'Error - Fasttify' + } + + /** + * Obtiene descripciones para cada tipo de error + */ + private getErrorDescription(errorType: TemplateError['type']): string { + const descriptions = { + STORE_NOT_FOUND: 'La tienda que buscas no existe o no está disponible en este momento.', + TEMPLATE_NOT_FOUND: 'Esta tienda está siendo configurada y estará disponible pronto.', + RENDER_ERROR: + 'Se produjo un error técnico temporal. Nuestro equipo está trabajando para solucionarlo.', + DATA_ERROR: 'Hubo un problema al cargar los datos. Inténtalo de nuevo en unos momentos.', + } + + return descriptions[errorType] || 'Se produjo un error inesperado.' + } + + /** + * Extrae el nombre de la tienda del dominio + */ + private extractStoreName(domain: string): string { + const parts = domain.split('.') + return parts[0] || domain + } + + /** + * Página de error de respaldo si falla el renderizado de error + */ + private getFallbackErrorPage(error: TemplateError, options: ErrorRenderOptions): RenderResult { + const html = ` + + + + + + Error - Fasttify + + + +
+

🚧 Error Temporal

+

Se produjo un error inesperado. Por favor, inténtalo de nuevo más tarde.

+ Volver al inicio +
+ + + ` + + return { + html, + metadata: { + title: 'Error - Fasttify', + description: 'Se produjo un error inesperado', + openGraph: { + title: 'Error - Fasttify', + description: 'Se produjo un error inesperado', + url: options.domain, + type: 'website', + site_name: 'Fasttify', + }, + schema: { + '@context': 'https://schema.org', + '@type': 'WebPage', + name: 'Error', + }, + }, + cacheKey: `fallback_error_${Date.now()}`, + cacheTTL: 0, + } + } +} + +// Exportar instancia singleton +export const errorRenderer = new ErrorRenderer() diff --git a/package-lock.json b/package-lock.json index e5538f02..05ba7afd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,8 @@ "@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-toast": "^1.2.6", "@radix-ui/react-tooltip": "^1.1.8", + "@shopify/polaris": "^13.9.5", + "@shopify/react-form": "^2.7.3", "@tailwindcss/postcss": "^4.1.8", "@tanstack/react-query": "^5.67.2", "aws-amplify": "^6.13.2", @@ -30469,6 +30471,94 @@ "dev": true, "license": "MIT" }, + "node_modules/@shopify/polaris": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@shopify/polaris/-/polaris-13.9.5.tgz", + "integrity": "sha512-UN+rT2q1r/uF0Xia8MaCl2nDxatuzbjunS5WYcv4qw8VBvThTxDVURgpwOuvutSrvu138pwScOAah933vqlYkg==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@shopify/polaris-icons": "^9.3.1", + "@shopify/polaris-tokens": "^9.4.2", + "@types/react": "*", + "@types/react-dom": "*", + "@types/react-transition-group": "^4.4.2", + "react-fast-compare": "^3.2.0", + "react-transition-group": "^4.4.2" + }, + "engines": { + "node": ">=20.10.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@shopify/polaris-icons": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@shopify/polaris-icons/-/polaris-icons-9.3.1.tgz", + "integrity": "sha512-16BIFAT93LJ8X4YRXz5cR9ZPHeErMg3DYS0gyTPNPkd0E5IBPoTxPINjn2b4Mr9Sc1x4RfI4AqPcV8ut0D1J5w==", + "license": "SEE LICENSE IN LICENSE.md", + "engines": { + "node": ">=20.10.0" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@shopify/polaris-tokens": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@shopify/polaris-tokens/-/polaris-tokens-9.4.2.tgz", + "integrity": "sha512-WNoDWLYFj38Cj0FolbNsLaY54JbjuYoO0qsLCj6yBb3Bkg4BEdAjOHji9AktL9IZGPsNhTcMp2/8CfzKtSHg2A==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "deepmerge": "^4.3.1" + }, + "engines": { + "node": ">=20.10.0" + } + }, + "node_modules/@shopify/predicates": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@shopify/predicates/-/predicates-3.1.0.tgz", + "integrity": "sha512-0bEEJKLncd0EKs+O39tf6c6m0mN/HXXqtHBBaD7L4gD3nUSeNB8dE0sKjVWhENkwXHNURht6yoFigqKQg0paMA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@shopify/react-form": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@shopify/react-form/-/react-form-2.7.3.tgz", + "integrity": "sha512-Z2C2o2pOh8Lt71FchP3CdDKUMLcWOA1K+qioMDEJJVlwxfZyj4OZSTPhY0iaVZj1m5oN81skLl196PYwX92hMg==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "dependencies": { + "@shopify/predicates": "^3.1.0", + "@shopify/react-hooks": "^4.1.2", + "fast-deep-equal": "^3.1.3", + "get-value": "^3.0.1" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "react": ">=18.0.0 <19.0.0" + } + }, + "node_modules/@shopify/react-hooks": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@shopify/react-hooks/-/react-hooks-4.1.2.tgz", + "integrity": "sha512-F5WWZ7t2qd0i+ALCFbdQ6v5TG+6jUZ/N/dTWLd7w56uteO2H6a91KfwUWClffPVfch0qqlHG84F8t4pOMj8/Gg==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "react": ">=18.0.0 <19.0.0" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -32181,14 +32271,12 @@ "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", - "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.23", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", - "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -32199,12 +32287,20 @@ "version": "18.3.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", - "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^18.0.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -34864,7 +34960,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -35677,7 +35772,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-equals": { @@ -36253,6 +36347,18 @@ "node": ">= 14" } }, + "node_modules/get-value": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-3.0.1.tgz", + "integrity": "sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=6.0" + } + }, "node_modules/getopts": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", @@ -37571,6 +37677,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -42093,6 +42208,12 @@ "react": "^18.3.1" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, "node_modules/react-hook-form": { "version": "7.57.0", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.57.0.tgz", diff --git a/package.json b/package.json index 7d2848f6..03ab0b14 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ ] }, "dependencies": { - "@aws-amplify/backend-cli": "^1.7.2", "@aws-amplify/adapter-nextjs": "^1.4.1", + "@aws-amplify/backend-cli": "^1.7.2", "@aws-amplify/data-schema-types": "^1.2.0", "@aws-sdk/client-bedrock-runtime": "^3.758.0", "@aws-sdk/client-ses": "^3.741.0", @@ -47,6 +47,8 @@ "@radix-ui/react-tabs": "^1.1.3", "@radix-ui/react-toast": "^1.2.6", "@radix-ui/react-tooltip": "^1.1.8", + "@shopify/polaris": "^13.9.5", + "@shopify/react-form": "^2.7.3", "@tailwindcss/postcss": "^4.1.8", "@tanstack/react-query": "^5.67.2", "aws-amplify": "^6.13.2",