Compare commits
No commits in common. "777693c7dde151d3ba18953088d5ea7a1224e4e3" and "ad4ab40389310b4db4612849cdbdebbc0c49fdfb" have entirely different histories.
777693c7dd
...
ad4ab40389
@ -1,13 +1,10 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="es">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="theme-color" content="#f97316" />
|
<title>frontend</title>
|
||||||
<meta name="description" content="MiChangarrito - Sistema POS para changarritos" />
|
|
||||||
<title>MiChangarrito</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
4454
package-lock.json
generated
4454
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -43,7 +43,6 @@
|
|||||||
"tailwindcss": "^4.1.18",
|
"tailwindcss": "^4.1.18",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
"typescript-eslint": "^8.46.4",
|
"typescript-eslint": "^8.46.4",
|
||||||
"vite": "^7.2.4",
|
"vite": "^7.2.4"
|
||||||
"vite-plugin-pwa": "^1.2.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" width="180" height="180">
|
|
||||||
<rect width="180" height="180" fill="#f97316" rx="22"/>
|
|
||||||
<text x="90" y="112" font-family="Arial, sans-serif" font-size="68" font-weight="bold" fill="white" text-anchor="middle">MCH</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 287 B |
@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
|
|
||||||
<rect width="32" height="32" fill="#f97316" rx="4"/>
|
|
||||||
<text x="16" y="22" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="white" text-anchor="middle">M</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 277 B |
@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 192" width="192" height="192">
|
|
||||||
<rect width="192" height="192" fill="#f97316" rx="24"/>
|
|
||||||
<text x="96" y="120" font-family="Arial, sans-serif" font-size="72" font-weight="bold" fill="white" text-anchor="middle">MCH</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 287 B |
@ -1,4 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
|
||||||
<rect width="512" height="512" fill="#f97316" rx="64"/>
|
|
||||||
<text x="256" y="320" font-family="Arial, sans-serif" font-size="192" font-weight="bold" fill="white" text-anchor="middle">MCH</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 289 B |
@ -1,7 +1,6 @@
|
|||||||
import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom';
|
import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
||||||
import { ThemeProvider } from './contexts/ThemeContext';
|
|
||||||
import { Layout } from './components/Layout';
|
import { Layout } from './components/Layout';
|
||||||
import { Dashboard } from './pages/Dashboard';
|
import { Dashboard } from './pages/Dashboard';
|
||||||
import { Products } from './pages/Products';
|
import { Products } from './pages/Products';
|
||||||
@ -60,7 +59,6 @@ function PublicRoute() {
|
|||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<ThemeProvider>
|
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
@ -94,7 +92,6 @@ function App() {
|
|||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
</ThemeProvider>
|
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,13 +16,10 @@ import {
|
|||||||
Truck,
|
Truck,
|
||||||
Coins,
|
Coins,
|
||||||
QrCode,
|
QrCode,
|
||||||
Sun,
|
|
||||||
Moon,
|
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import { useTheme } from '../contexts/ThemeContext';
|
|
||||||
|
|
||||||
const navigation = [
|
const navigation = [
|
||||||
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard },
|
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard },
|
||||||
@ -42,7 +39,6 @@ const navigation = [
|
|||||||
export function Layout() {
|
export function Layout() {
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
const { user, tenant, logout } = useAuth();
|
const { user, tenant, logout } = useAuth();
|
||||||
const { resolvedTheme, toggleTheme } = useTheme();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
@ -60,7 +56,7 @@ export function Layout() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 transition-colors duration-200">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Mobile sidebar */}
|
{/* Mobile sidebar */}
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
@ -72,13 +68,13 @@ export function Layout() {
|
|||||||
className="fixed inset-0 bg-gray-900/80"
|
className="fixed inset-0 bg-gray-900/80"
|
||||||
onClick={() => setSidebarOpen(false)}
|
onClick={() => setSidebarOpen(false)}
|
||||||
/>
|
/>
|
||||||
<div className="fixed inset-y-0 left-0 w-64 bg-white dark:bg-gray-800 shadow-xl">
|
<div className="fixed inset-y-0 left-0 w-64 bg-white shadow-xl">
|
||||||
<div className="flex h-16 items-center justify-between px-4 border-b dark:border-gray-700">
|
<div className="flex h-16 items-center justify-between px-4 border-b">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Store className="h-8 w-8 text-primary-500" />
|
<Store className="h-8 w-8 text-primary-500" />
|
||||||
<span className="font-bold text-lg dark:text-gray-100">MiChangarrito</span>
|
<span className="font-bold text-lg">MiChangarrito</span>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={() => setSidebarOpen(false)} className="dark:text-gray-300">
|
<button onClick={() => setSidebarOpen(false)}>
|
||||||
<X className="h-6 w-6" />
|
<X className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -92,8 +88,8 @@ export function Layout() {
|
|||||||
clsx(
|
clsx(
|
||||||
'flex items-center gap-3 px-3 py-2 rounded-lg transition-colors',
|
'flex items-center gap-3 px-3 py-2 rounded-lg transition-colors',
|
||||||
isActive
|
isActive
|
||||||
? 'bg-primary-50 text-primary-600 dark:bg-primary-900/30 dark:text-primary-400'
|
? 'bg-primary-50 text-primary-600'
|
||||||
: 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
|
: 'text-gray-700 hover:bg-gray-100'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -107,23 +103,12 @@ export function Layout() {
|
|||||||
|
|
||||||
{/* Desktop sidebar */}
|
{/* Desktop sidebar */}
|
||||||
<div className="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
|
<div className="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
|
||||||
<div className="flex flex-col flex-grow bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 transition-colors duration-200">
|
<div className="flex flex-col flex-grow bg-white border-r border-gray-200">
|
||||||
<div className="flex h-16 items-center justify-between px-4 border-b dark:border-gray-700">
|
<div className="flex h-16 items-center px-4 border-b">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Store className="h-8 w-8 text-primary-500" />
|
<Store className="h-8 w-8 text-primary-500" />
|
||||||
<span className="font-bold text-lg dark:text-gray-100">MiChangarrito</span>
|
<span className="font-bold text-lg">MiChangarrito</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
onClick={toggleTheme}
|
|
||||||
className="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
||||||
title={resolvedTheme === 'dark' ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
|
|
||||||
>
|
|
||||||
{resolvedTheme === 'dark' ? (
|
|
||||||
<Sun className="h-5 w-5" />
|
|
||||||
) : (
|
|
||||||
<Moon className="h-5 w-5" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex-1 p-4 space-y-1">
|
<nav className="flex-1 p-4 space-y-1">
|
||||||
{navigation.map((item) => (
|
{navigation.map((item) => (
|
||||||
@ -134,8 +119,8 @@ export function Layout() {
|
|||||||
clsx(
|
clsx(
|
||||||
'flex items-center gap-3 px-3 py-2 rounded-lg transition-colors',
|
'flex items-center gap-3 px-3 py-2 rounded-lg transition-colors',
|
||||||
isActive
|
isActive
|
||||||
? 'bg-primary-50 text-primary-600 dark:bg-primary-900/30 dark:text-primary-400'
|
? 'bg-primary-50 text-primary-600'
|
||||||
: 'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700'
|
: 'text-gray-700 hover:bg-gray-100'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -144,22 +129,22 @@ export function Layout() {
|
|||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
<div className="p-4 border-t dark:border-gray-700">
|
<div className="p-4 border-t">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="h-10 w-10 rounded-full bg-emerald-100 dark:bg-emerald-900/50 flex items-center justify-center">
|
<div className="h-10 w-10 rounded-full bg-emerald-100 flex items-center justify-center">
|
||||||
<span className="text-emerald-600 dark:text-emerald-400 font-semibold">
|
<span className="text-emerald-600 font-semibold">
|
||||||
{tenant ? getInitials(tenant.name) : 'MC'}
|
{tenant ? getInitials(tenant.name) : 'MC'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium dark:text-gray-100">{tenant?.name || 'Mi Negocio'}</p>
|
<p className="text-sm font-medium">{tenant?.name || 'Mi Negocio'}</p>
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">{user?.name}</p>
|
<p className="text-xs text-gray-500">{user?.name}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={handleLogout}
|
onClick={handleLogout}
|
||||||
className="p-2 text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400 transition-colors"
|
className="p-2 text-gray-400 hover:text-red-500 transition-colors"
|
||||||
title="Cerrar sesion"
|
title="Cerrar sesion"
|
||||||
>
|
>
|
||||||
<LogOut className="h-5 w-5" />
|
<LogOut className="h-5 w-5" />
|
||||||
@ -172,28 +157,15 @@ export function Layout() {
|
|||||||
{/* Main content */}
|
{/* Main content */}
|
||||||
<div className="lg:pl-64">
|
<div className="lg:pl-64">
|
||||||
{/* Mobile header */}
|
{/* Mobile header */}
|
||||||
<div className="sticky top-0 z-40 flex h-16 items-center justify-between gap-4 bg-white dark:bg-gray-800 border-b dark:border-gray-700 px-4 lg:hidden transition-colors duration-200">
|
<div className="sticky top-0 z-40 flex h-16 items-center gap-4 bg-white border-b px-4 lg:hidden">
|
||||||
<div className="flex items-center gap-4">
|
<button onClick={() => setSidebarOpen(true)}>
|
||||||
<button onClick={() => setSidebarOpen(true)} className="dark:text-gray-300">
|
|
||||||
<Menu className="h-6 w-6" />
|
<Menu className="h-6 w-6" />
|
||||||
</button>
|
</button>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Store className="h-6 w-6 text-primary-500" />
|
<Store className="h-6 w-6 text-primary-500" />
|
||||||
<span className="font-bold dark:text-gray-100">MiChangarrito</span>
|
<span className="font-bold">MiChangarrito</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
onClick={toggleTheme}
|
|
||||||
className="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
||||||
title={resolvedTheme === 'dark' ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
|
|
||||||
>
|
|
||||||
{resolvedTheme === 'dark' ? (
|
|
||||||
<Sun className="h-5 w-5" />
|
|
||||||
) : (
|
|
||||||
<Moon className="h-5 w-5" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Page content */}
|
{/* Page content */}
|
||||||
<main className="p-4 lg:p-8">
|
<main className="p-4 lg:p-8">
|
||||||
|
|||||||
@ -1,103 +0,0 @@
|
|||||||
import { createContext, useContext, useState, useEffect } from 'react';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
|
|
||||||
type Theme = 'light' | 'dark' | 'system';
|
|
||||||
|
|
||||||
interface ThemeContextType {
|
|
||||||
theme: Theme;
|
|
||||||
resolvedTheme: 'light' | 'dark';
|
|
||||||
setTheme: (theme: Theme) => void;
|
|
||||||
toggleTheme: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
|
||||||
|
|
||||||
const STORAGE_KEY = 'michangarrito-theme';
|
|
||||||
|
|
||||||
function getSystemTheme(): 'light' | 'dark' {
|
|
||||||
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
return 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStoredTheme(): Theme {
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
const stored = localStorage.getItem(STORAGE_KEY);
|
|
||||||
if (stored === 'light' || stored === 'dark' || stored === 'system') {
|
|
||||||
return stored;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'system';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
||||||
const [theme, setThemeState] = useState<Theme>(getStoredTheme);
|
|
||||||
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');
|
|
||||||
|
|
||||||
// Resolve the actual theme (handles 'system' preference)
|
|
||||||
useEffect(() => {
|
|
||||||
const resolved = theme === 'system' ? getSystemTheme() : theme;
|
|
||||||
setResolvedTheme(resolved);
|
|
||||||
|
|
||||||
// Apply class to document
|
|
||||||
const root = document.documentElement;
|
|
||||||
if (resolved === 'dark') {
|
|
||||||
root.classList.add('dark');
|
|
||||||
} else {
|
|
||||||
root.classList.remove('dark');
|
|
||||||
}
|
|
||||||
}, [theme]);
|
|
||||||
|
|
||||||
// Listen for system theme changes
|
|
||||||
useEffect(() => {
|
|
||||||
if (theme !== 'system') return;
|
|
||||||
|
|
||||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
||||||
const handleChange = (e: MediaQueryListEvent) => {
|
|
||||||
const newTheme = e.matches ? 'dark' : 'light';
|
|
||||||
setResolvedTheme(newTheme);
|
|
||||||
|
|
||||||
const root = document.documentElement;
|
|
||||||
if (newTheme === 'dark') {
|
|
||||||
root.classList.add('dark');
|
|
||||||
} else {
|
|
||||||
root.classList.remove('dark');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaQuery.addEventListener('change', handleChange);
|
|
||||||
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
||||||
}, [theme]);
|
|
||||||
|
|
||||||
const setTheme = (newTheme: Theme) => {
|
|
||||||
setThemeState(newTheme);
|
|
||||||
localStorage.setItem(STORAGE_KEY, newTheme);
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleTheme = () => {
|
|
||||||
const newTheme = resolvedTheme === 'light' ? 'dark' : 'light';
|
|
||||||
setTheme(newTheme);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemeContext.Provider
|
|
||||||
value={{
|
|
||||||
theme,
|
|
||||||
resolvedTheme,
|
|
||||||
setTheme,
|
|
||||||
toggleTheme,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useTheme() {
|
|
||||||
const context = useContext(ThemeContext);
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error('useTheme must be used within a ThemeProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
@ -26,12 +26,7 @@
|
|||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
body {
|
body {
|
||||||
@apply bg-gray-50 text-gray-900 transition-colors duration-200;
|
@apply bg-gray-50 text-gray-900;
|
||||||
}
|
|
||||||
|
|
||||||
.dark body,
|
|
||||||
html.dark body {
|
|
||||||
@apply bg-gray-900 text-gray-100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,16 +41,13 @@
|
|||||||
|
|
||||||
.btn-outline {
|
.btn-outline {
|
||||||
@apply border border-gray-300 hover:border-gray-400 text-gray-700 font-medium py-2 px-4 rounded-lg transition-colors;
|
@apply border border-gray-300 hover:border-gray-400 text-gray-700 font-medium py-2 px-4 rounded-lg transition-colors;
|
||||||
@apply dark:border-gray-600 dark:hover:border-gray-500 dark:text-gray-300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@apply bg-white rounded-xl shadow-sm border border-gray-200 p-4;
|
@apply bg-white rounded-xl shadow-sm border border-gray-200 p-4;
|
||||||
@apply dark:bg-gray-800 dark:border-gray-700;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
@apply w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500;
|
@apply w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500;
|
||||||
@apply dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100 dark:placeholder-gray-400;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
darkMode: 'class',
|
|
||||||
content: [
|
content: [
|
||||||
"./index.html",
|
"./index.html",
|
||||||
"./src/**/*.{js,ts,jsx,tsx}",
|
"./src/**/*.{js,ts,jsx,tsx}",
|
||||||
|
|||||||
@ -1,45 +1,9 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [react()],
|
||||||
react(),
|
|
||||||
VitePWA({
|
|
||||||
registerType: 'autoUpdate',
|
|
||||||
includeAssets: ['favicon.svg', 'robots.txt', 'apple-touch-icon.svg'],
|
|
||||||
manifest: {
|
|
||||||
name: 'MiChangarrito',
|
|
||||||
short_name: 'Changarrito',
|
|
||||||
description: 'Sistema POS para changarritos',
|
|
||||||
theme_color: '#f97316',
|
|
||||||
background_color: '#ffffff',
|
|
||||||
display: 'standalone',
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: 'pwa-192x192.svg',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/svg+xml'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'pwa-512x512.svg',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/svg+xml'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'pwa-512x512.svg',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/svg+xml',
|
|
||||||
purpose: 'any maskable'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
workbox: {
|
|
||||||
globPatterns: ['**/*.{js,css,html,ico,png,svg}']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
],
|
|
||||||
server: {
|
server: {
|
||||||
port: 3140,
|
port: 3140,
|
||||||
proxy: {
|
proxy: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user