ソースを参照

Actualizacion mesas

OscarGil03 7 ヶ月 前
コミット
319ceeed89
共有100 個のファイルを変更した1597 個の追加116 個の削除を含む
  1. 3 3
      .vscode/launch.json
  2. 1 1
      README.md
  3. 2 2
      android/app/build.gradle
  4. 1 1
      android/app/src/main/AndroidManifest.xml
  5. 1 1
      android/app/src/main/kotlin/com/example/yoshi_papas_app/MainActivity.kt
  6. BIN
      android/app/src/main/res/mipmap-hdpi/launcher_icon.png
  7. BIN
      android/app/src/main/res/mipmap-mdpi/launcher_icon.png
  8. BIN
      android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
  9. BIN
      android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
  10. BIN
      android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
  11. BIN
      assets/JoshiLogo.ico
  12. BIN
      assets/icono.ico
  13. BIN
      assets/logo-BN.png
  14. BIN
      assets/logo.png
  15. 4 4
      flutter_launcher_icons.yaml
  16. 52 0
      installers/Joshi_inno_Script.iss
  17. 52 0
      installers/Joshi_inno_Scripts.iss
  18. 51 0
      installers/Turquesa_POS_Inno_Setup.iss
  19. BIN
      installers/TurquessaCoffeeSetup/TurquessaCoffeeSetup-2024-11-13.exe
  20. BIN
      installers/TurquessaPOS_Setup_2024-11-13-1.exe
  21. BIN
      installers/TurquessaPOS_Setup_2024-11-22.exe
  22. BIN
      installers/Turquessa_Setup-1.exe
  23. BIN
      installers/Turquessa_Setup_2024_11_13.exe
  24. 52 0
      installers/Turquessa_inno_Script1.iss
  25. 64 0
      installers/turq_installer.iss
  26. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  27. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  28. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  29. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  30. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  31. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  32. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  33. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  34. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  35. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  36. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
  37. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
  38. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
  39. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
  40. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  41. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  42. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
  43. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
  44. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  45. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  46. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  47. 2 2
      ios/Runner/Info.plist
  48. 3 2
      lib/main.dart
  49. 66 0
      lib/models/mesa_model.dart
  50. 1 0
      lib/models/models.dart
  51. 1 1
      lib/models/pedido_producto_toping_model.dart
  52. 1 1
      lib/models/permiso_model.dart
  53. 1 1
      lib/models/producto_model.dart
  54. 1 1
      lib/models/toping_categoria_model.dart
  55. 1 1
      lib/models/toping_model.dart
  56. 6 0
      lib/models/usuario_model.dart
  57. 1 1
      lib/models/usuario_permiso_model.dart
  58. 2 2
      lib/services/categoria_producto_service.dart
  59. 2 2
      lib/services/producto_service.dart
  60. 1 1
      lib/services/productos_service.dart
  61. 1 1
      lib/services/profile_service.dart
  62. 59 1
      lib/services/repo_service.dart
  63. 165 0
      lib/viewmodels/mesa_view_model.dart
  64. 36 23
      lib/viewmodels/pedido_view_model.dart
  65. 1 1
      lib/viewmodels/toping_categoria_view_model.dart
  66. 1 1
      lib/viewmodels/toping_view_model.dart
  67. 1 0
      lib/viewmodels/viewmodels.dart
  68. 2 2
      lib/views/categoria_producto/categoria_producto_form.dart
  69. 4 1
      lib/views/home/home_screen.dart
  70. 115 0
      lib/views/mesa/mesa_form.dart
  71. 407 0
      lib/views/mesa/mesa_screen.dart
  72. 362 11
      lib/views/pedido/pedido_form.dart
  73. 18 6
      lib/views/pedido/pedido_screen.dart
  74. 1 1
      lib/views/perfil/perfil_screen.dart
  75. 1 2
      lib/views/producto/producto_form.dart
  76. 2 2
      lib/views/toping/toping_form.dart
  77. 2 2
      lib/views/toping_categoria/toping_categoria_form.dart
  78. 20 7
      lib/widgets/app_drawer.dart
  79. 2 2
      linux/CMakeLists.txt
  80. 2 2
      linux/my_application.cc
  81. 6 6
      macos/Runner.xcodeproj/project.pbxproj
  82. 4 4
      macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  83. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
  84. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
  85. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
  86. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
  87. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
  88. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
  89. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
  90. 1 1
      macos/Runner/Configs/AppInfo.xcconfig
  91. 7 8
      pubspec.yaml
  92. 1 1
      test/widget_test.dart
  93. BIN
      web/favicon.png
  94. BIN
      web/icons/Icon-192.png
  95. BIN
      web/icons/Icon-512.png
  96. BIN
      web/icons/Icon-maskable-192.png
  97. BIN
      web/icons/Icon-maskable-512.png
  98. 2 2
      web/index.html
  99. 2 2
      web/manifest.json
  100. 0 0
      windows/CMakeLists.txt

+ 3 - 3
.vscode/launch.json

