Skip to content
Merged

Cli #370

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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [Fasttify](https://fasttify.com) · [![GitHub license](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/Fasttify/fasttify/blob/main/LICENSE) [![Next.js](https://img.shields.io/badge/Next.js-15.5.4-black?logo=next.js&logoColor=white)](https://nextjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.8.3-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![AWS Amplify](https://img.shields.io/badge/AWS%20Amplify-Gen2-orange?logo=aws&logoColor=white)](https://aws.amazon.com/amplify/) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Fasttify/fasttify/blob/main/CONTRIBUTING.md)
# [Fasttify](https://fasttify.com) · [![GitHub license](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/Fasttify/fasttify/blob/main/LICENSE) [![Next.js](https://img.shields.io/badge/Next.js-16.0.0-black?logo=next.js&logoColor=white)](https://nextjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.8.3-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![AWS Amplify](https://img.shields.io/badge/AWS%20Amplify-Gen2-orange?logo=aws&logoColor=white)](https://aws.amazon.com/amplify/) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Fasttify/fasttify/blob/main/CONTRIBUTING.md)

Fasttify es una plataforma SaaS completa para crear y gestionar tiendas online con motor de plantillas Liquid 100% compatible con Shopify.

Expand All @@ -19,7 +19,7 @@ Fasttify está diseñado para adopción gradual y **puedes usar tanto o tan poco

### Prerrequisitos

- Node.js 18+ con npm
- Node.js +20.18.3 con pnpm 10.18.0
- AWS CLI configurado
- Cuenta AWS con permisos para Amplify
- Git
Expand Down
8 changes: 1 addition & 7 deletions app/(setup)/first-steps/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,7 @@ export default function FirstStepsPage() {
return (
<div className="relative min-h-screen w-full overflow-hidden">
<div className="absolute top-4 left-4 z-10">
<Image
src="https://cdn.fasttify.com/assets/b/fasttify-white.webp"
priority={true}
alt="Fasttify Logo"
width={50}
height={50}
/>
<Image src="https://cdn.fasttify.com/assets/b/fasttify-white.webp" alt="Fasttify Logo" width={50} height={50} />
</div>
<div className="absolute inset-0 z-0 sm:block hidden">
<AnimatedBackground
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const ImageSlider = () => {
<SwiperSlide key={index}>
<div className="h-screen">
<Image
src={slide.image || '/placeholder.svg'}
src={slide.image}
alt={`Slide ${index + 1}`}
fill
className="object-cover"
Expand Down
10 changes: 2 additions & 8 deletions app/(www)/landing/components/FashionSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const slides: Slide[] = [
];

export function FashionSlider() {
const swiperRef = useRef<SwiperType>();
const swiperRef = useRef<SwiperType>(undefined);
const [activeIndex, setActiveIndex] = useState(0);

return (
Expand Down Expand Up @@ -138,13 +138,7 @@ export function FashionSlider() {
</div>

<div className="fashion-slider-image absolute w-full h-full overflow-hidden">
<Image
src={slide.image || '/placeholder.svg'}
alt={slide.title}
fill
className="object-cover"
priority={index === 0}
/>
<Image src={slide.image} alt={slide.title} fill className="object-cover" />
</div>
</SwiperSlide>
))}
Expand Down
2 changes: 1 addition & 1 deletion app/(www)/landing/components/FirstView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const slides = [
];

export function FirstView() {
const swiperRef = useRef<SwiperType>();
const swiperRef = useRef<SwiperType>(undefined);
const [activeIndex, setActiveIndex] = useState(0);
const router = useRouter();

Expand Down
2 changes: 1 addition & 1 deletion app/(www)/landing/components/Platform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const slides: CompatibilitySlide[] = [
];

export function Platform() {
const swiperRef = useRef<SwiperType>();
const swiperRef = useRef<SwiperType>(undefined);
const [activeIndex, setActiveIndex] = useState(0);
const [navigationLocked, setNavigationLocked] = useState(false);
const [isAutoplay, setIsAutoplay] = useState(true);
Expand Down
3 changes: 2 additions & 1 deletion app/[store]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { domainResolver } from '@fasttify/liquid-forge';
import { Metadata } from 'next';
import { headers } from 'next/headers';
import { notFound } from 'next/navigation';
import { Suspense } from 'react';

export const dynamic = 'force-dynamic';

Expand Down Expand Up @@ -79,7 +80,7 @@ export default async function StorePage({ params, searchParams }: StorePageProps
return (
<>
<div dangerouslySetInnerHTML={{ __html: result.html }} />
<DevAutoReloadScript />
{process.env.NODE_ENV === 'development' && <DevAutoReloadScript />}
</>
);
} catch (error: any) {
Expand Down
2 changes: 1 addition & 1 deletion app/api/v1/auth/_lib/controllers/send-token-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export async function postSendToken(request: NextRequest) {
token,
email,
storeName: storeId ? 'Tu Tienda' : 'Fasttify',
}) as React.ReactElement
}) as React.ReactElement<any>
);

// Enviar email
Expand Down
4 changes: 2 additions & 2 deletions app/store/components/ai-chat/types/chat-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export interface EmptyStateProps {
export interface MessageListProps {
messages: Message[];
loading: boolean;
messagesEndRef: React.RefObject<HTMLDivElement>;
scrollRef?: React.RefObject<HTMLDivElement>;
messagesEndRef: React.RefObject<HTMLDivElement | null>;
scrollRef?: React.RefObject<HTMLDivElement | null>;
hasMoreMessages?: boolean;
loadingMoreMessages?: boolean;
onLoadMore?: () => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function DateRangePicker({
year={year}
shouldShowMultiMonth={shouldShowMultiMonth}
mdDown={mdDown}
popoverContentRef={popoverContentRef}
popoverContentRef={popoverContentRef as React.RefObject<HTMLDivElement>}
onStartInputChange={handleStartInputValueChange}
onEndInputChange={handleEndInputValueChange}
onInputBlur={handleInputBlur}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface UseNotificationPopoverResult {

hasNextPage: boolean;
loadMore: () => Promise<void>;
scrollContainerRef: React.RefObject<HTMLDivElement>;
scrollContainerRef: React.RefObject<HTMLDivElement | null>;
handleScroll: () => void;

refreshNotifications: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Image from 'next/image';
import { LegacyStack, Text, Button, Badge } from '@shopify/polaris';
import { PaymentGatewayType } from '@/app/(setup)/first-steps/hooks/useUserStoreData';
import { WompiPaymentIcons, MercadoPagoIcons } from '@/app/store/components/payments/components/PaymentMethodIcons';
import type { JSX } from 'react';

interface PaymentGatewayCardProps {
gateway: PaymentGatewayType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Card, SkeletonBodyText, SkeletonThumbnail, SkeletonDisplayText } from '@shopify/polaris';
import type { JSX } from 'react';

interface ProfilePageSkeletonProps {
isGoogleUser?: boolean;
Expand Down
13 changes: 7 additions & 6 deletions app/store/components/sidebar/components/PolarisLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@

import { NavigationPolaris } from '@/app/store/components/sidebar/components/NavigationPolaris';
import { TopBarPolaris } from '@/app/store/components/sidebar/components/TopBarPolaris';
import { PageTransition } from '@/components/ui/page-transition';
import { AppProvider, Frame } from '@shopify/polaris';
import { routes } from '@/utils/client/routes';
import translations from '@shopify/polaris/locales/es.json';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState, useCallback, useMemo, memo } from 'react';
import { ChatLayout } from '@/app/store/components/ai-chat/components/ChatLayout';
import { useChatContext } from '@/app/store/components/ai-chat/context/ChatContext';
import { ConversationProvider } from '@/app/store/components/ai-chat/context/ConversationContext';
import { ConversationHistoryProvider } from '@/app/store/components/ai-chat/context/ConversationHistoryContext';
import { RefinedAIAssistantSheet } from '@/app/store/components/ai-chat/components/RefinedAiAssistant';
import { ViewTransition } from 'react';
import Link from 'next/link';
import translations from '@shopify/polaris/locales/es.json';

interface PolarisLayoutProps {
children: React.ReactNode;
storeId: string;
prefersReducedMotion?: boolean;
}

const PolarisLinkComponent = memo(({ children, url = '', external = false, ...rest }: any) => {
Expand Down Expand Up @@ -66,7 +65,7 @@ const ChatComponent = memo(() => {

ChatComponent.displayName = 'ChatComponent';

export const PolarisLayout = memo(({ children, storeId, prefersReducedMotion = false }: PolarisLayoutProps) => {
export const PolarisLayout = memo(({ children, storeId }: PolarisLayoutProps) => {
const [mobileNavigationActive, setMobileNavigationActive] = useState(false);
const { isOpen: isChatOpen } = useChatContext();

Expand Down Expand Up @@ -109,7 +108,9 @@ export const PolarisLayout = memo(({ children, storeId, prefersReducedMotion = f
logo={logo}>
<main className="flex flex-1 flex-col gap-4 p-4 pt-0 bg-[#f3f4f6]">
<ChatLayout isChatOpen={isChatOpen}>
<PageTransition enabled={!prefersReducedMotion}>{children}</PageTransition>
<ViewTransition enter="fade-in" exit="fade-out">
{children}
</ViewTransition>
</ChatLayout>
<ChatComponent />
</main>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,7 @@ export function InactiveThemesList({ themes, onAction }: InactiveThemesListProps
icon: StatusActiveIcon,
onAction: () => handleAction('activate', themeId),
},
{
content: 'Vista previa',
icon: ViewIcon,
onAction: () => handleAction('preview', themeId),
},
{
content: 'Renombrar',
icon: EditIcon,
onAction: () => handleAction('rename', themeId),
},

{
content: 'Editar código',
icon: EditIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function useThemeUpload({ storeId, onUpload, onConfirm }: UseThemeUploadP
}
}, [selectedFile, onUpload]);

const handleConfirmRef = useRef<() => void>();
const handleConfirmRef = useRef<() => void>(undefined);

const handleConfirm = useCallback(async () => {
if (!uploadResult || !selectedFile) return;
Expand Down
5 changes: 4 additions & 1 deletion app/store/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@/app/global.css';
import { StoreLayoutClient } from '@/app/store/layout/StoreLayoutClient';
import { inter } from '@/lib/fonts/fonts';
import { Suspense } from 'react';

export const metadata = {
title: 'Mi tienda',
Expand All @@ -11,7 +12,9 @@ export default function StoreLayout({ children }: { children: React.ReactNode })
return (
<html lang="es">
<body className={inter.className}>
<StoreLayoutClient>{children}</StoreLayoutClient>
<Suspense>
<StoreLayoutClient>{children}</StoreLayoutClient>
</Suspense>
</body>
</html>
);
Expand Down
8 changes: 2 additions & 6 deletions app/store/layout/StoreLayoutClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import '@shopify/polaris/build/esm/styles.css';
import esTranslations from '@shopify/polaris/locales/es.json';
import { Amplify } from 'aws-amplify';
import { useParams, usePathname } from 'next/navigation';
import { useState } from 'react';
import { ChatProvider } from '@/app/store/components/ai-chat/context/ChatContext';
import { ConversationProvider } from '@/app/store/components/ai-chat/context/ConversationContext';

Expand All @@ -34,7 +33,6 @@ export const StoreLayoutClient = ({ children }: { children: React.ReactNode }) =
useAuthInitializer();
useStore(storeId);

const [prefersReducedMotion, _setPrefersReducedMotion] = useState(false);
const hideSidebar =
pathname.includes('/editor') || pathname.includes('/profile') || pathname.includes('/suscribe/select-plan');
const isCheckoutPage = pathname.includes('/access_account/checkout');
Expand All @@ -55,7 +53,7 @@ export const StoreLayoutClient = ({ children }: { children: React.ReactNode }) =
<div className="relative">
{/* Layout completo con blur - Sidebar, TopBar y contenido */}
<div className="pointer-events-none" style={{ filter: 'blur(5px)' }}>
<PolarisLayout storeId={storeId} prefersReducedMotion={prefersReducedMotion}>
<PolarisLayout storeId={storeId}>
<div className="rounded-lg shadow p-6">
<h1 className="text-2xl font-bold text-gray-900 mb-4">Panel de Administración</h1>
<p className="text-gray-600 mb-4">
Expand All @@ -68,9 +66,7 @@ export const StoreLayoutClient = ({ children }: { children: React.ReactNode }) =
{children}
</div>
) : (
<PolarisLayout storeId={storeId} prefersReducedMotion={prefersReducedMotion}>
{children}
</PolarisLayout>
<PolarisLayout storeId={storeId}>{children}</PolarisLayout>
)}
</ConversationProvider>
</ChatProvider>
Expand Down
2 changes: 2 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const config: Config = {
'^@/liquid-forge$': '<rootDir>/packages/liquid-forge',
'^@/tenant-domains/(.*)$': '<rootDir>/packages/tenant-domains/$1',
'^@/tenant-domains$': '<rootDir>/packages/tenant-domains',
'^@/packages/theme-editor/(.*)$': '<rootDir>/packages/theme-editor/src/$1',
'^@/packages/theme-editor$': '<rootDir>/packages/theme-editor/src',
'^@/(.*)$': '<rootDir>/$1',
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
Expand Down
3 changes: 0 additions & 3 deletions lib/actions/secure-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { isExternalUrl } from '@/lib/utils/external-domains';
async function _getSecureImageUrl(imageUrl: string): Promise<string> {
if (!imageUrl) return imageUrl;

// En desarrollo, devolver URL directa
if (process.env.NODE_ENV === 'development') {
return imageUrl;
}
Expand Down Expand Up @@ -70,7 +69,6 @@ async function _getSecureImageUrl(imageUrl: string): Promise<string> {
return generateSignedUrl(s3Path, 30 * 24 * 60); // 30 días
}

// Función con cache nativo de Next.js - crear una función por URL única
const createCachedSecureImageUrl = (imageUrl: string) => {
return unstable_cache(
() => _getSecureImageUrl(imageUrl),
Expand All @@ -95,7 +93,6 @@ export const getSecureImageUrl = async (imageUrl: string): Promise<string> => {
if (typeof cachedFunction === 'function') {
return await cachedFunction();
} else {
// Fallback: return original imageUrl if cache entry is not a function
return imageUrl;
}
};
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
import "./.next/dev/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
9 changes: 6 additions & 3 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { NextConfig } from 'next';

/** @type {import('next').NextConfig} */
const nextConfig: NextConfig = {
// TypeScript optimizations - disable type checking in build
reactCompiler: true,
typescript: {
ignoreBuildErrors: true, // Disable type checking during build
ignoreBuildErrors: true,
},

serverExternalPackages: [
Expand All @@ -23,7 +23,7 @@ const nextConfig: NextConfig = {
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",

unoptimized: process.env.NODE_ENV === 'development',
unoptimized: false,

qualities: [25, 50, 75, 85, 90, 95, 100],

Expand Down Expand Up @@ -76,6 +76,9 @@ const nextConfig: NextConfig = {
},
],
},
experimental: {
turbopackFileSystemCacheForDev: true,
},
};

module.exports = nextConfig;
Loading