coregen-cli 3.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coregen.py +1585 -0
- coregen_cli-3.1.6.dist-info/METADATA +1211 -0
- coregen_cli-3.1.6.dist-info/RECORD +172 -0
- coregen_cli-3.1.6.dist-info/WHEEL +5 -0
- coregen_cli-3.1.6.dist-info/entry_points.txt +2 -0
- coregen_cli-3.1.6.dist-info/top_level.txt +2 -0
- generators/__init__.py +1 -0
- generators/assets/__init__.py +1 -0
- generators/assets/assets.py +30 -0
- generators/assets/main.py +4 -0
- generators/config/__init__.py +1 -0
- generators/config/analisy_options.py +42 -0
- generators/config/main.py +11 -0
- generators/config/pubspec.py +139 -0
- generators/cursor/__init__.py +3 -0
- generators/cursor/setup.py +87 -0
- generators/helpers/__init__.py +56 -0
- generators/helpers/component.py +1030 -0
- generators/helpers/config.py +255 -0
- generators/helpers/data_source.py +180 -0
- generators/helpers/domain.py +469 -0
- generators/helpers/feature.py +654 -0
- generators/helpers/navigation.py +274 -0
- generators/helpers/page.py +63 -0
- generators/helpers/project.py +33 -0
- generators/helpers/utils.py +338 -0
- generators/helpers/validation.py +364 -0
- generators/initializator.py +68 -0
- generators/main.py +81 -0
- generators/static/assets/logo.png +0 -0
- generators/static/assets/mock/auth_user.json +5 -0
- generators/static/assets/svgs/apple.svg +4 -0
- generators/static/assets/svgs/google.svg +2 -0
- generators/static/cursor/AGENTS.md.jinja +37 -0
- generators/static/cursor/agents/doc-writer.md +20 -0
- generators/static/cursor/agents/epic-orchestrator.md +28 -0
- generators/static/cursor/agents/feature-implementer.md +29 -0
- generators/static/cursor/agents/integration-wiring.md +30 -0
- generators/static/cursor/agents/layer-application.md +21 -0
- generators/static/cursor/agents/layer-guardian.md +21 -0
- generators/static/cursor/agents/layer-infrastructure.md +31 -0
- generators/static/cursor/agents/layer-model.md +24 -0
- generators/static/cursor/agents/layer-presentation.md +33 -0
- generators/static/cursor/docs/architecture/APIS_AND_INTEGRATION.md.jinja +42 -0
- generators/static/cursor/docs/architecture/CARAVAGGIO_COMPONENTS.md.jinja +317 -0
- generators/static/cursor/docs/architecture/DDD_LAYERS.md.jinja +32 -0
- generators/static/cursor/docs/architecture/FILE_TEMPLATES.md.jinja +76 -0
- generators/static/cursor/docs/architecture/MOCK_AND_REMOTE_DATA.md.jinja +87 -0
- generators/static/cursor/docs/architecture/REFERENCE_IMPLEMENTATIONS.md.jinja +48 -0
- generators/static/cursor/docs/architecture/WIDGETS_AND_CARAVAGGIO.md.jinja +76 -0
- generators/static/cursor/docs/epics/README.md +17 -0
- generators/static/cursor/lib/domain/AGENTS.md +23 -0
- generators/static/cursor/lib/features/AGENTS.md +23 -0
- generators/static/cursor/lib/widgets/AGENTS.md +21 -0
- generators/static/cursor/rules/apis-layer.mdc.jinja +21 -0
- generators/static/cursor/rules/application-layer.mdc.jinja +12 -0
- generators/static/cursor/rules/architecture-core.mdc.jinja +43 -0
- generators/static/cursor/rules/dart-conventions.mdc.jinja +14 -0
- generators/static/cursor/rules/domain-layer.mdc.jinja +24 -0
- generators/static/cursor/rules/login-context.mdc.jinja +16 -0
- generators/static/cursor/rules/presentation-layer.mdc.jinja +15 -0
- generators/static/cursor/rules/quality-gate.mdc.jinja +14 -0
- generators/static/cursor/rules/ui-caravaggio.mdc.jinja +22 -0
- generators/static/cursor/skills/caravaggio-ui/SKILL.md +138 -0
- generators/static/cursor/skills/epic-delivery/SKILL.md +74 -0
- generators/static/cursor/skills/epic-delivery/templates/epic-status.md +14 -0
- generators/static/cursor/skills/epic-delivery/templates/epic.md +36 -0
- generators/static/templates/apis/common/constants_template.jinja +48 -0
- generators/static/templates/apis/common/data_source_config_template.jinja +47 -0
- generators/static/templates/apis/core/api_injectable_module_template.jinja +14 -0
- generators/static/templates/apis/interceptors/api_logger_template.jinja +135 -0
- generators/static/templates/apis/interceptors/auth_interceptor_template.jinja +207 -0
- generators/static/templates/auth/application/auth_bloc_template.jinja +36 -0
- generators/static/templates/auth/application/auth_event_template.jinja +7 -0
- generators/static/templates/auth/application/auth_state_template.jinja +8 -0
- generators/static/templates/auth/infrastructure/auth_facade_module_template.jinja +16 -0
- generators/static/templates/auth/infrastructure/auth_facade_template.jinja +288 -0
- generators/static/templates/auth/infrastructure/mock_auth_facade_template.jinja +106 -0
- generators/static/templates/auth/model/auth_failure_template.jinja +11 -0
- generators/static/templates/auth/model/i_auth_facade_template.jinja +24 -0
- generators/static/templates/auth/model/user_template.jinja +34 -0
- generators/static/templates/auth/model/value_objects_template.jinja +54 -0
- generators/static/templates/auth/presentation/login_screen_template.jinja +24 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_bloc_template.jinja +139 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_event_template.jinja +15 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_state_template.jinja +26 -0
- generators/static/templates/auth/sign_in_form/presentation/apple_form_template.jinja +16 -0
- generators/static/templates/auth/sign_in_form/presentation/email_password_form_template_INACTIVE.jinja +94 -0
- generators/static/templates/auth/sign_in_form/presentation/google_form_template.jinja +15 -0
- generators/static/templates/auth/sign_in_form/presentation/sign_in_form_template.jinja +381 -0
- generators/static/templates/component/component_bloc_template.jinja +49 -0
- generators/static/templates/component/component_event_template.jinja +7 -0
- generators/static/templates/component/component_form_bloc_template.jinja +56 -0
- generators/static/templates/component/component_form_event_template.jinja +7 -0
- generators/static/templates/component/component_form_state_template.jinja +18 -0
- generators/static/templates/component/component_form_widget_template.jinja +130 -0
- generators/static/templates/component/component_list_widget_template.jinja +95 -0
- generators/static/templates/component/component_state_template.jinja +9 -0
- generators/static/templates/component/component_widget_template.jinja +113 -0
- generators/static/templates/core/bloc/base_form_bloc_template.jinja +32 -0
- generators/static/templates/core/errors/error_localizer_template.jinja +61 -0
- generators/static/templates/core/infrastructure/base_mapper_template.jinja +21 -0
- generators/static/templates/core/infrastructure/base_repository_mixin_template.jinja +78 -0
- generators/static/templates/core/infrastructure/firebase_injectable_module_template.jinja +11 -0
- generators/static/templates/core/infrastructure/firestore_helpers_template.jinja +22 -0
- generators/static/templates/core/infrastructure/repository_error_handler_template.jinja +44 -0
- generators/static/templates/core/model/common_interfaces_template.jinja +3 -0
- generators/static/templates/core/model/entity_template.jinja +5 -0
- generators/static/templates/core/model/errors_template.jinja +15 -0
- generators/static/templates/core/model/failures_template.jinja +97 -0
- generators/static/templates/core/model/value_objects_template.jinja +135 -0
- generators/static/templates/core/model/value_validators_template.jinja +105 -0
- generators/static/templates/core/presentation/app_drawer_template.jinja +52 -0
- generators/static/templates/core/presentation/app_widget_template.jinja +41 -0
- generators/static/templates/core/presentation/bottom_nav_bar_template.jinja +32 -0
- generators/static/templates/domain/domain_mapper_template.jinja +39 -0
- generators/static/templates/domain/domain_remote_service_template.jinja +46 -0
- generators/static/templates/domain/domain_repository_template.jinja +90 -0
- generators/static/templates/domain/domain_service_module_template.jinja +23 -0
- generators/static/templates/domain/enum_template.jinja +3 -0
- generators/static/templates/domain/i_domain_service_template.jinja +18 -0
- generators/static/templates/domain/mock_domain_service_template.jinja +73 -0
- generators/static/templates/feature/feature_bloc_template.jinja +104 -0
- generators/static/templates/feature/feature_dto_template.jinja +26 -0
- generators/static/templates/feature/feature_entity_template.jinja +23 -0
- generators/static/templates/feature/feature_event_template.jinja +20 -0
- generators/static/templates/feature/feature_extensions_template.jinja +25 -0
- generators/static/templates/feature/feature_failure_template.jinja +11 -0
- generators/static/templates/feature/feature_page_template.jinja +113 -0
- generators/static/templates/feature/feature_repository_template.jinja +112 -0
- generators/static/templates/feature/feature_state_template.jinja +20 -0
- generators/static/templates/feature/i_feature_repository_template.jinja +21 -0
- generators/static/templates/feature/value_object_field_template.jinja +0 -0
- generators/static/templates/feature/value_object_template.jinja +0 -0
- generators/static/templates/feature/value_validators_template.jinja +57 -0
- generators/static/templates/home/home_screen_template.jinja +68 -0
- generators/static/templates/home/presentation/home_screen_template.jinja +52 -0
- generators/static/templates/home/screen_template.jinja +12 -0
- generators/static/templates/injection_template.jinja +8 -0
- generators/static/templates/logging/analytics_logging_template.jinja +42 -0
- generators/static/templates/logging/console_template.jinja +50 -0
- generators/static/templates/logging/logger_injectable_module_template.jinja +24 -0
- generators/static/templates/logging/logger_template.jinja +118 -0
- generators/static/templates/main_template.jinja +43 -0
- generators/static/templates/page_template.jinja +29 -0
- generators/static/templates/router_template.jinja +26 -0
- generators/static/templates/splash/presentation/splash_screen_auth_template.jinja +97 -0
- generators/static/templates/splash/presentation/splash_screen_template.jinja +51 -0
- generators/static/templates/storage/storage_repository_template.jinja +80 -0
- generators/static/templates/user_profile/infrastructure/user_profile_dto_template.jinja +27 -0
- generators/static/templates/user_profile/infrastructure/user_profile_mapper_template.jinja +43 -0
- generators/static/templates/user_profile/infrastructure/user_profile_repository_template.jinja +82 -0
- generators/static/templates/user_profile/infrastructure/user_profile_service_template.jinja +27 -0
- generators/static/templates/user_profile/model/i_user_profile_repository_template.jinja +34 -0
- generators/static/templates/user_profile/model/user_profile_failure_template.jinja +11 -0
- generators/static/templates/user_profile/model/user_profile_template.jinja +31 -0
- generators/static/templates/widgets/common/custom_scaffold_template.jinja +52 -0
- generators/static/templates/widgets/common/error_widget_template.jinja +22 -0
- generators/static/templates/widgets/common/loading_widget_template.jinja +14 -0
- generators/static/templates/widgets/common/unknown_state_widget_template.jinja +23 -0
- generators/templates/__init__.py +1 -0
- generators/templates/_core/core_generator.py +121 -0
- generators/templates/apis/apis_generator.py +50 -0
- generators/templates/auth/auth_generator.py +40 -0
- generators/templates/auth/sign_in_form_generator.py +22 -0
- generators/templates/copier.py +51 -0
- generators/templates/home/home_generator.py +26 -0
- generators/templates/lib/lib_generator.py +40 -0
- generators/templates/logging/logging_generator.py +28 -0
- generators/templates/main.py +75 -0
- generators/templates/splash/splash_generator.py +20 -0
- generators/templates/storage/storage_generator.py +5 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"""Navigation functions (drawer and bottom navigation)"""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from generators.templates.copier import generate_file
|
|
6
|
+
from .project import get_project_name
|
|
7
|
+
from .page import generate_page_file, update_router
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def create_drawer_page(project_dir: Path, drawer_item_name: str, project_name: str) -> None:
|
|
11
|
+
"""Create a page for the drawer item"""
|
|
12
|
+
lib_path = project_dir / "lib"
|
|
13
|
+
|
|
14
|
+
# Create page directory structure
|
|
15
|
+
page_dir = lib_path / drawer_item_name
|
|
16
|
+
page_dir.mkdir(exist_ok=True)
|
|
17
|
+
|
|
18
|
+
# Create presentation layer
|
|
19
|
+
presentation_dir = page_dir / "presentation"
|
|
20
|
+
presentation_dir.mkdir(exist_ok=True)
|
|
21
|
+
|
|
22
|
+
# Generate page file
|
|
23
|
+
generate_page_file(drawer_item_name, presentation_dir, project_name)
|
|
24
|
+
|
|
25
|
+
# Update router
|
|
26
|
+
update_router(project_dir, drawer_item_name, project_name)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def update_home_page_with_drawer(project_dir: Path, project_name: str) -> None:
|
|
30
|
+
"""Update the home screen to include a drawer"""
|
|
31
|
+
home_page_path = project_dir / "lib" / "features" / "home" / "home_page.dart"
|
|
32
|
+
|
|
33
|
+
if not home_page_path.exists():
|
|
34
|
+
click.echo("⚠️ Home screen not found, creating basic drawer implementation")
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
content = home_page_path.read_text()
|
|
38
|
+
|
|
39
|
+
# Check if drawer is already implemented
|
|
40
|
+
if "drawer:" in content:
|
|
41
|
+
click.echo("ℹ️ Drawer already exists in home screen")
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
# Add drawer import if not present
|
|
45
|
+
drawer_import = f"import 'package:{project_name}/core/presentation/app_drawer.dart';"
|
|
46
|
+
if drawer_import not in content:
|
|
47
|
+
# Add import after existing imports
|
|
48
|
+
lines = content.split('\n')
|
|
49
|
+
insert_index = 0
|
|
50
|
+
for i, line in enumerate(lines):
|
|
51
|
+
if line.startswith('import'):
|
|
52
|
+
insert_index = i + 1
|
|
53
|
+
elif line.strip() and not line.startswith('//'):
|
|
54
|
+
break
|
|
55
|
+
|
|
56
|
+
lines.insert(insert_index, drawer_import)
|
|
57
|
+
content = '\n'.join(lines)
|
|
58
|
+
|
|
59
|
+
# Modify the Scaffold to include drawer
|
|
60
|
+
if "return const Scaffold(" in content:
|
|
61
|
+
content = content.replace(
|
|
62
|
+
"return const Scaffold(",
|
|
63
|
+
"return Scaffold(\n drawer: const AppDrawer(),"
|
|
64
|
+
)
|
|
65
|
+
elif "return Scaffold(" in content:
|
|
66
|
+
if "drawer:" not in content:
|
|
67
|
+
content = content.replace(
|
|
68
|
+
"return Scaffold(",
|
|
69
|
+
"return Scaffold(\n drawer: const AppDrawer(),"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
home_page_path.write_text(content)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def create_drawer_widget(project_dir: Path, drawer_item_name: str, project_name: str) -> None:
|
|
76
|
+
"""Create or update the drawer widget using Jinja template"""
|
|
77
|
+
core_presentation_dir = project_dir / "lib" / "core" / "presentation"
|
|
78
|
+
core_presentation_dir.mkdir(parents=True, exist_ok=True)
|
|
79
|
+
|
|
80
|
+
drawer_path = core_presentation_dir / "app_drawer.dart"
|
|
81
|
+
|
|
82
|
+
# Get all drawer items
|
|
83
|
+
drawer_items = []
|
|
84
|
+
|
|
85
|
+
if drawer_path.exists():
|
|
86
|
+
content = drawer_path.read_text()
|
|
87
|
+
lines = content.split('\n')
|
|
88
|
+
|
|
89
|
+
for line in lines:
|
|
90
|
+
if f'package:{project_name}/' in line and '_page.dart' in line:
|
|
91
|
+
import_match = line.strip()
|
|
92
|
+
if import_match.startswith("import 'package:") and import_match.endswith("_page.dart';"):
|
|
93
|
+
start = import_match.find(f'package:{project_name}/') + len(f'package:{project_name}/')
|
|
94
|
+
end = import_match.find('/presentation/', start)
|
|
95
|
+
if start != -1 and end != -1:
|
|
96
|
+
existing_item = import_match[start:end]
|
|
97
|
+
if existing_item != 'home':
|
|
98
|
+
drawer_items.append({"name": existing_item})
|
|
99
|
+
|
|
100
|
+
if not any(item["name"] == drawer_item_name for item in drawer_items):
|
|
101
|
+
drawer_items.append({"name": drawer_item_name})
|
|
102
|
+
|
|
103
|
+
generate_file(project_name, core_presentation_dir, "core/presentation/app_drawer_template.jinja", "app_drawer.dart", {
|
|
104
|
+
"project_name": project_name,
|
|
105
|
+
"drawer_items": drawer_items
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def update_router_for_drawer_item(project_dir: Path, drawer_item_name: str) -> None:
|
|
110
|
+
"""Update router to include the drawer item route if needed"""
|
|
111
|
+
router_path = project_dir / "lib" / "router.dart"
|
|
112
|
+
|
|
113
|
+
if not router_path.exists():
|
|
114
|
+
click.echo("⚠️ router.dart not found, skipping router update")
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
content = router_path.read_text()
|
|
118
|
+
|
|
119
|
+
route_pattern = f"path: '/{drawer_item_name}'"
|
|
120
|
+
if route_pattern in content:
|
|
121
|
+
click.echo("ℹ️ Route already exists in router")
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
route_line = f"""GoRoute(
|
|
125
|
+
path: '/{drawer_item_name}',
|
|
126
|
+
builder: (BuildContext context, GoRouterState state) => const Placeholder(),
|
|
127
|
+
),"""
|
|
128
|
+
|
|
129
|
+
if route_line not in content:
|
|
130
|
+
if 'routes: <RouteBase>[' in content:
|
|
131
|
+
content = content.replace(' ],', f' {route_line}\n ],')
|
|
132
|
+
elif 'routes: [' in content:
|
|
133
|
+
content = content.replace(' ],', f' {route_line}\n ],')
|
|
134
|
+
else:
|
|
135
|
+
click.echo("⚠️ Could not find routes list in router.dart")
|
|
136
|
+
|
|
137
|
+
router_path.write_text(content)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def create_bottom_nav_page(project_dir: Path, bottom_nav_item_name: str) -> None:
|
|
141
|
+
"""Create a screen for the bottom nav item in features/home using Jinja template"""
|
|
142
|
+
home_dir = project_dir / "lib" / "features" / "home"
|
|
143
|
+
home_dir.mkdir(parents=True, exist_ok=True)
|
|
144
|
+
|
|
145
|
+
project_name = get_project_name(project_dir)
|
|
146
|
+
|
|
147
|
+
generate_file(project_name, home_dir, "home/screen_template.jinja", f"{bottom_nav_item_name}_screen.dart", {
|
|
148
|
+
"screen_name": bottom_nav_item_name.capitalize(),
|
|
149
|
+
"screen_title": bottom_nav_item_name.replace("_", " ").capitalize()
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def update_home_page_with_bottom_nav(project_dir: Path, bottom_nav_item_name: str, project_name: str) -> None:
|
|
154
|
+
"""Update the home screen to include bottom navigation"""
|
|
155
|
+
home_page_path = project_dir / "lib" / "features" / "home" / "home_page.dart"
|
|
156
|
+
|
|
157
|
+
if not home_page_path.exists():
|
|
158
|
+
click.echo("⚠️ Home screen not found, creating basic bottom nav implementation")
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
content = home_page_path.read_text()
|
|
162
|
+
|
|
163
|
+
if "BottomNavigationBar" in content or "BottomNavBar" in content:
|
|
164
|
+
class_name = bottom_nav_item_name.capitalize() + 'Screen'
|
|
165
|
+
|
|
166
|
+
screen_import = f"import 'package:{project_name}/features/home/{bottom_nav_item_name}_screen.dart';"
|
|
167
|
+
if screen_import not in content:
|
|
168
|
+
lines = content.split('\n')
|
|
169
|
+
insert_index = 0
|
|
170
|
+
for i, line in enumerate(lines):
|
|
171
|
+
if line.startswith('import'):
|
|
172
|
+
insert_index = i + 1
|
|
173
|
+
elif line.strip() and not line.startswith('//'):
|
|
174
|
+
break
|
|
175
|
+
|
|
176
|
+
lines.insert(insert_index, screen_import)
|
|
177
|
+
content = '\n'.join(lines)
|
|
178
|
+
|
|
179
|
+
lines = content.split('\n')
|
|
180
|
+
pages_list_start = -1
|
|
181
|
+
for i, line in enumerate(lines):
|
|
182
|
+
if 'final List<Widget> _pages = [' in line or '_pages = [' in line:
|
|
183
|
+
pages_list_start = i
|
|
184
|
+
break
|
|
185
|
+
|
|
186
|
+
if pages_list_start != -1:
|
|
187
|
+
bracket_count = 0
|
|
188
|
+
for j in range(pages_list_start, len(lines)):
|
|
189
|
+
bracket_count += lines[j].count('[')
|
|
190
|
+
bracket_count -= lines[j].count(']')
|
|
191
|
+
if bracket_count == 0 and '];' in lines[j]:
|
|
192
|
+
lines.insert(j, f' const {class_name}(),')
|
|
193
|
+
break
|
|
194
|
+
|
|
195
|
+
content = '\n'.join(lines)
|
|
196
|
+
else:
|
|
197
|
+
capitalized_name = bottom_nav_item_name.replace('_', ' ').title()
|
|
198
|
+
class_name = bottom_nav_item_name.capitalize() + 'Screen'
|
|
199
|
+
|
|
200
|
+
existing_content = home_page_path.read_text()
|
|
201
|
+
has_drawer = "drawer:" in existing_content
|
|
202
|
+
drawer_import_needed = "import 'package:" + project_name + "/core/presentation/app_drawer.dart';" in existing_content
|
|
203
|
+
|
|
204
|
+
imports = f"""import 'package:flutter/material.dart';
|
|
205
|
+
import 'package:{project_name}/core/presentation/bottom_nav_bar.dart';
|
|
206
|
+
import 'package:{project_name}/features/home/{bottom_nav_item_name}_screen.dart';"""
|
|
207
|
+
|
|
208
|
+
if drawer_import_needed:
|
|
209
|
+
imports += f"\nimport 'package:{project_name}/core/presentation/app_drawer.dart';"
|
|
210
|
+
|
|
211
|
+
drawer_line = ""
|
|
212
|
+
if has_drawer:
|
|
213
|
+
drawer_line = " drawer: const AppDrawer(),"
|
|
214
|
+
|
|
215
|
+
content = f"""{imports}
|
|
216
|
+
|
|
217
|
+
class HomePage extends StatefulWidget {{
|
|
218
|
+
static const String routeName = '/home';
|
|
219
|
+
|
|
220
|
+
const HomePage({{super.key}});
|
|
221
|
+
|
|
222
|
+
@override
|
|
223
|
+
State<HomePage> createState() => _HomePageState();
|
|
224
|
+
}}
|
|
225
|
+
|
|
226
|
+
class _HomePageState extends State<HomePage> {{
|
|
227
|
+
int _selectedIndex = 0;
|
|
228
|
+
|
|
229
|
+
final List<Widget> _pages = [
|
|
230
|
+
const Center(child: Text('Home Content')),
|
|
231
|
+
const {class_name}(),
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
void _onItemTapped(int index) {{
|
|
235
|
+
setState(() {{
|
|
236
|
+
_selectedIndex = index;
|
|
237
|
+
}});
|
|
238
|
+
}}
|
|
239
|
+
|
|
240
|
+
@override
|
|
241
|
+
Widget build(BuildContext context) {{
|
|
242
|
+
return Scaffold(
|
|
243
|
+
appBar: AppBar(
|
|
244
|
+
title: const Text('Home'),
|
|
245
|
+
),
|
|
246
|
+
{drawer_line}
|
|
247
|
+
body: _pages[_selectedIndex],
|
|
248
|
+
bottomNavigationBar: BottomNavBar(
|
|
249
|
+
currentIndex: _selectedIndex,
|
|
250
|
+
onTap: _onItemTapped,
|
|
251
|
+
),
|
|
252
|
+
);
|
|
253
|
+
}}
|
|
254
|
+
}}
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
home_page_path.write_text(content)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def create_bottom_nav_widget(project_dir: Path, bottom_nav_item_name: str) -> None:
|
|
261
|
+
"""Create or update the bottom navigation widget using Jinja template"""
|
|
262
|
+
core_presentation_dir = project_dir / "lib" / "core" / "presentation"
|
|
263
|
+
core_presentation_dir.mkdir(parents=True, exist_ok=True)
|
|
264
|
+
|
|
265
|
+
bottom_nav_path = core_presentation_dir / "bottom_nav_bar.dart"
|
|
266
|
+
|
|
267
|
+
project_name = project_dir.name
|
|
268
|
+
|
|
269
|
+
nav_items = [{"name": bottom_nav_item_name}]
|
|
270
|
+
|
|
271
|
+
generate_file(project_name, core_presentation_dir, "core/presentation/bottom_nav_bar_template.jinja", "bottom_nav_bar.dart", {
|
|
272
|
+
"nav_items": nav_items
|
|
273
|
+
})
|
|
274
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Page generation functions"""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from generators.templates.copier import generate_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def generate_page_file(page_name: str, presentation_dir: Path, project_name: str) -> None:
|
|
10
|
+
"""Generate a basic page file using Jinja template"""
|
|
11
|
+
generate_file(project_name, presentation_dir, "page_template.jinja", f"{page_name}_page.dart", {
|
|
12
|
+
"page_name": page_name
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def update_router(project_dir: Path, page_name: str, project_name: str, folder: Optional[str] = None) -> None:
|
|
17
|
+
"""Update the router.dart file to include the new page"""
|
|
18
|
+
router_path = project_dir / "lib" / "router.dart"
|
|
19
|
+
if not router_path.exists():
|
|
20
|
+
click.echo("⚠️ router.dart not found, skipping router update")
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
# Build the import path prefix
|
|
24
|
+
if folder:
|
|
25
|
+
import_prefix = f"{folder.replace('/', '/')}/{page_name}"
|
|
26
|
+
else:
|
|
27
|
+
import_prefix = page_name
|
|
28
|
+
|
|
29
|
+
# Read current router
|
|
30
|
+
content = router_path.read_text()
|
|
31
|
+
|
|
32
|
+
# Add import
|
|
33
|
+
import_line = f"import 'package:{project_name}/{import_prefix}/{page_name}_page.dart';"
|
|
34
|
+
if import_line not in content:
|
|
35
|
+
# Find where to insert import (after other imports)
|
|
36
|
+
lines = content.split('\n')
|
|
37
|
+
insert_index = 0
|
|
38
|
+
for i, line in enumerate(lines):
|
|
39
|
+
if line.startswith('import'):
|
|
40
|
+
insert_index = i + 1
|
|
41
|
+
elif line.strip() and not line.startswith('//'):
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
lines.insert(insert_index, import_line)
|
|
45
|
+
content = '\n'.join(lines)
|
|
46
|
+
|
|
47
|
+
# Add route
|
|
48
|
+
route_line = f"""GoRoute(
|
|
49
|
+
path: {page_name.capitalize()}Page.routeName,
|
|
50
|
+
builder: (BuildContext context, GoRouterState state) => const {page_name.capitalize()}Page(),
|
|
51
|
+
),"""
|
|
52
|
+
if route_line not in content:
|
|
53
|
+
# Find routes list and add the new route before the closing bracket
|
|
54
|
+
if 'routes: <RouteBase>[' in content:
|
|
55
|
+
# Replace the closing bracket with the new route + closing bracket
|
|
56
|
+
content = content.replace(' ],', f' {route_line}\n ],')
|
|
57
|
+
elif 'routes: [' in content:
|
|
58
|
+
content = content.replace(' ],', f' {route_line}\n ],')
|
|
59
|
+
else:
|
|
60
|
+
click.echo("⚠️ Could not find routes list in router.dart")
|
|
61
|
+
|
|
62
|
+
router_path.write_text(content)
|
|
63
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Project validation and utility functions"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
console = Console()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_project_name(project_dir: Path) -> str:
|
|
11
|
+
"""Extract project name from pubspec.yaml"""
|
|
12
|
+
pubspec_path = project_dir / "pubspec.yaml"
|
|
13
|
+
if pubspec_path.exists():
|
|
14
|
+
with open(pubspec_path, 'r') as f:
|
|
15
|
+
for line in f:
|
|
16
|
+
if line.strip().startswith('name:'):
|
|
17
|
+
return line.split(':', 1)[1].strip().strip('"').strip("'")
|
|
18
|
+
return project_dir.name
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def validate_flutter_project(project_dir: Path) -> tuple[Path, str]:
|
|
22
|
+
"""Validate Flutter project and return lib_path and project_name"""
|
|
23
|
+
if not (project_dir / "pubspec.yaml").exists():
|
|
24
|
+
console.print("[bold red]❌ Not a valid Flutter project. pubspec.yaml not found.[/bold red]")
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
lib_path = project_dir / "lib"
|
|
28
|
+
if not lib_path.exists():
|
|
29
|
+
console.print("[bold red]❌ lib directory not found.[/bold red]")
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
|
|
32
|
+
return lib_path, get_project_name(project_dir)
|
|
33
|
+
|