@@ -5,18 +5,18 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "yoshi_papas_app",
+            "name": "turquessa_app",
             "request": "launch",
             "type": "dart"
         },
         {
-            "name": "yoshi_papas_app (profile mode)",
+            "name": "turquessa_app (profile mode)",
             "request": "launch",
             "type": "dart",
             "flutterMode": "profile"
         },
         {
-            "name": "yoshi_papas_app (release mode)",
+            "name": "turquessa_app (release mode)",
             "request": "launch",
             "type": "dart",
             "flutterMode": "release"

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
-# yoshi_papas_app
+# turquessa_app
 
 A new Flutter project.
 

+ 2 - 2
android/app/build.gradle

@@ -23,7 +23,7 @@ if (flutterVersionName == null) {
 }
 
 android {
-    namespace "com.example.yoshi_papas_app"
+    namespace "com.example.turquessa_app"
     compileSdkVersion 34
     ndkVersion flutter.ndkVersion
 
@@ -42,7 +42,7 @@ android {
 
     defaultConfig {
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
-        applicationId "com.example.yoshi_papas_app"
+        applicationId "com.example.turquessa_app"
         // You can update the following values to match your application needs.
         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
         minSdkVersion 24

+ 1 - 1
android/app/src/main/AndroidManifest.xml

@@ -5,7 +5,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
     <application
-        android:label="joshi_papas_app"
+        android:label="turquessa_coffee_app"
         android:name="${applicationName}"
         android:icon="@mipmap/launcher_icon">
         <activity

+ 1 - 1
android/app/src/main/kotlin/com/example/yoshi_papas_app/MainActivity.kt

@@ -1,4 +1,4 @@
-package com.example.yoshi_papas_app
+package com.example.turquessa_app
 
 import io.flutter.embedding.android.FlutterActivity
 

BIN
android/app/src/main/res/mipmap-hdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-mdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xhdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png


BIN
assets/JoshiLogo.ico


BIN
assets/icono.ico


BIN
assets/logo-BN.png


BIN
assets/logo.png


+ 4 - 4
flutter_launcher_icons.yaml

@@ -1,6 +1,6 @@
 # flutter pub run flutter_launcher_icons
 flutter_launcher_icons:
-  image_path: "assets/JoshiLogo.png"
+  image_path: "assets/logo.png"
 
   android: "launcher_icon"
   # image_path_android: "assets/icon/icon.png"
@@ -14,13 +14,13 @@ flutter_launcher_icons:
 
   web:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"
 
   windows:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"
       icon_size: 256
 
   macos:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"

+ 52 - 0
installers/Joshi_inno_Script.iss

@@ -0,0 +1,52 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "JoshiPapasPOS"
+#define MyAppVersion "1.0"
+#define MyAppPublisher "JoshiPapas"
+#define MyAppExeName "yoshi_papas_app.exe"
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{702582E6-37C5-43C7-B36D-3C94AB62D406}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+DefaultDirName={autopf}\{#MyAppName}
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\installers
+OutputBaseFilename=JoshiPapasSetup
+SetupIconFile=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\assets\JoshiLogo.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\pdfium.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\permission_handler_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\printing_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\sqlite3.def"; DestDir: "{app}"; Flags: ignoreversion
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+

+ 52 - 0
installers/Joshi_inno_Scripts.iss

@@ -0,0 +1,52 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "JoshiPapasPOS"
+#define MyAppVersion "1.1"
+#define MyAppPublisher "JoshiPapas"
+#define MyAppExeName "yoshi_papas_app.exe"
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{94577222-7355-4608-BA29-68F4D6596669}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+DefaultDirName={autopf}\{#MyAppName}
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\installers
+OutputBaseFilename=JoshiPapasSetup
+SetupIconFile=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\assets\JoshiLogo.png
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\pdfium.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\permission_handler_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\printing_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\sqlite3.def"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\YoshiPapas\yoshi_papas_app\build\windows\x64\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+

+ 51 - 0
installers/Turquesa_POS_Inno_Setup.iss

@@ -0,0 +1,51 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "TurquessaPOS"
+#define MyAppVersion "1.2024.11.22"
+#define MyAppExeName "turquessa_app.exe"
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{FDA490E5-50B7-47B4-BE58-38ED1486304C}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+DefaultDirName={autopf}\{#MyAppName}
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\installers
+OutputBaseFilename=TurquessaPOS_Setup_2024-11-20
+SetupIconFile=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\assets\icono.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\pdfium.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\permission_handler_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\printing_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.def"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+

BIN
installers/TurquessaCoffeeSetup/TurquessaCoffeeSetup-2024-11-13.exe


BIN
installers/TurquessaPOS_Setup_2024-11-13-1.exe


BIN
installers/TurquessaPOS_Setup_2024-11-22.exe


BIN
installers/Turquessa_Setup-1.exe


BIN
installers/Turquessa_Setup_2024_11_13.exe


+ 52 - 0
installers/Turquessa_inno_Script1.iss

@@ -0,0 +1,52 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "TurquessaCoffeePOS"
+#define MyAppVersion "1.24.11.13"
+#define MyAppPublisher "TurquessaCoffee"
+#define MyAppExeName "turquessa_coffee_app.exe"
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{A1520D9F-748A-4E3A-8BF6-21BA8A5DE484}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+DefaultDirName={autopf}\{#MyAppName}
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\installers
+OutputBaseFilename=TurquessaCoffeeSetup
+SetupIconFile=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\assets\icono.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\pdfium.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\permission_handler_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\printing_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.def"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+

+ 64 - 0
installers/turq_installer.iss

@@ -0,0 +1,64 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+#define MyAppName "TurquessaCoffeeSetup"
+#define MyAppVersion "1.0"
+#define MyAppPublisher "Turquessa Coffee"
+#define MyAppExeName "turquessa_coffee_app.exe"
+#define MyAppAssocName MyAppName + " File"
+#define MyAppAssocExt ".myp"
+#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{BCAA57CD-BF4C-4777-A45B-1FBB46A4339B}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+DefaultDirName={autopf}\{#MyAppName}
+ChangesAssociations=yes
+DisableProgramGroupPage=yes
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+;PrivilegesRequired=lowest
+OutputDir=TurquessaCoffeeSetup
+OutputBaseFilename=TurquessaCoffeeSetup
+SetupIconFile=C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\assets\icono.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+
+[Languages]
+Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\pdfium.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\permission_handler_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\printing_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.def"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\turquessa_coffee_app.exe"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
+Source: "C:\Users\gusos\OneDrive\Escritorio\eDesarrollos\Turquesa\pos_turquessa_flutter\build\windows\x64\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Registry]
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
+Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
+Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".myp"; ValueData: ""
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
+

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png


+ 2 - 2
ios/Runner/Info.plist

@@ -5,7 +5,7 @@
 	<key>CFBundleDevelopmentRegion</key>
 	<string>$(DEVELOPMENT_LANGUAGE)</string>
 	<key>CFBundleDisplayName</key>
-	<string>Yoshi Papas App</string>
+	<string>Turquessa App</string>
 	<key>CFBundleExecutable</key>
 	<string>$(EXECUTABLE_NAME)</string>
 	<key>CFBundleIdentifier</key>
@@ -13,7 +13,7 @@
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
 	<key>CFBundleName</key>
-	<string>yoshi_papas_app</string>
+	<string>turquessa_app</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>

+ 3 - 2
lib/main.dart

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:provider/provider.dart';
 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
-import 'dart:io'; // Importa esto para usar Platform.isWindows
+import 'dart:io';
 
 import 'services/productos_service.dart';
 import 'views/home/home_screen.dart';
@@ -47,6 +47,7 @@ void main() async {
       ChangeNotifierProvider(create: (_) => SucursalViewModel()),
       ChangeNotifierProvider(create: (_) => PermisoViewModel()),
       ChangeNotifierProvider(create: (_) => CorteCajaViewModel()),
+      ChangeNotifierProvider(create: (_) => MesaViewModel()),
       // Agrega aquí cualquier otro provider que necesites
     ], child: const MyApp()));
   });
@@ -60,7 +61,7 @@ class MyApp extends StatelessWidget {
     return MaterialApp(
       locale: const Locale("en", "ES"),
       debugShowCheckedModeBanner: false,
-      title: 'Yoshi Papas',
+      title: 'Turquessa',
       theme: AppTheme.lightTheme,
       initialRoute: 'login',
       routes: {

+ 66 - 0
lib/models/mesa_model.dart

@@ -0,0 +1,66 @@
+import '/models/basico_model.dart';
+import '../services/services.dart';
+
+class Mesa extends Basico {
+  int? idSucursal;
+  String? nombre;
+  String? clave;
+  String? posicion;
+  bool? activa;
+
+  Mesa(
+      {super.id,
+      super.idLocal,
+      this.idSucursal,
+      this.nombre,
+      this.clave,
+      this.posicion,
+      this.activa,
+      super.creado,
+      super.modificado,
+      super.eliminado});
+
+  @override
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'idSucursal': idSucursal ?? 0,
+      'nombre': nombre ?? '',
+      'clave': clave ?? '',
+      'posicion': posicion ?? '',
+      'activa': activa == true ? 1 : 0,
+      'creado': creado?.toIso8601String(),
+      'modificado': modificado?.toIso8601String(),
+      'eliminado': eliminado?.toIso8601String(),
+    }..addAll(super.toJson());
+  }
+
+  Mesa.fromJson(Map<String, dynamic> json) {
+    super.parseJson(json);
+    idSucursal = Basico.parseInt(json['idSucursal']);
+    nombre = Basico.parseString(json['nombre']);
+    clave = Basico.parseString(json['clave']);
+    posicion = Basico.parseString(json['posicion']);
+    activa = Basico.parseInt(json['activa']) == 1;
+  }
+
+  Mesa.fromApi(Map<String, dynamic> json) {
+    super.parseJson(json);
+    idSucursal = Basico.parseInt(json['idSucursal']);
+    nombre = Basico.parseString(json['nombre']);
+    clave = Basico.parseString(json['clave']);
+    posicion = Basico.parseString(json['posicion']);
+    if (json['activo'] is bool) {
+      activa = json['activo'];
+    } else {
+      activa = Basico.parseInt(json['activo']) == 1;
+    }
+    creado = Basico.parseDate(json['creado']);
+    modificado = Basico.parseDate(json['modificado']);
+    eliminado = Basico.parseDate(json['eliminado']);
+  }
+
+  Future<void> guardar() async {
+    idLocal = await RepoService().guardar(this);
+  }
+}

+ 1 - 0
lib/models/models.dart

@@ -23,3 +23,4 @@ export '../models/sucursal_model.dart';
 export '../models/permiso_model.dart';
 export '../models/usuario_permiso_model.dart';
 export '../models/retiro_model.dart';
+export '../models/mesa_model.dart';

+ 1 - 1
lib/models/pedido_producto_toping_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/producto_model.dart';
+import '/models/producto_model.dart';
 import 'basico_model.dart';
 
 class PedidoProductoTopping extends Basico {

+ 1 - 1
lib/models/permiso_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/models.dart';
+import '/models/models.dart';
 
 import '../services/services.dart';
 import 'basico_model.dart';

+ 1 - 1
lib/models/producto_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/models.dart';
+import '/models/models.dart';
 
 import '../services/services.dart';
 import 'basico_model.dart';

+ 1 - 1
lib/models/toping_categoria_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/models.dart';
+import '/models/models.dart';
 import 'media_toping_categoria_model.dart';
 import 'basico_model.dart';
 

+ 1 - 1
lib/models/toping_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/models.dart';
+import '/models/models.dart';
 import 'basico_model.dart';
 
 class Toping extends Basico {

+ 6 - 0
lib/models/usuario_model.dart

@@ -23,6 +23,7 @@ class Usuario extends Basico {
   int? idSucursal;
   String? turno;
   String? clave;
+  String? token;
   List<String>? permisos;
   static const VER_CATEGORIAS = 'VER_CATEGORIAS';
   static const VER_DESC_APP = 'VER_DESC_APP';
@@ -54,6 +55,7 @@ class Usuario extends Basico {
     this.idSucursal,
     this.turno,
     this.clave,
+    this.token,
     this.permisos,
   });
 
@@ -81,6 +83,7 @@ class Usuario extends Basico {
       'idSucursal': idSucursal,
       'turno': turno,
       'clave': clave,
+      'token': token,
       'creado': creado?.toIso8601String(),
       'modificado': modificado?.toIso8601String(),
       'eliminado': eliminado?.toIso8601String(),
@@ -110,6 +113,7 @@ class Usuario extends Basico {
       'idSucursal': idSucursal,
       'turno': turno,
       'clave': clave,
+      'token': token,
       'creado': creado != null ? creado!.toIso8601String() : null,
       'modificado': modificado != null ? modificado!.toIso8601String() : null,
       'eliminado': eliminado != null ? eliminado!.toIso8601String() : null,
@@ -138,6 +142,7 @@ class Usuario extends Basico {
     idSucursal = Basico.parseInt(json['idSucursal']);
     turno = Basico.parseString(json['turno']);
     clave = Basico.parseString(json['clave']);
+    token = Basico.parseString(json['token']);
   }
 
   Usuario.fromApi(Map<String, dynamic> json) {
@@ -162,6 +167,7 @@ class Usuario extends Basico {
     idSucursal = Basico.parseInt(json['idSucursal']);
     turno = Basico.parseString(json['turno']);
     clave = Basico.parseString(json['clave']);
+    token = Basico.parseString(json['token']);
     permisos = (json['permisos'] as List).map((e) => e.toString()).toList();
   }
 

+ 1 - 1
lib/models/usuario_permiso_model.dart

@@ -1,4 +1,4 @@
-import 'package:yoshi_papas_app/models/models.dart';
+import '/models/models.dart';
 
 import '../services/services.dart';
 import 'basico_model.dart';

+ 2 - 2
lib/services/categoria_producto_service.dart

@@ -1,7 +1,7 @@
 import 'dart:convert';
 
-import 'package:yoshi_papas_app/data/api_response.dart';
-import 'package:yoshi_papas_app/models/models.dart';
+import '/data/api_response.dart';
+import '/models/models.dart';
 
 import '../services/base_service.dart';
 

+ 2 - 2
lib/services/producto_service.dart

@@ -1,6 +1,6 @@
 import 'package:sqflite/sqflite.dart';
-import 'package:yoshi_papas_app/data/api_response.dart';
-import 'package:yoshi_papas_app/models/models.dart';
+import '/data/api_response.dart';
+import '/models/models.dart';
 
 import '../services/base_service.dart';
 

+ 1 - 1
lib/services/productos_service.dart

@@ -1,5 +1,5 @@
 import 'package:sqflite/sqflite.dart';
-import 'package:yoshi_papas_app/services/repo_service.dart';
+import '/services/repo_service.dart';
 
 import '../models/models.dart';
 

+ 1 - 1
lib/services/profile_service.dart

@@ -1,6 +1,6 @@
 import 'dart:convert';
 import 'package:http/http.dart' as http;
-import 'package:yoshi_papas_app/data/session/session_storage.dart';
+import '/data/session/session_storage.dart';
 import '../models/models.dart';
 import '../services/base_service.dart';
 

+ 59 - 1
lib/services/repo_service.dart

@@ -9,7 +9,7 @@ import 'services.dart';
 import '../views/producto/producto_imagen.dart';
 
 class RepoService<T> {
-  static int dbVersion = 21;
+  static int dbVersion = 23;
   static String dbName = 'posTurquessa.db';
   static const String id = Basico.identificadorWeb;
   static const String idLocal = Basico.identificadorLocal;
@@ -26,6 +26,7 @@ class RepoService<T> {
     'UsuarioPermiso': UsuarioPermiso(),
     'Variable': Variable(),
     'Descuento': Descuento(),
+    'Mesa': Mesa(),
   };
 
   Future<Database?> get db async {
@@ -600,6 +601,33 @@ class RepoService<T> {
           await db.execute('''
           ALTER TABLE Deposito ADD COLUMN sincronizado TEXT;
         ''');
+
+          break;
+
+        case 21:
+          await db.execute('''
+          CREATE TABLE Mesa (
+            id INTEGER PRIMARY KEY AUTOINCREMENT,
+            idLocal INTEGER,
+            idSucursal INTEGER,
+            nombre TEXT,
+            clave TEXT,
+            posicion TEXT,
+            activa BOOLEAN,
+            creado TEXT,
+            modificado TEXT,
+            eliminado TEXT
+          )
+        ''');
+
+          break;
+
+        case 22:
+          await db.execute('''
+          ALTER TABLE Usuario ADD COLUMN token TEXT;
+        ''');
+
+          break;
       }
       oldVersion++;
     }
@@ -1401,4 +1429,34 @@ class RepoService<T> {
         ? response.resultados!.map((json) => Usuario.fromApi(json)).toList()
         : [];
   }
+
+  Future<void> sincronizarMesas(List<Mesa> mesasApi,
+      {bool forzar = false}) async {
+    var db = await RepoService().db;
+
+    // Obtener mesas locales
+    var mesasLocalesQuery = await db!.query('Mesa');
+    List<Mesa> mesasLocales =
+        mesasLocalesQuery.map((e) => Mesa.fromJson(e)).toList();
+
+    for (var mesaApi in mesasApi) {
+      // Buscar la mesa localmente
+      var mesaLocal = mesasLocales.firstWhere(
+        (mesa) => mesa.id == mesaApi.id,
+        orElse: () => Mesa(),
+      );
+
+      // Validar si es una nueva mesa o si necesita ser actualizada
+      if (mesaLocal.id == 0) {
+        print("Insertando nueva mesa: ${mesaApi.nombre}");
+        await RepoService().guardar(mesaApi);
+      } else if (forzar ||
+          mesaApi.modificado != null &&
+              (mesaLocal.modificado == null ||
+                  mesaApi.modificado!.isAfter(mesaLocal.modificado!))) {
+        print("Actualizando mesa: ${mesaApi.nombre}");
+        await RepoService().guardar(mesaApi);
+      }
+    }
+  }
 }

+ 165 - 0
lib/viewmodels/mesa_view_model.dart

@@ -0,0 +1,165 @@
+import '../data/api_response.dart';
+import '/models/mesa_model.dart';
+import 'package:flutter/material.dart';
+import '../services/services.dart';
+import 'package:sqflite/sqflite.dart';
+
+class MesaViewModel extends ChangeNotifier {
+  String _busqueda = "";
+  String get busqueda => _busqueda;
+
+  List<Mesa> _mesas = [];
+  bool _isLoading = false;
+  Mesa? _selectedMesa;
+
+  List<Mesa> get mesas => _mesas;
+  bool get isLoading => _isLoading;
+  Mesa? get selectedMesa => _selectedMesa;
+
+  int _currentPage = 1;
+  int _totalMesas = 0;
+  int _limit = 10;
+
+  int get currentPage => _currentPage;
+  int get totalMesas => _totalMesas;
+  int get totalPages => (_totalMesas / _limit).ceil();
+
+  setBusqueda(String value) {
+    _busqueda = value;
+    notifyListeners();
+  }
+
+  void selectMesa(Mesa mesa) {
+    _selectedMesa = mesa;
+    notifyListeners();
+  }
+
+  Future<void> fetchLocalAll({int page = 1}) async {
+    _currentPage = page;
+    var db = await RepoService().db;
+
+    int? count =
+        Sqflite.firstIntValue(await db!.rawQuery('SELECT COUNT(*) FROM Mesa'));
+    _totalMesas = count ?? 0;
+
+    int offset = (_limit * (page - 1));
+
+    var query = await db.query('Mesa',
+        orderBy: 'id asc', limit: _limit, offset: offset);
+    _mesas = query.map((element) => Mesa.fromJson(element)).toList();
+    notifyListeners();
+  }
+
+  Future<void> fetchLocalByName({required String nombre}) async {
+    var db = await RepoService().db;
+    var query = await db!.query(
+      'Mesa',
+      where: 'nombre LIKE "%$nombre%"',
+      orderBy: 'id asc',
+    );
+    List<Mesa> aux = [];
+    for (var element in query) {
+      Mesa mesa = Mesa.fromJson(element);
+      aux.add(mesa);
+    }
+    _mesas = aux;
+    notifyListeners();
+  }
+
+  Mesa fetchLocalById({required int? idMesa}) {
+    final mesa = mesas.firstWhere((mesa) => mesa.id == idMesa,
+        orElse: () => Mesa(id: 0, nombre: 'Mesa desconocida'));
+    return mesa;
+  }
+
+  Future<void> addMesa(Mesa mesa) async {
+    mesa.creado = DateTime.now().toUtc();
+    await RepoService().guardar(mesa);
+    await fetchLocalAll();
+  }
+
+  Future<void> updateMesa(Mesa mesa) async {
+    setIsLoading(true);
+    try {
+      mesa.modificado = DateTime.now().toUtc();
+      await RepoService().guardar(mesa);
+      await fetchLocalAll();
+    } catch (e) {
+      print('Error updating mesa: $e');
+    }
+    setIsLoading(false);
+  }
+
+  Future<void> deleteMesa(int id) async {
+    await RepoService().eliminar<Mesa>(id);
+    fetchLocalAll();
+  }
+
+  void setIsLoading(bool loading) {
+    _isLoading = loading;
+    notifyListeners();
+  }
+
+  void nextPage() {
+    if (_currentPage < totalPages) {
+      fetchLocalAll(page: _currentPage + 1);
+    }
+  }
+
+  void previousPage() {
+    if (_currentPage > 1) {
+      fetchLocalAll(page: _currentPage - 1);
+    }
+  }
+
+  Future<bool> isMesaActive(String clave) async {
+    var db = await RepoService().db;
+    var result = await db!.query(
+      'Mesa',
+      where: 'clave = ?',
+      whereArgs: [clave],
+    );
+
+    if (result.isNotEmpty) {
+      var mesa = Mesa.fromJson(result.first);
+      return mesa.activa == true;
+    }
+
+    return false;
+  }
+
+  Future<bool> sincronizarMesas() async {
+    String? claveSucursal =
+        await RepoService().obtenerClaveSucursalSeleccionada();
+
+    try {
+      Map<String, String> parametros = {
+        "claveSucursal": claveSucursal!,
+        "limite": "-1"
+      };
+
+      final response = ApiResponse(await BaseService()
+          .get('/pos/mesa', queryParameters: parametros, withAuth: true));
+
+      if (response.isOk && response.resultados != null) {
+        List<Mesa> mesasApi =
+            response.resultados!.map((json) => Mesa.fromApi(json)).toList();
+
+        if (mesasApi.isNotEmpty) {
+          print("Mesas API obtenidas: ${mesasApi.length}");
+          await RepoService().sincronizarMesas(mesasApi);
+          await fetchLocalAll();
+          return true;
+        } else {
+          print("No se encontraron mesas en la API.");
+        }
+      } else {
+        print("Error en la respuesta de la API o resultados nulos MESAS.");
+      }
+      return false;
+    } catch (e) {
+      print('Error al sincronizar mesas: $e');
+      return false;
+    }
+  }
+}

+ 36 - 23
lib/viewmodels/pedido_view_model.dart

@@ -34,47 +34,60 @@ class PedidoViewModel extends ChangeNotifier {
   Future<bool> guardarPedidoLocal({required Pedido pedido}) async {
     RepoService<Pedido> repoPedido = RepoService<Pedido>();
 
-    int nextFolio = await repoPedido.obtenerProximoFolio();
-    pedido.folio = nextFolio;
+    if (pedido.id == null || pedido.id == 0) {
+      int nextFolio = await repoPedido.obtenerProximoFolio();
+      pedido.folio = nextFolio;
+    }
+
+    try {
+      // Verifica si el pedido ya existe en la base de datos
+      Pedido? pedidoExistente = await repoPedido.obtenerPorId(pedido.id!);
+
+      if (pedidoExistente != null) {
+        // Si existe, actualiza
+        await repoPedido.guardar(pedido);
+      } else {
+        // Si no existe, inserta como nuevo
+        int idPedido = await repoPedido.guardarLocal(pedido);
+        pedido.id = idPedido;
+      }
 
-    int idPedido = await repoPedido.guardarLocal(pedido);
-    if (idPedido > 0) {
-      pedido.id = idPedido;
       RepoService<PedidoProducto> repoPedidoProducto =
           RepoService<PedidoProducto>();
       RepoService<PedidoProductoTopping> repoPedidoProductoTopping =
           RepoService<PedidoProductoTopping>();
 
+      // Manejo de productos asociados al pedido
       for (var producto in pedido.productos) {
         PedidoProducto pedidoProducto = PedidoProducto(
-          idPedido: idPedido,
+          idPedido: pedido.id,
           idProducto: producto.idProducto,
           cantidad: producto.cantidad,
           costoUnitario: producto.costoUnitario,
           comentario: producto.comentario,
         );
-        int idPedidoProducto =
-            await repoPedidoProducto.guardarLocal(pedidoProducto);
-
-        for (var topping in producto.toppings) {
-          PedidoProductoTopping pedidoProductoTopping = PedidoProductoTopping(
-            idPedidoProducto: idPedidoProducto,
-            idTopping: topping.idTopping,
-            idCategoria: topping.idCategoria,
-          );
-          await repoPedidoProductoTopping.guardarLocal(pedidoProductoTopping);
-
-          // Recuperar detalles completos del topping
-          Producto? toppingInfo = await RepoService<Producto>()
-              .obtenerProductoPorId(topping.idTopping!);
-          if (toppingInfo != null) {
-            topping.topping = toppingInfo;
+
+        if (producto.id != null && producto.id! > 0) {
+          await repoPedidoProducto.guardarLocal(pedidoProducto);
+        } else {
+          int idPedidoProducto =
+              await repoPedidoProducto.guardarLocal(pedidoProducto);
+
+          for (var topping in producto.toppings) {
+            PedidoProductoTopping pedidoProductoTopping = PedidoProductoTopping(
+              idPedidoProducto: idPedidoProducto,
+              idTopping: topping.idTopping,
+              idCategoria: topping.idCategoria,
+            );
+            await repoPedidoProductoTopping.guardarLocal(pedidoProductoTopping);
           }
         }
       }
+
       notifyListeners();
       return true;
-    } else {
+    } catch (e) {
+      print('Error al guardar el pedido: $e');
       return false;
     }
   }

+ 1 - 1
lib/viewmodels/toping_categoria_view_model.dart

@@ -2,7 +2,7 @@ import 'dart:convert';
 
 import 'package:camera/camera.dart';
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/models/toping_categoria_model.dart';
+import '/models/toping_categoria_model.dart';
 
 import '../data/api_response.dart';
 import '../services/base_service.dart';

+ 1 - 1
lib/viewmodels/toping_view_model.dart

@@ -2,7 +2,7 @@ import 'dart:convert';
 
 import 'package:camera/camera.dart';
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/models/toping_categoria_model.dart';
+import '/models/toping_categoria_model.dart';
 
 import '../data/api_response.dart';
 import '../services/base_service.dart';

+ 1 - 0
lib/viewmodels/viewmodels.dart

@@ -12,3 +12,4 @@ export '../viewmodels/variable_view_model.dart';
 export '../viewmodels/sucursal_view_model.dart';
 export '../viewmodels/permiso_view_model.dart';
 export '../viewmodels/corte_caja_view_model.dart';
+export '../viewmodels/mesa_view_model.dart';

+ 2 - 2
lib/views/categoria_producto/categoria_producto_form.dart

@@ -1,6 +1,6 @@
-import 'package:yoshi_papas_app/themes/themes.dart';
+import '/themes/themes.dart';
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/widgets/widgets.dart';
+import '/widgets/widgets.dart';
 import 'package:provider/provider.dart';
 
 import '../../models/models.dart';

+ 4 - 1
lib/views/home/home_screen.dart

@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/widgets/widgets.dart';
+import '/widgets/widgets.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 
@@ -28,6 +28,8 @@ class Formulario extends State<HomeScreen> {
       Provider.of<ProductoViewModel>(context, listen: false)
           .sincronizarProductosYCategorias();
 
+      Provider.of<MesaViewModel>(context, listen: false).sincronizarMesas();
+
       final permisoViewModel =
           Provider.of<PermisoViewModel>(context, listen: false);
       if (permisoViewModel.userPermisos.isEmpty) {
@@ -35,6 +37,7 @@ class Formulario extends State<HomeScreen> {
       }
 
       Provider.of<CorteCajaViewModel>(context, listen: false).fetchCortes();
+      Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll();
     });
   }
 

+ 115 - 0
lib/views/mesa/mesa_form.dart

@@ -0,0 +1,115 @@
+import '/models/mesa_model.dart';
+import '/themes/themes.dart';
+import '/viewmodels/mesa_view_model.dart';
+import '/widgets/widgets.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class MesaForm extends StatefulWidget {
+  final Mesa mesa;
+
+  const MesaForm({Key? key, required this.mesa}) : super(key: key);
+
+  @override
+  _MesaFormState createState() => _MesaFormState();
+}
+
+class _MesaFormState extends State<MesaForm> {
+  final _nombre = TextEditingController();
+  final _clave = TextEditingController();
+  bool _activa = true;
+
+  @override
+  void initState() {
+    super.initState();
+    _nombre.text = widget.mesa.nombre ?? "";
+    _clave.text = widget.mesa.clave ?? "";
+    _activa = widget.mesa.activa ?? true;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(
+          widget.mesa.id == null ? 'Nueva Mesa' : 'Editar Mesa',
+          style: TextStyle(color: AppTheme.secondary),
+        ),
+        iconTheme: IconThemeData(color: AppTheme.secondary),
+      ),
+      body: SingleChildScrollView(
+        padding: EdgeInsets.all(8),
+        child: Column(
+          children: [
+            tarjeta(
+              Padding(
+                padding: const EdgeInsets.all(8),
+                child: Column(
+                  children: [
+                    AppTextField(
+                      maxLength: 100,
+                      etiqueta: 'Nombre',
+                      controller: _nombre,
+                      hintText: 'Nombre de la mesa',
+                    ),
+                    AppTextField(
+                      maxLength: 100,
+                      etiqueta: 'Clave',
+                      controller: _clave,
+                      hintText: 'Clave de la mesa',
+                    ),
+                    SwitchListTile(
+                      activeColor: AppTheme.primary,
+                      title: const Text(
+                        "Activo",
+                        style: TextStyle(
+                            fontWeight: FontWeight.bold, fontSize: 18),
+                      ),
+                      value: _activa,
+                      onChanged: (bool value) {
+                        setState(() {
+                          _activa = value;
+                        });
+                      },
+                    ),
+                  ],
+                ),
+              ),
+            ),
+            SizedBox(height: 15),
+            boton("Guardar", () async {
+              Provider.of<MesaViewModel>(context, listen: false)
+                  .setIsLoading(true);
+
+              widget.mesa.nombre = _nombre.text;
+              widget.mesa.clave = _clave.text;
+              widget.mesa.activa = _activa;
+
+              if (widget.mesa.id == null || widget.mesa.id == 0) {
+                await Provider.of<MesaViewModel>(context, listen: false)
+                    .addMesa(widget.mesa);
+              } else {
+                await Provider.of<MesaViewModel>(context, listen: false)
+                    .updateMesa(widget.mesa);
+              }
+
+              Provider.of<MesaViewModel>(context, listen: false)
+                  .setIsLoading(false);
+
+              if (context.mounted) {
+                Navigator.pop(context);
+              }
+            })
+          ],
+        ),
+      ),
+    );
+  }
+
+  @override
+  void dispose() {
+    _nombre.dispose();
+    _clave.dispose();
+    super.dispose();
+  }
+}

+ 407 - 0
lib/views/mesa/mesa_screen.dart

@@ -0,0 +1,407 @@
+import '/models/mesa_model.dart';
+import '/themes/themes.dart';
+import '/viewmodels/mesa_view_model.dart';
+import 'mesa_form.dart';
+import '/widgets/widgets.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import '../../widgets/widgets_components.dart' as clase;
+
+class MesasScreen extends StatefulWidget {
+  @override
+  _MesasScreenState createState() => _MesasScreenState();
+}
+
+class _MesasScreenState extends State<MesasScreen> {
+  final _busqueda = TextEditingController(text: '');
+  ScrollController horizontalScrollController = ScrollController();
+
+  @override
+  void initState() {
+    super.initState();
+    Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll();
+  }
+
+  void go(Mesa variable) {
+    Navigator.push(
+      context,
+      MaterialPageRoute(
+        builder: (context) => MesaForm(mesa: variable),
+      ),
+    ).then((_) =>
+        Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll());
+  }
+
+  void clearSearchAndReset() {
+    setState(() {
+      _busqueda.clear();
+      Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll();
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final model = Provider.of<MesaViewModel>(context);
+    double screenWidth = MediaQuery.of(context).size.width;
+    final isMobile = screenWidth < 1250;
+    final double? columnSpacing = isMobile ? null : 0;
+    TextStyle estilo = const TextStyle(fontWeight: FontWeight.bold);
+
+    List<DataRow> registros = [];
+    for (Mesa item in model.mesas) {
+      registros.add(DataRow(cells: [
+        DataCell(
+            Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
+          PopupMenuButton(
+            itemBuilder: (context) => [
+              PopupMenuItem(
+                child: const Text('Editar'),
+                onTap: () => go(item),
+              ),
+              PopupMenuItem(
+                child: const Text('Eliminar'),
+                onTap: () async {
+                  await Future.delayed(Duration(milliseconds: 100));
+                  bool confirmado = await showDialog<bool>(
+                        context: context,
+                        builder: (context) {
+                          return AlertDialog(
+                            title: const Text("Eliminar",
+                                style: TextStyle(
+                                    fontWeight: FontWeight.w500, fontSize: 22)),
+                            content: const Text(
+                                '¿Estás seguro de que deseas eliminar esta variable?',
+                                style: TextStyle(fontSize: 18)),
+                            actions: [
+                              Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  TextButton(
+                                    onPressed: () =>
+                                        Navigator.of(context).pop(false),
+                                    child: const Text('No',
+                                        style: TextStyle(fontSize: 18)),
+                                    style: ButtonStyle(
+                                        padding: MaterialStatePropertyAll(
+                                            EdgeInsets.fromLTRB(
+                                                20, 10, 20, 10)),
+                                        backgroundColor:
+                                            MaterialStatePropertyAll(
+                                                AppTheme.primary),
+                                        foregroundColor:
+                                            MaterialStatePropertyAll(
+                                                AppTheme.secondary)),
+                                  ),
+                                  TextButton(
+                                    onPressed: () =>
+                                        Navigator.of(context).pop(true),
+                                    child: const Text('Sí',
+                                        style: TextStyle(fontSize: 18)),
+                                    style: ButtonStyle(
+                                        padding: MaterialStatePropertyAll(
+                                            EdgeInsets.fromLTRB(
+                                                20, 10, 20, 10)),
+                                        backgroundColor:
+                                            MaterialStatePropertyAll(
+                                                AppTheme.tertiary),
+                                        foregroundColor:
+                                            MaterialStatePropertyAll(
+                                                AppTheme.quaternary)),
+                                  ),
+                                ],
+                              )
+                            ],
+                          );
+                        },
+                      ) ??
+                      false;
+
+                  if (confirmado) {
+                    await model.deleteMesa(item.id!);
+                    model.fetchLocalAll();
+                  }
+                },
+              )
+            ],
+            icon: const Icon(Icons.more_vert),
+          ),
+        ])),
+        DataCell(
+          Text(item.id.toString()),
+          onTap: () {
+            Provider.of<MesaViewModel>(context, listen: false).selectMesa(item);
+            go(item);
+          },
+        ),
+        DataCell(
+          Text(item.nombre.toString()),
+          onTap: () {
+            Provider.of<MesaViewModel>(context, listen: false).selectMesa(item);
+            go(item);
+          },
+        ),
+      ]));
+    }
+
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(
+          'Mesas',
+          style: TextStyle(color: AppTheme.secondary),
+        ),
+        iconTheme: IconThemeData(color: AppTheme.secondary),
+      ),
+      body: Column(
+        children: [
+          Expanded(
+            child: ListView(
+              padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
+              children: [
+                const SizedBox(height: 8),
+                clase.tarjeta(
+                  Padding(
+                    padding: const EdgeInsets.all(8.0),
+                    child: LayoutBuilder(
+                      builder: (context, constraints) {
+                        if (screenWidth > 1000) {
+                          return Row(
+                            children: [
+                              Expanded(
+                                flex: 7,
+                                child: busquedaTextField(),
+                              ),
+                              SizedBox(width: 5),
+                              botonBuscar()
+                            ],
+                          );
+                        } else {
+                          return Column(
+                            children: [
+                              Row(
+                                children: [busquedaTextField()],
+                              ),
+                              SizedBox(height: 15),
+                              Row(
+                                children: [botonBuscar()],
+                              ),
+                            ],
+                          );
+                        }
+                      },
+                    ),
+                  ),
+                ),
+                const SizedBox(height: 8),
+                model.isLoading
+                    ? const Center(child: CircularProgressIndicator())
+                    : Container(),
+                clase.tarjeta(
+                  Column(
+                    children: [
+                      LayoutBuilder(builder: (context, constraints) {
+                        return SingleChildScrollView(
+                          scrollDirection: Axis.vertical,
+                          child: Scrollbar(
+                            controller: horizontalScrollController,
+                            interactive: true,
+                            thumbVisibility: true,
+                            thickness: 10.0,
+                            child: SingleChildScrollView(
+                              controller: horizontalScrollController,
+                              scrollDirection: Axis.horizontal,
+                              child: ConstrainedBox(
+                                constraints: BoxConstraints(
+                                    minWidth: isMobile
+                                        ? constraints.maxWidth
+                                        : screenWidth),
+                                child: DataTable(
+                                  columnSpacing: columnSpacing,
+                                  sortAscending: true,
+                                  sortColumnIndex: 1,
+                                  columns: [
+                                    DataColumn(label: Text(" ", style: estilo)),
+                                    DataColumn(
+                                        label: Text("ID", style: estilo)),
+                                    DataColumn(
+                                        label: Text("NOMBRE", style: estilo)),
+                                  ],
+                                  rows: registros,
+                                ),
+                              ),
+                            ),
+                          ),
+                        );
+                      }),
+                    ],
+                  ),
+                ),
+                const SizedBox(
+                  height: 15,
+                ),
+                if (!model.isLoading) ...[
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      TextButton(
+                        onPressed:
+                            model.currentPage > 1 ? model.previousPage : null,
+                        child: Text('Anterior'),
+                        style: ButtonStyle(
+                          backgroundColor:
+                              MaterialStateProperty.resolveWith<Color?>(
+                            (Set<MaterialState> states) {
+                              if (states.contains(MaterialState.disabled)) {
+                                return Colors.grey;
+                              }
+                              return AppTheme.tertiary;
+                            },
+                          ),
+                          foregroundColor:
+                              MaterialStateProperty.resolveWith<Color?>(
+                            (Set<MaterialState> states) {
+                              if (states.contains(MaterialState.disabled)) {
+                                return Colors.black;
+                              }
+                              return Colors.white;
+                            },
+                          ),
+                        ),
+                      ),
+                      SizedBox(width: 15),
+                      Text(
+                          'Página ${model.currentPage} de ${model.totalPages}'),
+                      SizedBox(width: 15),
+                      TextButton(
+                        onPressed: model.currentPage < model.totalPages
+                            ? model.nextPage
+                            : null,
+                        child: Text('Siguiente'),
+                        style: ButtonStyle(
+                          backgroundColor:
+                              MaterialStateProperty.resolveWith<Color?>(
+                            (Set<MaterialState> states) {
+                              if (states.contains(MaterialState.disabled)) {
+                                return Colors.grey;
+                              }
+                              return AppTheme.tertiary;
+                            },
+                          ),
+                          foregroundColor:
+                              MaterialStateProperty.resolveWith<Color?>(
+                            (Set<MaterialState> states) {
+                              if (states.contains(MaterialState.disabled)) {
+                                return Colors.black;
+                              }
+                              return Colors.white;
+                            },
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                ],
+                const SizedBox(
+                  height: 15,
+                ),
+              ],
+            ),
+          ),
+        ],
+      ),
+      floatingActionButton: FloatingActionButton.extended(
+        onPressed: () async {
+          Mesa nuevaMesa = Mesa();
+          Navigator.push(
+            context,
+            MaterialPageRoute(
+              builder: (context) => MesaForm(mesa: nuevaMesa),
+            ),
+          ).then((_) => Provider.of<MesaViewModel>(context, listen: false)
+              .fetchLocalAll());
+        },
+        icon: Icon(Icons.add, size: 30, color: AppTheme.quaternary),
+        label: Text(
+          "Agregar Mesa",
+          style: TextStyle(fontSize: 18, color: AppTheme.quaternary),
+        ),
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(8),
+        ),
+        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+        backgroundColor: AppTheme.tertiary,
+      ),
+    );
+  }
+
+  Widget busquedaTextField() {
+    return Row(
+      children: [
+        Expanded(
+          flex: 3,
+          child: AppTextField(
+            prefixIcon: const Icon(Icons.search),
+            etiqueta: 'Búsqueda por nombre...',
+            controller: _busqueda,
+            hintText: 'Búsqueda por nombre...',
+          ),
+        ),
+        const SizedBox(width: 5),
+      ],
+    );
+  }
+
+  Widget botonBuscar() {
+    return Expanded(
+        flex: 2,
+        child: Row(
+          children: [
+            Expanded(
+              flex: 2,
+              child: Padding(
+                padding: const EdgeInsets.only(top: 30),
+                child: ElevatedButton(
+                  onPressed: clearSearchAndReset,
+                  style: ElevatedButton.styleFrom(
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(20.0),
+                    ),
+                    backgroundColor: AppTheme.tertiary,
+                    padding: const EdgeInsets.symmetric(vertical: 25),
+                  ),
+                  child: Text('Limpiar',
+                      style: TextStyle(color: AppTheme.quaternary)),
+                ),
+              ),
+            ),
+            const SizedBox(width: 8),
+            Expanded(
+              flex: 2,
+              child: Padding(
+                padding: const EdgeInsets.only(top: 30),
+                child: ElevatedButton(
+                  onPressed: () async {
+                    if (_busqueda.text.isNotEmpty) {
+                      await Provider.of<MesaViewModel>(context, listen: false)
+                          .fetchLocalByName(nombre: _busqueda.text.trim());
+                    } else {
+                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
+                          content: Text('Introduce un nombre para buscar.')));
+                    }
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(20.0),
+                    ),
+                    backgroundColor: AppTheme.tertiary,
+                    padding: const EdgeInsets.symmetric(vertical: 25),
+                  ),
+                  child: Text('Buscar',
+                      style: TextStyle(color: AppTheme.quaternary)),
+                ),
+              ),
+            ),
+          ],
+        ));
+  }
+}

+ 362 - 11
lib/views/pedido/pedido_form.dart

@@ -5,8 +5,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
-import 'package:yoshi_papas_app/data/session/session_storage.dart';
-import 'package:yoshi_papas_app/views/pedido/pedido_ticket.dart';
+import '/data/session/session_storage.dart';
+import '/views/pedido/pedido_ticket.dart';
 import '../../themes/themes.dart';
 import '../../models/models.dart';
 import '../../viewmodels/viewmodels.dart';
@@ -14,6 +14,10 @@ import 'package:collection/collection.dart';
 import '../../widgets/widgets.dart';
 
 class PedidoForm extends StatefulWidget {
+  final Pedido? pedidoExistente;
+
+  const PedidoForm({Key? key, this.pedidoExistente}) : super(key: key);
+
   @override
   _PedidoFormState createState() => _PedidoFormState();
 }
@@ -50,6 +54,7 @@ class _PedidoFormState extends State<PedidoForm> {
   double cambio = 0.0;
   double faltante = 0.0;
   bool totalCompletado = false;
+  bool _isMesasActive = false;
 
   double calcularTotalPedido() {
     double total = 0;
@@ -85,6 +90,21 @@ class _PedidoFormState extends State<PedidoForm> {
   @override
   void initState() {
     super.initState();
+
+    pedidoActual = widget.pedidoExistente ?? Pedido(id: 0);
+    Future.microtask(() async {
+      bool isMesasActive =
+          await Provider.of<VariableViewModel>(context, listen: false)
+              .isVariableActive('MESAS');
+      setState(() {
+        _isMesasActive = isMesasActive;
+      });
+
+      if (pedidoActual != null && pedidoActual!.id! > 0) {
+        await _cargarPedidoExistente(pedidoActual!.id!);
+      }
+    });
+
     cargarCategoriasIniciales().then((_) {
       if (categorias.isNotEmpty) {
         categoriaSeleccionada = categorias.first;
@@ -95,6 +115,34 @@ class _PedidoFormState extends State<PedidoForm> {
     Provider.of<DescuentoViewModel>(context, listen: false).cargarDescuentos();
   }
 
+  Future<void> _cargarPedidoExistente(int pedidoId) async {
+    Pedido? pedidoCompleto =
+        await Provider.of<PedidoViewModel>(context, listen: false)
+            .fetchPedidoConProductos(pedidoId);
+
+    if (pedidoCompleto != null) {
+      setState(() {
+        pedidoActual = pedidoCompleto;
+        carrito = pedidoCompleto.productos.map((producto) {
+          return ItemCarrito(
+            producto: producto.producto!,
+            cantidad: producto.cantidad!,
+            selectedToppings: producto.toppings.fold<Map<int, Set<int>>>(
+              {},
+              (acc, topping) {
+                acc[topping.idCategoria!] ??= {};
+                acc[topping.idCategoria]!.add(topping.idTopping!);
+                return acc;
+              },
+            ),
+          );
+        }).toList();
+      });
+
+      _recalcularTotal();
+    }
+  }
+
   void _onSearchChanged(String value) async {
     if (value.isEmpty) {
       cargarProductosPorCategoria(
@@ -209,6 +257,276 @@ class _PedidoFormState extends State<PedidoForm> {
     await _promptForCustomerName();
   }
 
+  void _crearPedido() async {
+    if (carrito.isEmpty) {
+      _mostrarDialogoPedidoVacio();
+      return;
+    }
+
+    Pedido nuevoPedido = Pedido(
+      peticion: DateTime.now().toUtc().toIso8601String(),
+      estatus: 'NUEVO',
+      totalPedido: totalPedido,
+      descuento: selectedDescuento,
+      idUsuario: await SessionStorage().getId(),
+      productos: carrito.map((item) {
+        return PedidoProducto(
+          idProducto: item.producto.id,
+          producto: item.producto,
+          costoUnitario: item.producto.precio.toString(),
+          cantidad: item.cantidad,
+          toppings: item.selectedToppings.entries.expand((entry) {
+            return entry.value.map((toppingId) {
+              return PedidoProductoTopping(
+                idCategoria: entry.key,
+                idTopping: toppingId,
+              );
+            });
+          }).toList(),
+        );
+      }).toList(),
+    );
+
+    bool result = await Provider.of<PedidoViewModel>(context, listen: false)
+        .guardarPedidoLocal(pedido: nuevoPedido);
+
+    if (result) {
+      Navigator.of(context).pop();
+    } else {
+      print('Error al crear el pedido');
+    }
+  }
+
+  void _mostrarDialogoPedidoVacio() {
+    showDialog(
+      context: context,
+      builder: (BuildContext context) {
+        return AlertDialog(
+          title: const Text('Pedido vacío',
+              style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22)),
+          content: const Text(
+              'No puedes crear un pedido sin productos. Por favor, agrega al menos un producto.',
+              style: TextStyle(fontSize: 18)),
+          shape:
+              RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
+          actions: <Widget>[
+            TextButton(
+              style: TextButton.styleFrom(
+                  padding: const EdgeInsets.fromLTRB(30, 20, 30, 20),
+                  foregroundColor: AppTheme.quaternary,
+                  backgroundColor: AppTheme.tertiary),
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+              child: const Text('Aceptar', style: TextStyle(fontSize: 18)),
+            ),
+          ],
+        );
+      },
+    );
+  }
+
+  Future<void> _crearPedidoConModal() async {
+    TextEditingController nombreController = TextEditingController();
+    TextEditingController descripcionController = TextEditingController();
+
+    int? idMesaSeleccionada;
+
+    await Provider.of<MesaViewModel>(context, listen: false).fetchLocalAll();
+    List<Mesa> mesasDisponibles =
+        Provider.of<MesaViewModel>(context, listen: false).mesas;
+
+    bool? shouldSave = await showDialog<bool>(
+      context: context,
+      builder: (BuildContext context) {
+        return AlertDialog(
+          title: const Text(
+            'Crear Pedido',
+            style: TextStyle(fontSize: 22, fontWeight: FontWeight.w500),
+          ),
+          content: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              AppTextField(
+                controller: nombreController,
+                etiqueta: 'Nombre del Cliente',
+                hintText: 'Nombre del Cliente',
+              ),
+              const SizedBox(height: 10),
+              AppTextField(
+                controller: descripcionController,
+                etiqueta: 'Descripción',
+                hintText: 'Descripción del Pedido',
+              ),
+              const SizedBox(height: 10),
+              DropdownButtonFormField<int>(
+                hint: const Text('Seleccionar Mesa'),
+                items: mesasDisponibles
+                    .map((mesa) => DropdownMenuItem<int>(
+                          value: mesa.id,
+                          child: Text(mesa.nombre ?? 'Sin Nombre'),
+                        ))
+                    .toList(),
+                onChanged: (value) {
+                  idMesaSeleccionada = value;
+                },
+                decoration: const InputDecoration(
+                  labelText: 'Mesa',
+                  border: OutlineInputBorder(),
+                ),
+              ),
+            ],
+          ),
+          actions: [
+            TextButton(
+              onPressed: () => Navigator.of(context).pop(false),
+              child: const Text('Cancelar'),
+            ),
+            TextButton(
+              onPressed: () {
+                if (idMesaSeleccionada != null) {
+                  Navigator.of(context).pop(true);
+                } else {
+                  ScaffoldMessenger.of(context).showSnackBar(
+                    const SnackBar(
+                      content: Text('Seleccione una mesa por favor'),
+                    ),
+                  );
+                }
+              },
+              child: const Text('Guardar'),
+            ),
+          ],
+        );
+      },
+    );
+
+    if (shouldSave ?? false) {
+      Pedido nuevoPedido = Pedido(
+        peticion: DateTime.now().toUtc().toIso8601String(),
+        nombreCliente: nombreController.text,
+        comentarios: descripcionController.text,
+        estatus: 'NUEVO',
+        idMesa: idMesaSeleccionada,
+        totalPedido: totalPedido,
+        descuento: selectedDescuento,
+        idUsuario: await SessionStorage().getId(),
+        productos: carrito.map((item) {
+          return PedidoProducto(
+            idProducto: item.producto.id,
+            producto: item.producto,
+            costoUnitario: item.producto.precio.toString(),
+            cantidad: item.cantidad,
+            toppings: item.selectedToppings.entries.expand((entry) {
+              return entry.value.map((toppingId) {
+                return PedidoProductoTopping(
+                  idCategoria: entry.key,
+                  idTopping: toppingId,
+                );
+              });
+            }).toList(),
+          );
+        }).toList(),
+      );
+
+      bool result = await Provider.of<PedidoViewModel>(context, listen: false)
+          .guardarPedidoLocal(pedido: nuevoPedido);
+
+      if (result) {
+        Navigator.of(context).pop();
+      } else {
+        print('Error al guardar el pedido');
+      }
+    }
+  }
+
+  Future<void> _guardarPedidoExistente() async {
+    if (pedidoActual == null) return;
+
+    pedidoActual!.totalPedido = totalPedido;
+    pedidoActual!.descuento = selectedDescuento;
+    pedidoActual!.sincronizado = null;
+
+    final Map<int, PedidoProducto> productosExistentes = {
+      for (var producto in pedidoActual!.productos)
+        producto.idProducto!: producto
+    };
+
+    for (var item in carrito) {
+      PedidoProducto? productoExistente = productosExistentes[item.producto.id];
+
+      if (productoExistente != null) {
+        print(
+            "Actualizando producto existente: ID ${productoExistente.idProducto}, cantidad previa: ${productoExistente.cantidad}, cantidad nueva: ${item.cantidad}");
+
+        productoExistente.cantidad = item.cantidad;
+        productoExistente.descuento =
+            item.producto.descuento?.toString() ?? '0';
+        productoExistente.costoUnitario = item.producto.precio.toString();
+        productoExistente.sincronizado = null;
+
+        // Actualizar los toppings, si aplica
+        for (var entry in item.selectedToppings.entries) {
+          int categoriaId = entry.key;
+          for (int toppingId in entry.value) {
+            PedidoProductoTopping? toppingExistente =
+                productoExistente.toppings.firstWhereOrNull(
+              (t) => t.idTopping == toppingId && t.idCategoria == categoriaId,
+            );
+
+            if (toppingExistente == null) {
+              print(
+                  "Añadiendo topping nuevo: Categoria ${categoriaId}, Topping ${toppingId}");
+              productoExistente.toppings.add(
+                PedidoProductoTopping(
+                  idCategoria: categoriaId,
+                  idTopping: toppingId,
+                ),
+              );
+            }
+          }
+        }
+      } else {
+        print(
+            "Añadiendo nuevo producto: ID ${item.producto.id}, cantidad: ${item.cantidad}");
+        PedidoProducto nuevoProducto = PedidoProducto(
+          idProducto: item.producto.id,
+          producto: item.producto,
+          costoUnitario: item.producto.precio.toString(),
+          descuento: item.producto.descuento?.toString() ?? '0',
+          cantidad: item.cantidad,
+          sincronizado: null,
+          toppings: item.selectedToppings.entries.expand((entry) {
+            return entry.value.map((toppingId) {
+              return PedidoProductoTopping(
+                idCategoria: entry.key,
+                idTopping: toppingId,
+              );
+            });
+          }).toList(),
+        );
+
+        pedidoActual!.productos.add(nuevoProducto);
+      }
+    }
+
+    print("Productos finales antes de guardar:");
+    pedidoActual!.productos.forEach((producto) {
+      print(
+          "Producto ID: ${producto.idProducto}, Cantidad: ${producto.cantidad}, Costo: ${producto.costoUnitario}");
+    });
+
+    bool result = await Provider.of<PedidoViewModel>(context, listen: false)
+        .guardarPedidoLocal(pedido: pedidoActual!);
+
+    if (result) {
+      print("Pedido actualizado correctamente: ID ${pedidoActual!.id}");
+      Navigator.of(context).pop();
+    } else {
+      print('Error al actualizar el pedido');
+    }
+  }
+
   Future<void> _promptForCustomerName() async {
     TextEditingController nombreController = TextEditingController();
     TextEditingController comentarioController = TextEditingController();
@@ -1047,15 +1365,48 @@ class _PedidoFormState extends State<PedidoForm> {
           const SizedBox(height: 25),
           Padding(
             padding: const EdgeInsets.all(8.0),
-            child: ElevatedButton(
-              onPressed: _finalizeOrder,
-              style: ElevatedButton.styleFrom(
-                backgroundColor: AppTheme.tertiary,
-                textStyle: const TextStyle(fontSize: 22),
-                fixedSize: const Size(250, 50),
-              ),
-              child: Text('Finalizar Pedido',
-                  style: TextStyle(color: AppTheme.quaternary)),
+            child: Column(
+              children: [
+                if (pedidoActual != null && pedidoActual!.id! > 0) ...[
+                  ElevatedButton(
+                    onPressed: () => _guardarPedidoExistente(),
+                    style: ElevatedButton.styleFrom(
+                      backgroundColor: AppTheme.tertiary,
+                      textStyle: const TextStyle(fontSize: 22),
+                      fixedSize: const Size(250, 50),
+                    ),
+                    child: Text(
+                      'Actualizar Pedido',
+                      style: TextStyle(color: AppTheme.quaternary),
+                    ),
+                  ),
+                  const SizedBox(height: 10),
+                  ElevatedButton(
+                    onPressed: () => _promptForCustomerName(),
+                    style: ElevatedButton.styleFrom(
+                      backgroundColor: Colors.green,
+                      textStyle: const TextStyle(fontSize: 22),
+                      fixedSize: const Size(250, 50),
+                    ),
+                    child: Text(
+                      'Finalizar Pedido',
+                      style: TextStyle(color: Colors.white),
+                    ),
+                  ),
+                ] else
+                  ElevatedButton(
+                    onPressed: () => _crearPedidoConModal(),
+                    style: ElevatedButton.styleFrom(
+                      backgroundColor: AppTheme.tertiary,
+                      textStyle: const TextStyle(fontSize: 22),
+                      fixedSize: const Size(250, 50),
+                    ),
+                    child: Text(
+                      'Crear Pedido',
+                      style: TextStyle(color: AppTheme.quaternary),
+                    ),
+                  ),
+              ],
             ),
           ),
         ],

+ 18 - 6
lib/views/pedido/pedido_screen.dart

@@ -78,13 +78,25 @@ class _PedidoScreenState extends State<PedidoScreen> {
     Pedido? pedidoCompleto =
         await Provider.of<PedidoViewModel>(context, listen: false)
             .fetchPedidoConProductos(item.id);
+
     if (pedidoCompleto != null) {
-      Navigator.push(
-        context,
-        MaterialPageRoute(
-          builder: (context) => PedidoDetalleScreen(pedido: pedidoCompleto),
-        ),
-      );
+      if (pedidoCompleto.estatus == 'TERMINADO') {
+        Navigator.push(
+          context,
+          MaterialPageRoute(
+            builder: (context) => PedidoDetalleScreen(pedido: pedidoCompleto),
+          ),
+        );
+      } else {
+        Navigator.push(
+          context,
+          MaterialPageRoute(
+            builder: (context) => PedidoForm(
+              pedidoExistente: pedidoCompleto,
+            ),
+          ),
+        );
+      }
     } else {
       print("Error al cargar el pedido con productos");
     }

+ 1 - 1
lib/views/perfil/perfil_screen.dart

@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/widgets/widgets.dart';
+import '/widgets/widgets.dart';
 import 'package:provider/provider.dart';
 import '../../themes/themes.dart';
 import '../../viewmodels/viewmodels.dart';

+ 1 - 2
lib/views/producto/producto_form.dart

@@ -22,8 +22,7 @@ class ProductoForm extends StatefulWidget {
 class Formulario extends State<ProductoForm> {
   final _nombre = TextEditingController();
   final _descripcion = TextEditingController();
-  final _precio =
-      TextEditingController(); // Mantén esto como String pero conviértelo a `double` más adelante
+  final _precio = TextEditingController();
   final _existencia = TextEditingController();
   final _descuento = TextEditingController();
   final _busquedaCategoria = TextEditingController();

+ 2 - 2
lib/views/toping/toping_form.dart

@@ -3,8 +3,8 @@
 import 'package:camera/camera.dart';
 import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/views/home/home_screen.dart';
-import 'package:yoshi_papas_app/widgets/widgets.dart';
+import '/views/home/home_screen.dart';
+import '/widgets/widgets.dart';
 import 'package:provider/provider.dart';
 
 import '../../models/models.dart';

+ 2 - 2
lib/views/toping_categoria/toping_categoria_form.dart

@@ -3,8 +3,8 @@
 import 'package:camera/camera.dart';
 import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/views/home/home_screen.dart';
-import 'package:yoshi_papas_app/widgets/widgets.dart';
+import '/views/home/home_screen.dart';
+import '/widgets/widgets.dart';
 import 'package:provider/provider.dart';
 
 import '../../models/models.dart';

+ 20 - 7
lib/widgets/app_drawer.dart

@@ -1,12 +1,13 @@
 // ignore_for_file: must_be_immutable
 
 import 'package:flutter/material.dart';
-import 'package:yoshi_papas_app/views/categoria_producto/categoria_producto_screen.dart';
-import 'package:yoshi_papas_app/views/pedido/pedido_screen.dart';
-import 'package:yoshi_papas_app/views/producto/producto_screen.dart';
-import 'package:yoshi_papas_app/views/sucursal/sucursal_screen.dart';
-import 'package:yoshi_papas_app/views/variable/variable_screen.dart';
-import 'package:yoshi_papas_app/views/venta/venta_screen.dart';
+import '/views/categoria_producto/categoria_producto_screen.dart';
+import '/views/mesa/mesa_screen.dart';
+import '/views/pedido/pedido_screen.dart';
+import '/views/producto/producto_screen.dart';
+import '/views/sucursal/sucursal_screen.dart';
+import '/views/variable/variable_screen.dart';
+import '/views/venta/venta_screen.dart';
 import 'package:provider/provider.dart';
 import '../models/models.dart';
 import '../services/services.dart';
@@ -181,6 +182,18 @@ class AppDrawer extends StatelessWidget {
                           ),
                         },
                       ),
+                      ListTile(
+                        leading: circulo(const Icon(Icons.table_bar)),
+                        title: const Text('Mesas'),
+                        onTap: () => {
+                          Navigator.pop(context),
+                          Navigator.of(context).push(
+                            MaterialPageRoute(
+                              builder: (context) => MesasScreen(),
+                            ),
+                          ),
+                        },
+                      ),
                       if (userPermisos.contains(Usuario.VER_SUCURSALES))
                         ListTile(
                           leading:
@@ -329,7 +342,7 @@ class AppDrawer extends StatelessWidget {
             child: Align(
               alignment: Alignment.bottomCenter,
               child: Text(
-                '$prefijoVersion.1.24.11.13',
+                '$prefijoVersion.1.24.11.22',
                 style: const TextStyle(fontWeight: FontWeight.w300),
               ),
             ),

+ 2 - 2
linux/CMakeLists.txt

@@ -4,10 +4,10 @@ project(runner LANGUAGES CXX)
 
 # The name of the executable created for the application. Change this to change
 # the on-disk name of your application.
-set(BINARY_NAME "yoshi_papas_app")
+set(BINARY_NAME "turquessa_app")
 # The unique GTK application identifier for this application. See:
 # https://wiki.gnome.org/HowDoI/ChooseApplicationID
-set(APPLICATION_ID "com.example.yoshi_papas_app")
+set(APPLICATION_ID "com.example.turquessa_app")
 
 # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
 # versions of CMake.

+ 2 - 2
linux/my_application.cc

@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
   if (use_header_bar) {
     GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
     gtk_widget_show(GTK_WIDGET(header_bar));
-    gtk_header_bar_set_title(header_bar, "yoshi_papas_app");
+    gtk_header_bar_set_title(header_bar, "turquessa_app");
     gtk_header_bar_set_show_close_button(header_bar, TRUE);
     gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
   } else {
-    gtk_window_set_title(window, "yoshi_papas_app");
+    gtk_window_set_title(window, "turquessa_app");
   }
 
   gtk_window_set_default_size(window, 1280, 720);

+ 6 - 6
macos/Runner.xcodeproj/project.pbxproj

@@ -64,7 +64,7 @@
 		331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
 		333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
 		335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
-		33CC10ED2044A3C60003C045 /* yoshi_papas_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "yoshi_papas_app.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+		33CC10ED2044A3C60003C045 /* turquessa_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "turquessa_app.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
 		33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@@ -131,7 +131,7 @@
 		33CC10EE2044A3C60003C045 /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				33CC10ED2044A3C60003C045 /* yoshi_papas_app.app */,
+				33CC10ED2044A3C60003C045 /* turquessa_app.app */,
 				331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
 			);
 			name = Products;
@@ -217,7 +217,7 @@
 			);
 			name = Runner;
 			productName = Runner;
-			productReference = 33CC10ED2044A3C60003C045 /* yoshi_papas_app.app */;
+			productReference = 33CC10ED2044A3C60003C045 /* turquessa_app.app */;
 			productType = "com.apple.product-type.application";
 		};
 /* End PBXNativeTarget section */
@@ -387,7 +387,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.yoshiPapasApp.RunnerTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_VERSION = 5.0;
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/yoshi_papas_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/yoshi_papas_app";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/turquessa_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/turquessa_app";
 			};
 			name = Debug;
 		};
@@ -401,7 +401,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.yoshiPapasApp.RunnerTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_VERSION = 5.0;
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/yoshi_papas_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/yoshi_papas_app";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/turquessa_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/turquessa_app";
 			};
 			name = Release;
 		};
@@ -415,7 +415,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = com.example.yoshiPapasApp.RunnerTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_VERSION = 5.0;
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/yoshi_papas_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/yoshi_papas_app";
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/turquessa_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/turquessa_app";
 			};
 			name = Profile;
 		};

+ 4 - 4
macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -15,7 +15,7 @@
             <BuildableReference
                BuildableIdentifier = "primary"
                BlueprintIdentifier = "33CC10EC2044A3C60003C045"
-               BuildableName = "yoshi_papas_app.app"
+               BuildableName = "turquessa_app.app"
                BlueprintName = "Runner"
                ReferencedContainer = "container:Runner.xcodeproj">
             </BuildableReference>
@@ -31,7 +31,7 @@
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "33CC10EC2044A3C60003C045"
-            BuildableName = "yoshi_papas_app.app"
+            BuildableName = "turquessa_app.app"
             BlueprintName = "Runner"
             ReferencedContainer = "container:Runner.xcodeproj">
          </BuildableReference>
@@ -65,7 +65,7 @@
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "33CC10EC2044A3C60003C045"
-            BuildableName = "yoshi_papas_app.app"
+            BuildableName = "turquessa_app.app"
             BlueprintName = "Runner"
             ReferencedContainer = "container:Runner.xcodeproj">
          </BuildableReference>
@@ -82,7 +82,7 @@
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "33CC10EC2044A3C60003C045"
-            BuildableName = "yoshi_papas_app.app"
+            BuildableName = "turquessa_app.app"
             BlueprintName = "Runner"
             ReferencedContainer = "container:Runner.xcodeproj">
          </BuildableReference>

BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png


+ 1 - 1
macos/Runner/Configs/AppInfo.xcconfig

@@ -5,7 +5,7 @@
 // 'flutter create' template.
 
 // The application's name. By default this is also the title of the Flutter window.
-PRODUCT_NAME = yoshi_papas_app
+PRODUCT_NAME = turquessa_app
 
 // The application's bundle identifier
 PRODUCT_BUNDLE_IDENTIFIER = com.example.yoshiPapasApp

+ 7 - 8
pubspec.yaml

@@ -1,4 +1,4 @@
-name: yoshi_papas_app
+name: turquessa_app
 description: "A new Flutter project."
 # The following line prevents the package from being accidentally published to
 # pub.dev using `flutter pub publish`. This is preferred for private packages.
@@ -72,18 +72,18 @@ dev_dependencies:
 flutter_launcher_icons:
     android: "launcher_icon"
     ios: true
-    image_path: "assets/JoshiLogo.png"
+    image_path: "assets/logo.png"
     min_sdk_android: 21 # android min sdk min:16, default 21
     web:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"
     windows:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"
       icon_size: 256
     macos:
       generate: true
-      image_path: "assets/JoshiLogo.png"
+      image_path: "assets/logo.png"
 
   # The "flutter_lints" package below contains a set of recommended lints to
   # encourage good coding practices. The lint set provided by the package is
@@ -105,9 +105,8 @@ flutter:
 
   # To add assets to your application, add an assets section, like this:
   assets:
-    - assets/JoshiLogoHorizontal.png
-    - assets/JoshiLogo.png
-    - assets/JoshiLogo-BN.png
+    - assets/logo.png
+    - assets/logo-BN.png
 
   # An image asset can refer to one or more resolution-specific "variants", see
   # https://flutter.dev/assets-and-images/#resolution-aware

+ 1 - 1
test/widget_test.dart

@@ -8,7 +8,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 
-import 'package:yoshi_papas_app/main.dart';
+import 'package:turquessa_app/main.dart';
 
 void main() {
   testWidgets('Counter increments smoke test', (WidgetTester tester) async {

BIN
web/favicon.png


BIN
web/icons/Icon-192.png


BIN
web/icons/Icon-512.png


BIN
web/icons/Icon-maskable-192.png


BIN
web/icons/Icon-maskable-512.png


+ 2 - 2
web/index.html

@@ -23,13 +23,13 @@
   <!-- iOS meta tags & icons -->
   <meta name="apple-mobile-web-app-capable" content="yes">
   <meta name="apple-mobile-web-app-status-bar-style" content="black">
-  <meta name="apple-mobile-web-app-title" content="yoshi_papas_app">
+  <meta name="apple-mobile-web-app-title" content="turquessa_app">
   <link rel="apple-touch-icon" href="icons/Icon-192.png">
 
   <!-- Favicon -->
   <link rel="icon" type="image/png" href="favicon.png"/>
 
-  <title>yoshi_papas_app</title>
+  <title>turquessa_app</title>
   <link rel="manifest" href="manifest.json">
 
   <script>

+ 2 - 2
web/manifest.json

@@ -1,6 +1,6 @@
 {
-    "name": "yoshi_papas_app",
-    "short_name": "yoshi_papas_app",
+    "name": "turquessa_app",
+    "short_name": "turquessa_app",
     "start_url": ".",
     "display": "standalone",
     "background_color": "#0175C2",

+ 0 - 0
windows/CMakeLists.txt


Some files were not shown because too many files changed in this diff