nextpy-framework 2.4.4__tar.gz → 2.4.6__tar.gz
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.
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/cli.py +135 -110
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/component_router.py +23 -15
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/router.py +23 -15
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/app.py +52 -13
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6/.nextpy_framework/nextpy_framework.egg-info}/PKG-INFO +1 -1
- {nextpy_framework-2.4.4/.nextpy_framework/nextpy_framework.egg-info → nextpy_framework-2.4.6}/PKG-INFO +1 -1
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/pyproject.toml +1 -1
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/auth.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/builder.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/debug/AutoDebug.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/debug/DebugIcon.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/debug/DebugIconFixed.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/feedback.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/form.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/head.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/hooks_provider.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/image.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/layout.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/link.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/loader.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/navigation.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/toast.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/ui.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/visual.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/config.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/builder.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/component_renderer.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/data_fetching.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/demo_pages_simple.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/demo_router.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/renderer.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/sync.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/db.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/dev_server.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/dev_tools.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/errors.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/hooks.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/hooks_provider.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/hooks_provider_new.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/jsx.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/jsx_preprocessor.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/jsx_transformer.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/main.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/performance.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/base.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/builtin.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/config.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/py.typed +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/security.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/debug.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/middleware.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/true_jsx.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/__init__.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/cache.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/email.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/file_upload.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/logging.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/search.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/seo.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/validators.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/websocket.py +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy_framework.egg-info/SOURCES.txt +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy_framework.egg-info/dependency_links.txt +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy_framework.egg-info/entry_points.txt +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy_framework.egg-info/requires.txt +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy_framework.egg-info/top_level.txt +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/LICENSE +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/README.md +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/setup.cfg +0 -0
- {nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/tests/test_routing.py +0 -0
|
@@ -196,7 +196,7 @@ def _format_size(size_bytes: int) -> str:
|
|
|
196
196
|
return f"{size:.1f} {size_names[i]}"
|
|
197
197
|
|
|
198
198
|
@click.group()
|
|
199
|
-
@click.version_option(version="
|
|
199
|
+
@click.version_option(version="2.4.4", prog_name="NextPy")
|
|
200
200
|
def cli():
|
|
201
201
|
"""NextPy - A Python web framework inspired by Next.js"""
|
|
202
202
|
pass
|
|
@@ -533,7 +533,7 @@ def version():
|
|
|
533
533
|
click.echo(click.style("\n 📋 NextPy Framework Info", fg="cyan", bold=True))
|
|
534
534
|
click.echo(click.style(" ===================\n", fg="cyan"))
|
|
535
535
|
|
|
536
|
-
click.echo(f" 🏷️ Version: 2.4.
|
|
536
|
+
click.echo(f" 🏷️ Version: 2.4.6 ")
|
|
537
537
|
click.echo(f" 🐍 Python: {sys.version.split()[0]}")
|
|
538
538
|
click.echo(f" ⚡ Framework: NextPy")
|
|
539
539
|
click.echo(f" 🎨 Architecture: True JSX")
|
|
@@ -561,7 +561,7 @@ def info():
|
|
|
561
561
|
|
|
562
562
|
# Framework info
|
|
563
563
|
click.echo(click.style(" 📦 Framework Details:", fg="blue", bold=True))
|
|
564
|
-
click.echo(f" Version: 2.
|
|
564
|
+
click.echo(f" Version: 2.4.4")
|
|
565
565
|
click.echo(f" Architecture: True JSX")
|
|
566
566
|
click.echo(f" Python: {sys.version.split()[0]}")
|
|
567
567
|
|
|
@@ -878,6 +878,43 @@ def _create_project_structure(project_dir: Path):
|
|
|
878
878
|
(project_dir / dir_path).mkdir(parents=True, exist_ok=True)
|
|
879
879
|
click.echo(f" Created: {dir_path}/")
|
|
880
880
|
|
|
881
|
+
# Create essential templates
|
|
882
|
+
(project_dir / "templates" / "_page.html").write_text('''<!DOCTYPE html>
|
|
883
|
+
<html lang="en">
|
|
884
|
+
<head>
|
|
885
|
+
<meta charset="utf-8">
|
|
886
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
887
|
+
<title>{{ title or "NextPy App" }}</title>
|
|
888
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
889
|
+
</head>
|
|
890
|
+
<body>
|
|
891
|
+
<div id="app">
|
|
892
|
+
{{ content }}
|
|
893
|
+
</div>
|
|
894
|
+
</body>
|
|
895
|
+
</html>''')
|
|
896
|
+
click.echo(" Created: templates/_page.html")
|
|
897
|
+
|
|
898
|
+
(project_dir / "templates" / "_404.html").write_text('''<!DOCTYPE html>
|
|
899
|
+
<html lang="en">
|
|
900
|
+
<head>
|
|
901
|
+
<meta charset="utf-8">
|
|
902
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
903
|
+
<title>404 - Page Not Found</title>
|
|
904
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
905
|
+
</head>
|
|
906
|
+
<body class="min-h-screen bg-gray-100 flex items-center justify-center">
|
|
907
|
+
<div class="text-center">
|
|
908
|
+
<h1 class="text-6xl font-bold text-gray-900 mb-4">404</h1>
|
|
909
|
+
<p class="text-xl text-gray-600 mb-8">Page not found</p>
|
|
910
|
+
<a href="/" class="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
|
|
911
|
+
Go Home
|
|
912
|
+
</a>
|
|
913
|
+
</div>
|
|
914
|
+
</body>
|
|
915
|
+
</html>''')
|
|
916
|
+
click.echo(" Created: templates/_404.html")
|
|
917
|
+
|
|
881
918
|
# Create styles.css with Tailwind directives
|
|
882
919
|
(project_dir / "styles.css").write_text('''/* NextPy Styles */
|
|
883
920
|
@tailwind base;
|
|
@@ -982,7 +1019,7 @@ body {
|
|
|
982
1019
|
# Create postcss.config.js with new Tailwind plugin
|
|
983
1020
|
(project_dir / "postcss.config.js").write_text('''module.exports = {
|
|
984
1021
|
plugins: {
|
|
985
|
-
|
|
1022
|
+
tailwindcss: {},
|
|
986
1023
|
autoprefixer: {},
|
|
987
1024
|
},
|
|
988
1025
|
};''')
|
|
@@ -1005,11 +1042,8 @@ body {
|
|
|
1005
1042
|
"devDependencies": {
|
|
1006
1043
|
"autoprefixer": "^10.4.22",
|
|
1007
1044
|
"postcss": "^8.5.6",
|
|
1008
|
-
"
|
|
1009
|
-
|
|
1010
|
-
"dependencies": {
|
|
1011
|
-
"@tailwindcss/postcss": "^4.1.18",
|
|
1012
|
-
"postcss-cli": "^11.0.1"
|
|
1045
|
+
"postcss-cli": "^11.0.1",
|
|
1046
|
+
"tailwindcss": "^3.4.1"
|
|
1013
1047
|
}
|
|
1014
1048
|
}''')
|
|
1015
1049
|
click.echo(" Created: package.json")
|
|
@@ -1024,7 +1058,6 @@ def Home(props=None):
|
|
|
1024
1058
|
|
|
1025
1059
|
return (
|
|
1026
1060
|
<div className="min-h-screen bg-gradient-to-br from-blue-600 via-purple-600 to-pink-600">
|
|
1027
|
-
{/* Navigation */}
|
|
1028
1061
|
<nav className="bg-white border-b border-white bg-opacity-10 backdrop-blur-md border-opacity-20">
|
|
1029
1062
|
<div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1030
1063
|
<div className="flex items-center justify-between h-16">
|
|
@@ -1046,7 +1079,6 @@ def Home(props=None):
|
|
|
1046
1079
|
</div>
|
|
1047
1080
|
</nav>
|
|
1048
1081
|
|
|
1049
|
-
{/* Hero Section */}
|
|
1050
1082
|
<div className="relative overflow-hidden">
|
|
1051
1083
|
<div className="mx-auto max-w-7xl">
|
|
1052
1084
|
<div className="relative z-10 pb-8 bg-transparent sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
|
|
@@ -1072,7 +1104,6 @@ def Home(props=None):
|
|
|
1072
1104
|
</div>
|
|
1073
1105
|
</div>
|
|
1074
1106
|
|
|
1075
|
-
{/* Background decoration */}
|
|
1076
1107
|
<div className="absolute inset-0 -z-10">
|
|
1077
1108
|
<div className="absolute top-0 transform -translate-x-1/2 left-1/2 blur-3xl opacity-20">
|
|
1078
1109
|
<div className="rounded-full aspect-square w-96 h-96 bg-gradient-to-r from-blue-400 to-purple-600"></div>
|
|
@@ -1083,7 +1114,7 @@ def Home(props=None):
|
|
|
1083
1114
|
</div>
|
|
1084
1115
|
</div>
|
|
1085
1116
|
|
|
1086
|
-
|
|
1117
|
+
|
|
1087
1118
|
<div className="py-12 bg-white">
|
|
1088
1119
|
<div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1089
1120
|
<div className="lg:text-center">
|
|
@@ -1097,10 +1128,10 @@ def Home(props=None):
|
|
|
1097
1128
|
|
|
1098
1129
|
<div className="mt-10">
|
|
1099
1130
|
<div className="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10 lg:grid-cols-3">
|
|
1100
|
-
|
|
1131
|
+
|
|
1101
1132
|
<div className="relative">
|
|
1102
1133
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-blue-500 rounded-md">
|
|
1103
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1134
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1104
1135
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
|
|
1105
1136
|
</svg>
|
|
1106
1137
|
</div>
|
|
@@ -1111,14 +1142,14 @@ def Home(props=None):
|
|
|
1111
1142
|
Write React-like components directly in Python with full JSX support.
|
|
1112
1143
|
</p>
|
|
1113
1144
|
<a href="/jsx-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
|
|
1114
|
-
Learn more
|
|
1145
|
+
Learn more →
|
|
1115
1146
|
</a>
|
|
1116
1147
|
</div>
|
|
1117
1148
|
|
|
1118
|
-
|
|
1149
|
+
|
|
1119
1150
|
<div className="relative">
|
|
1120
1151
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-purple-500 rounded-md">
|
|
1121
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1152
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1122
1153
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
|
|
1123
1154
|
</svg>
|
|
1124
1155
|
</div>
|
|
@@ -1129,14 +1160,14 @@ def Home(props=None):
|
|
|
1129
1160
|
Built-in Tailwind CSS v4 with PostCSS compilation and utility classes.
|
|
1130
1161
|
</p>
|
|
1131
1162
|
<a href="/tailwind-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
|
|
1132
|
-
Learn more
|
|
1163
|
+
Learn more →
|
|
1133
1164
|
</a>
|
|
1134
1165
|
</div>
|
|
1135
1166
|
|
|
1136
|
-
|
|
1167
|
+
|
|
1137
1168
|
<div className="relative">
|
|
1138
1169
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-green-500 rounded-md">
|
|
1139
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1170
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1140
1171
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
|
|
1141
1172
|
</svg>
|
|
1142
1173
|
</div>
|
|
@@ -1147,7 +1178,7 @@ def Home(props=None):
|
|
|
1147
1178
|
Automatic route discovery with support for dynamic routes and API endpoints.
|
|
1148
1179
|
</p>
|
|
1149
1180
|
<a href="/routing-demo" className="mt-4 ml-16 text-base font-medium text-blue-600 hover:text-blue-500">
|
|
1150
|
-
Learn more
|
|
1181
|
+
Learn more →
|
|
1151
1182
|
</a>
|
|
1152
1183
|
</div>
|
|
1153
1184
|
</div>
|
|
@@ -1155,7 +1186,7 @@ def Home(props=None):
|
|
|
1155
1186
|
</div>
|
|
1156
1187
|
</div>
|
|
1157
1188
|
|
|
1158
|
-
|
|
1189
|
+
|
|
1159
1190
|
<div className="py-12 bg-gray-50">
|
|
1160
1191
|
<div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1161
1192
|
<div className="text-center">
|
|
@@ -1168,7 +1199,7 @@ def Home(props=None):
|
|
|
1168
1199
|
</div>
|
|
1169
1200
|
|
|
1170
1201
|
<div className="grid grid-cols-1 gap-8 mt-12 sm:grid-cols-2 lg:grid-cols-3">
|
|
1171
|
-
|
|
1202
|
+
|
|
1172
1203
|
<div className="p-6 bg-white rounded-lg shadow-lg">
|
|
1173
1204
|
<h3 className="text-lg font-medium text-gray-900">Live Counter</h3>
|
|
1174
1205
|
<p className="mt-2 text-sm text-gray-500">Interactive state management demo</p>
|
|
@@ -1180,7 +1211,7 @@ def Home(props=None):
|
|
|
1180
1211
|
</div>
|
|
1181
1212
|
</div>
|
|
1182
1213
|
|
|
1183
|
-
|
|
1214
|
+
|
|
1184
1215
|
<div className="p-6 bg-white rounded-lg shadow-lg">
|
|
1185
1216
|
<h3 className="text-lg font-medium text-gray-900">Form Handling</h3>
|
|
1186
1217
|
<p className="mt-2 text-sm text-gray-500">Server-side form processing</p>
|
|
@@ -1192,7 +1223,7 @@ def Home(props=None):
|
|
|
1192
1223
|
</div>
|
|
1193
1224
|
</div>
|
|
1194
1225
|
|
|
1195
|
-
|
|
1226
|
+
|
|
1196
1227
|
<div className="p-6 bg-white rounded-lg shadow-lg">
|
|
1197
1228
|
<h3 className="text-lg font-medium text-gray-900">API Integration</h3>
|
|
1198
1229
|
<p className="mt-2 text-sm text-gray-500">RESTful API endpoints</p>
|
|
@@ -1207,12 +1238,12 @@ def Home(props=None):
|
|
|
1207
1238
|
</div>
|
|
1208
1239
|
</div>
|
|
1209
1240
|
|
|
1210
|
-
|
|
1241
|
+
|
|
1211
1242
|
<footer className="bg-gray-900">
|
|
1212
1243
|
<div className="px-4 py-12 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1213
1244
|
<div className="flex flex-col items-center space-y-4">
|
|
1214
1245
|
<p className="text-base text-center text-gray-400">
|
|
1215
|
-
Built with
|
|
1246
|
+
Built with ♥ using NextPy Framework
|
|
1216
1247
|
</p>
|
|
1217
1248
|
<div className="flex space-x-6">
|
|
1218
1249
|
<a href="/about" className="text-gray-400 hover:text-gray-300">About</a>
|
|
@@ -1249,8 +1280,7 @@ def About(props=None):
|
|
|
1249
1280
|
|
|
1250
1281
|
return (
|
|
1251
1282
|
<div className="min-h-screen bg-gray-50">
|
|
1252
|
-
|
|
1253
|
-
<div className="text-white bg-gradient-to-r from-blue-600 to-purple-600">
|
|
1283
|
+
<div className="text-white bg-gradient-to-r from-blue-600 to-purple-600">
|
|
1254
1284
|
<div className="px-4 py-16 mx-auto max-w-7xl sm:py-24 sm:px-6 lg:px-8">
|
|
1255
1285
|
<div className="text-center">
|
|
1256
1286
|
<h1 className="text-4xl font-extrabold tracking-tight sm:text-5xl lg:text-6xl">
|
|
@@ -1271,7 +1301,7 @@ def About(props=None):
|
|
|
1271
1301
|
</div>
|
|
1272
1302
|
</div>
|
|
1273
1303
|
|
|
1274
|
-
|
|
1304
|
+
|
|
1275
1305
|
<div className="py-12 bg-white">
|
|
1276
1306
|
<div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1277
1307
|
<div className="lg:text-center">
|
|
@@ -1285,10 +1315,10 @@ def About(props=None):
|
|
|
1285
1315
|
|
|
1286
1316
|
<div className="mt-10">
|
|
1287
1317
|
<div className="gap-8 space-y-10 md:space-y-0 md:grid md:grid-cols-2 lg:grid-cols-3">
|
|
1288
|
-
|
|
1318
|
+
|
|
1289
1319
|
<div className="relative">
|
|
1290
1320
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-blue-500 rounded-md">
|
|
1291
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1321
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1292
1322
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
|
|
1293
1323
|
</svg>
|
|
1294
1324
|
</div>
|
|
@@ -1298,10 +1328,10 @@ def About(props=None):
|
|
|
1298
1328
|
</p>
|
|
1299
1329
|
</div>
|
|
1300
1330
|
|
|
1301
|
-
|
|
1331
|
+
|
|
1302
1332
|
<div className="relative">
|
|
1303
1333
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-purple-500 rounded-md">
|
|
1304
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1334
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1305
1335
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
|
|
1306
1336
|
</svg>
|
|
1307
1337
|
</div>
|
|
@@ -1311,10 +1341,10 @@ def About(props=None):
|
|
|
1311
1341
|
</p>
|
|
1312
1342
|
</div>
|
|
1313
1343
|
|
|
1314
|
-
|
|
1344
|
+
|
|
1315
1345
|
<div className="relative">
|
|
1316
1346
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-green-500 rounded-md">
|
|
1317
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1347
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1318
1348
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
|
|
1319
1349
|
</svg>
|
|
1320
1350
|
</div>
|
|
@@ -1324,10 +1354,10 @@ def About(props=None):
|
|
|
1324
1354
|
</p>
|
|
1325
1355
|
</div>
|
|
1326
1356
|
|
|
1327
|
-
|
|
1357
|
+
|
|
1328
1358
|
<div className="relative">
|
|
1329
1359
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-red-500 rounded-md">
|
|
1330
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1360
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1331
1361
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
|
|
1332
1362
|
</svg>
|
|
1333
1363
|
</div>
|
|
@@ -1337,10 +1367,10 @@ def About(props=None):
|
|
|
1337
1367
|
</p>
|
|
1338
1368
|
</div>
|
|
1339
1369
|
|
|
1340
|
-
|
|
1370
|
+
|
|
1341
1371
|
<div className="relative">
|
|
1342
1372
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-yellow-500 rounded-md">
|
|
1343
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1373
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1344
1374
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 00-1.065 2.572c1.756.426 1.756 2.924 0 3.35-1.756a1.724 1.724 0 00-1.066-2.573c1.756-.426 1.756-2.924 0-3.35 1.756a1.724 1.724 0 00-2.573-1.066c-1.756.426-1.756-2.924 0-3.35 1.756A1.724 1.724 0 006.573 2.572C3.31 7.76 1.574 8.686 4.317 8.686a1.724 1.724 0 00-1.066-2.572c1.756-.426 1.756-2.924 0-3.35 1.756a1.724 1.724 0 00-2.573-1.066c-1.756.426-1.756-2.924 0-3.35 1.756A1.724 1.724 0 001.066 2.572c1.756.426 1.756 2.924 0 3.35-1.756a1.724 1.724 0 002.573 1.066z" />
|
|
1345
1375
|
</svg>
|
|
1346
1376
|
</div>
|
|
@@ -1350,10 +1380,10 @@ def About(props=None):
|
|
|
1350
1380
|
</p>
|
|
1351
1381
|
</div>
|
|
1352
1382
|
|
|
1353
|
-
|
|
1383
|
+
|
|
1354
1384
|
<div className="relative">
|
|
1355
1385
|
<div className="absolute flex items-center justify-center w-12 h-12 text-white bg-indigo-500 rounded-md">
|
|
1356
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1386
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1357
1387
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
1358
1388
|
</svg>
|
|
1359
1389
|
</div>
|
|
@@ -1367,7 +1397,7 @@ def About(props=None):
|
|
|
1367
1397
|
</div>
|
|
1368
1398
|
</div>
|
|
1369
1399
|
|
|
1370
|
-
|
|
1400
|
+
|
|
1371
1401
|
<div className="py-12 bg-gray-50">
|
|
1372
1402
|
<div className="px-4 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1373
1403
|
<div className="text-center">
|
|
@@ -1380,11 +1410,11 @@ def About(props=None):
|
|
|
1380
1410
|
</div>
|
|
1381
1411
|
|
|
1382
1412
|
<div className="grid grid-cols-1 gap-8 mt-12 sm:grid-cols-2 lg:grid-cols-3">
|
|
1383
|
-
|
|
1413
|
+
|
|
1384
1414
|
<div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
|
|
1385
1415
|
<div className="text-center">
|
|
1386
1416
|
<div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-blue-500 rounded-md">
|
|
1387
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1417
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1388
1418
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7m0 0v7l9-11h-7z" />
|
|
1389
1419
|
</svg>
|
|
1390
1420
|
</div>
|
|
@@ -1395,11 +1425,11 @@ def About(props=None):
|
|
|
1395
1425
|
</button>
|
|
1396
1426
|
</div>
|
|
1397
1427
|
|
|
1398
|
-
|
|
1428
|
+
|
|
1399
1429
|
<div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
|
|
1400
1430
|
<div className="text-center">
|
|
1401
1431
|
<div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-purple-500 rounded-md">
|
|
1402
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1432
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1403
1433
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
|
|
1404
1434
|
</svg>
|
|
1405
1435
|
</div>
|
|
@@ -1410,11 +1440,11 @@ def About(props=None):
|
|
|
1410
1440
|
</button>
|
|
1411
1441
|
</div>
|
|
1412
1442
|
|
|
1413
|
-
|
|
1443
|
+
|
|
1414
1444
|
<div className="p-6 transition-shadow bg-white rounded-lg shadow-lg hover:shadow-xl">
|
|
1415
1445
|
<div className="text-center">
|
|
1416
1446
|
<div className="flex items-center justify-center w-12 h-12 mx-auto mb-4 text-white bg-green-500 rounded-md">
|
|
1417
|
-
<svg className="w-6 h-6" fill="none" viewBox=
|
|
1447
|
+
<svg className="w-6 h-6" fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1418
1448
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
|
|
1419
1449
|
</svg>
|
|
1420
1450
|
</div>
|
|
@@ -1429,7 +1459,7 @@ def About(props=None):
|
|
|
1429
1459
|
</div>
|
|
1430
1460
|
</div>
|
|
1431
1461
|
|
|
1432
|
-
|
|
1462
|
+
|
|
1433
1463
|
<div className="bg-blue-600">
|
|
1434
1464
|
<div className="px-4 py-12 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1435
1465
|
<div className="grid grid-cols-2 gap-8 lg:grid-cols-4">
|
|
@@ -1453,12 +1483,12 @@ def About(props=None):
|
|
|
1453
1483
|
</div>
|
|
1454
1484
|
</div>
|
|
1455
1485
|
|
|
1456
|
-
|
|
1486
|
+
|
|
1457
1487
|
<footer className="bg-gray-900">
|
|
1458
1488
|
<div className="px-4 py-8 mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
1459
1489
|
<div className="flex flex-col items-center space-y-4">
|
|
1460
1490
|
<p className="text-base text-center text-gray-400">
|
|
1461
|
-
Built with
|
|
1491
|
+
Built with ♥ using NextPy Framework
|
|
1462
1492
|
</p>
|
|
1463
1493
|
<div className="flex space-x-6">
|
|
1464
1494
|
<a href="/" className="text-gray-400 hover:text-gray-300">Home</a>
|
|
@@ -1497,7 +1527,7 @@ def InteractiveDemo(props=None):
|
|
|
1497
1527
|
</h1>
|
|
1498
1528
|
|
|
1499
1529
|
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3">
|
|
1500
|
-
|
|
1530
|
+
|
|
1501
1531
|
<div className="p-6 bg-white shadow-lg rounded-xl">
|
|
1502
1532
|
<h2 className="mb-4 text-2xl font-bold text-gray-900">Live Counter</h2>
|
|
1503
1533
|
<div className="text-center">
|
|
@@ -1516,7 +1546,7 @@ def InteractiveDemo(props=None):
|
|
|
1516
1546
|
</div>
|
|
1517
1547
|
</div>
|
|
1518
1548
|
|
|
1519
|
-
|
|
1549
|
+
|
|
1520
1550
|
<div className="p-6 bg-white shadow-lg rounded-xl">
|
|
1521
1551
|
<h2 className="mb-4 text-2xl font-bold text-gray-900">Todo List</h2>
|
|
1522
1552
|
<div className="space-y-4">
|
|
@@ -1527,12 +1557,12 @@ def InteractiveDemo(props=None):
|
|
|
1527
1557
|
</button>
|
|
1528
1558
|
</div>
|
|
1529
1559
|
<ul id="todoList" className="space-y-2">
|
|
1530
|
-
|
|
1560
|
+
|
|
1531
1561
|
</ul>
|
|
1532
1562
|
</div>
|
|
1533
1563
|
</div>
|
|
1534
1564
|
|
|
1535
|
-
|
|
1565
|
+
|
|
1536
1566
|
<div className="p-6 bg-white shadow-lg rounded-xl">
|
|
1537
1567
|
<h2 className="mb-4 text-2xl font-bold text-gray-900">Color Picker</h2>
|
|
1538
1568
|
<div className="space-y-4">
|
|
@@ -1543,7 +1573,7 @@ def InteractiveDemo(props=None):
|
|
|
1543
1573
|
</div>
|
|
1544
1574
|
</div>
|
|
1545
1575
|
|
|
1546
|
-
|
|
1576
|
+
|
|
1547
1577
|
<div className="p-6 bg-white shadow-lg rounded-xl">
|
|
1548
1578
|
<h2 className="mb-4 text-2xl font-bold text-gray-900">Form Validation</h2>
|
|
1549
1579
|
<form onsubmit="validateForm(event)" className="space-y-4">
|
|
@@ -1560,7 +1590,7 @@ def InteractiveDemo(props=None):
|
|
|
1560
1590
|
</button>
|
|
1561
1591
|
</form>
|
|
1562
1592
|
<div id="validationResult" className="hidden p-4 mt-4 rounded-lg">
|
|
1563
|
-
|
|
1593
|
+
|
|
1564
1594
|
</div>
|
|
1565
1595
|
</div>
|
|
1566
1596
|
</div>
|
|
@@ -1594,13 +1624,13 @@ def Features(props=None):
|
|
|
1594
1624
|
|
|
1595
1625
|
<div className="grid grid-cols-1 gap-12 md:grid-cols-2">
|
|
1596
1626
|
<div className="space-y-12">
|
|
1597
|
-
|
|
1627
|
+
|
|
1598
1628
|
<div>
|
|
1599
1629
|
<h2 className="mb-6 text-2xl font-bold text-gray-900">Core Features</h2>
|
|
1600
1630
|
<div className="space-y-6">
|
|
1601
1631
|
<div className="flex items-start space-x-4">
|
|
1602
1632
|
<div className="flex-shrink-0 w-6 h-6 text-green-500">
|
|
1603
|
-
<svg fill="none" viewBox=
|
|
1633
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1604
1634
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
1605
1635
|
</svg>
|
|
1606
1636
|
</div>
|
|
@@ -1612,7 +1642,7 @@ def Features(props=None):
|
|
|
1612
1642
|
|
|
1613
1643
|
<div className="flex items-start space-x-4">
|
|
1614
1644
|
<div className="flex-shrink-0 w-6 h-6 text-blue-500">
|
|
1615
|
-
<svg fill="none" viewBox=
|
|
1645
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1616
1646
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
|
|
1617
1647
|
</svg>
|
|
1618
1648
|
</div>
|
|
@@ -1624,7 +1654,7 @@ def Features(props=None):
|
|
|
1624
1654
|
|
|
1625
1655
|
<div className="flex items-start space-x-4">
|
|
1626
1656
|
<div className="flex-shrink-0 w-6 h-6 text-purple-500">
|
|
1627
|
-
<svg fill="none" viewBox=
|
|
1657
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1628
1658
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 2 9 9 0 0118 0z" />
|
|
1629
1659
|
</svg>
|
|
1630
1660
|
</div>
|
|
@@ -1636,13 +1666,13 @@ def Features(props=None):
|
|
|
1636
1666
|
</div>
|
|
1637
1667
|
</div>
|
|
1638
1668
|
|
|
1639
|
-
|
|
1669
|
+
|
|
1640
1670
|
<div>
|
|
1641
1671
|
<h2 className="mb-6 text-2xl font-bold text-gray-900">Development Experience</h2>
|
|
1642
1672
|
<div className="space-y-6">
|
|
1643
1673
|
<div className="flex items-start space-x-4">
|
|
1644
1674
|
<div className="flex-shrink-0 w-6 h-6 text-red-500">
|
|
1645
|
-
<svg fill="none" viewBox=
|
|
1675
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1646
1676
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v16h16V4H4z" />
|
|
1647
1677
|
</svg>
|
|
1648
1678
|
</div>
|
|
@@ -1654,7 +1684,7 @@ def Features(props=None):
|
|
|
1654
1684
|
|
|
1655
1685
|
<div className="flex items-start space-x-4">
|
|
1656
1686
|
<div className="flex-shrink-0 w-6 h-6 text-yellow-500">
|
|
1657
|
-
<svg fill="none" viewBox=
|
|
1687
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1658
1688
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.75 5H6.25v13l4.5 4.5z" />
|
|
1659
1689
|
</svg>
|
|
1660
1690
|
</div>
|
|
@@ -1666,7 +1696,7 @@ def Features(props=None):
|
|
|
1666
1696
|
|
|
1667
1697
|
<div className="flex items-start space-x-4">
|
|
1668
1698
|
<div className="flex-shrink-0 w-6 h-6 text-indigo-500">
|
|
1669
|
-
<svg fill="none" viewBox=
|
|
1699
|
+
<svg fill="none" viewBox={'0 0 24 24'} stroke="currentColor">
|
|
1670
1700
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
1671
1701
|
</svg>
|
|
1672
1702
|
</div>
|
|
@@ -1707,7 +1737,7 @@ def GettingStarted(props=None):
|
|
|
1707
1737
|
</div>
|
|
1708
1738
|
|
|
1709
1739
|
<div className="space-y-16">
|
|
1710
|
-
|
|
1740
|
+
|
|
1711
1741
|
<div className="p-8 rounded-lg bg-blue-50">
|
|
1712
1742
|
<div className="flex items-center mb-4">
|
|
1713
1743
|
<div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-blue-500 rounded-full">
|
|
@@ -1727,7 +1757,7 @@ def GettingStarted(props=None):
|
|
|
1727
1757
|
</div>
|
|
1728
1758
|
</div>
|
|
1729
1759
|
|
|
1730
|
-
|
|
1760
|
+
|
|
1731
1761
|
<div className="p-8 rounded-lg bg-green-50">
|
|
1732
1762
|
<div className="flex items-center mb-4">
|
|
1733
1763
|
<div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-green-500 rounded-full">
|
|
@@ -1744,18 +1774,18 @@ def GettingStarted(props=None):
|
|
|
1744
1774
|
<h3 className="mb-2 font-semibold text-gray-900">Project Structure</h3>
|
|
1745
1775
|
<pre className="p-4 overflow-x-auto text-sm bg-gray-100 rounded">
|
|
1746
1776
|
{`my-app/
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1777
|
+
|-- pages/ # Your pages and API routes
|
|
1778
|
+
|-- components/ # Reusable components
|
|
1779
|
+
|-- templates/ # HTML templates
|
|
1780
|
+
|-- public/ # Static assets
|
|
1781
|
+
|-- styles.css # Tailwind CSS
|
|
1782
|
+
|-- main.py # Application entry point
|
|
1783
|
+
`-- requirements.txt # Python dependencies`}</pre>
|
|
1754
1784
|
</div>
|
|
1755
1785
|
</div>
|
|
1756
1786
|
</div>
|
|
1757
1787
|
|
|
1758
|
-
|
|
1788
|
+
|
|
1759
1789
|
<div className="p-8 rounded-lg bg-purple-50">
|
|
1760
1790
|
<div className="flex items-center mb-4">
|
|
1761
1791
|
<div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-purple-500 rounded-full">
|
|
@@ -1775,7 +1805,7 @@ def GettingStarted(props=None):
|
|
|
1775
1805
|
</div>
|
|
1776
1806
|
</div>
|
|
1777
1807
|
|
|
1778
|
-
|
|
1808
|
+
|
|
1779
1809
|
<div className="p-8 rounded-lg bg-yellow-50">
|
|
1780
1810
|
<div className="flex items-center mb-4">
|
|
1781
1811
|
<div className="flex items-center justify-center flex-shrink-0 w-8 h-8 font-bold text-white bg-yellow-500 rounded-full">
|
|
@@ -1927,21 +1957,21 @@ default = Layout
|
|
|
1927
1957
|
"css.value.unit": "rem"
|
|
1928
1958
|
},
|
|
1929
1959
|
"files.exclude": {
|
|
1930
|
-
"
|
|
1931
|
-
"
|
|
1932
|
-
"
|
|
1933
|
-
"
|
|
1934
|
-
"
|
|
1935
|
-
"
|
|
1936
|
-
"
|
|
1960
|
+
"*}__pycache__": true,
|
|
1961
|
+
"*}*.pyc": true,
|
|
1962
|
+
"*}node_modules": true,
|
|
1963
|
+
"*}out": true,
|
|
1964
|
+
"*}.next": true,
|
|
1965
|
+
"*}.pytest_cache": true,
|
|
1966
|
+
"*}.mypy_cache": true
|
|
1937
1967
|
},
|
|
1938
1968
|
"search.exclude": {
|
|
1939
|
-
"
|
|
1940
|
-
"
|
|
1941
|
-
"
|
|
1942
|
-
"
|
|
1943
|
-
"
|
|
1944
|
-
"
|
|
1969
|
+
"*}node_modules": true,
|
|
1970
|
+
"*}out": true,
|
|
1971
|
+
"*}.next": true,
|
|
1972
|
+
"*}__pycache__": true,
|
|
1973
|
+
"*}.pytest_cache": true,
|
|
1974
|
+
"*}.mypy_cache": true
|
|
1945
1975
|
},
|
|
1946
1976
|
"python.linting.enabled": true,
|
|
1947
1977
|
"python.linting.pylintEnabled": false,
|
|
@@ -2197,19 +2227,19 @@ This is a NextPy application with True JSX, Tailwind CSS, and comprehensive API
|
|
|
2197
2227
|
|
|
2198
2228
|
## Project Structure
|
|
2199
2229
|
```
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2230
|
+
|-- pages/ # File-based routing
|
|
2231
|
+
| |-- api/ # API routes
|
|
2232
|
+
| `-- *.py # Page components
|
|
2233
|
+
|-- components/ # Reusable components
|
|
2234
|
+
|-- templates/ # HTML templates
|
|
2235
|
+
|-- models/ # Database models
|
|
2236
|
+
|-- utils/ # Utility functions
|
|
2237
|
+
|-- hooks/ # Custom hooks
|
|
2238
|
+
|-- middleware/ # Custom middleware
|
|
2239
|
+
|-- tests/ # Test files
|
|
2240
|
+
|-- public/ # Static assets
|
|
2241
|
+
|-- styles/ # CSS files
|
|
2242
|
+
`-- docs/ # Documentation
|
|
2213
2243
|
```
|
|
2214
2244
|
|
|
2215
2245
|
## Getting Started
|
|
@@ -2254,9 +2284,6 @@ import sys
|
|
|
2254
2284
|
import subprocess
|
|
2255
2285
|
from pathlib import Path
|
|
2256
2286
|
|
|
2257
|
-
print(f"DEBUG: Current working directory: {Path.cwd()}")
|
|
2258
|
-
print(f"DEBUG: sys.path before modification: {sys.path}")
|
|
2259
|
-
|
|
2260
2287
|
# Compile Tailwind CSS using PostCSS
|
|
2261
2288
|
try:
|
|
2262
2289
|
print("Compiling Tailwind CSS...")
|
|
@@ -2268,15 +2295,13 @@ try:
|
|
|
2268
2295
|
check=True
|
|
2269
2296
|
)
|
|
2270
2297
|
print("Tailwind CSS compiled successfully.")
|
|
2271
|
-
if result.stdout:
|
|
2272
|
-
print(f"CSS Output: {result.stdout[:200]}...")
|
|
2273
2298
|
except subprocess.CalledProcessError as e:
|
|
2274
2299
|
print(f"Error compiling Tailwind CSS: {e}")
|
|
2275
2300
|
if e.stderr:
|
|
2276
2301
|
print(f"CSS Error: {e.stderr}")
|
|
2277
2302
|
except FileNotFoundError:
|
|
2278
2303
|
print("Error: PostCSS not found. Make sure Node.js and Tailwind CSS are installed.")
|
|
2279
|
-
print("Install with: npm install postcss-cli
|
|
2304
|
+
print("Install with: npm install postcss-cli tailwindcss autoprefixer")
|
|
2280
2305
|
|
|
2281
2306
|
# Import NextPy modules (works when installed via pip)
|
|
2282
2307
|
from nextpy.server.app import create_app
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/component_router.py
RENAMED
|
@@ -342,26 +342,34 @@ class ComponentRouter:
|
|
|
342
342
|
return handler
|
|
343
343
|
|
|
344
344
|
def _create_template_handler(self, file_path: Path) -> Optional[Callable]:
|
|
345
|
-
"""Load the traditional template-based handler"""
|
|
345
|
+
"""Load the traditional template-based handler using JSX transformer"""
|
|
346
346
|
try:
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
spec.loader.exec_module(module)
|
|
354
|
-
|
|
347
|
+
# Use JSX transformer for consistent loading
|
|
348
|
+
from ..jsx_transformer import JSXTransformer
|
|
349
|
+
transformer = JSXTransformer()
|
|
350
|
+
module = transformer.load_jsx_module(file_path, file_path.stem)
|
|
351
|
+
|
|
352
|
+
if module:
|
|
355
353
|
for func_name in ["handler", "page", "get", "post", "default"]:
|
|
356
354
|
if hasattr(module, func_name):
|
|
357
355
|
return getattr(module, func_name)
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
356
|
+
except Exception:
|
|
357
|
+
# Fallback to regular import if JSX transformer fails
|
|
358
|
+
try:
|
|
359
|
+
spec = importlib.util.spec_from_file_location(
|
|
360
|
+
file_path.stem,
|
|
361
|
+
file_path
|
|
362
|
+
)
|
|
363
|
+
if spec and spec.loader:
|
|
364
|
+
module = importlib.util.module_from_spec(spec)
|
|
365
|
+
spec.loader.exec_module(module)
|
|
361
366
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
367
|
+
for func_name in ["handler", "page", "get", "post", "default"]:
|
|
368
|
+
if hasattr(module, func_name):
|
|
369
|
+
return getattr(module, func_name)
|
|
370
|
+
except Exception:
|
|
371
|
+
pass # Silently fail if both methods fail
|
|
372
|
+
|
|
365
373
|
return None
|
|
366
374
|
|
|
367
375
|
def _sort_routes(self) -> None:
|
|
@@ -164,26 +164,34 @@ class Router:
|
|
|
164
164
|
)
|
|
165
165
|
|
|
166
166
|
def _load_handler(self, file_path: Path) -> Optional[Callable]:
|
|
167
|
-
"""Dynamically load the handler function from a page file"""
|
|
167
|
+
"""Dynamically load the handler function from a page file using JSX transformer"""
|
|
168
168
|
try:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
spec.loader.exec_module(module)
|
|
176
|
-
|
|
169
|
+
# Use JSX transformer for consistent loading
|
|
170
|
+
from ..jsx_transformer import JSXTransformer
|
|
171
|
+
transformer = JSXTransformer()
|
|
172
|
+
module = transformer.load_jsx_module(file_path, file_path.stem)
|
|
173
|
+
|
|
174
|
+
if module:
|
|
177
175
|
for func_name in ["handler", "page", "get", "post", "default"]:
|
|
178
176
|
if hasattr(module, func_name):
|
|
179
177
|
return getattr(module, func_name)
|
|
180
|
-
|
|
181
|
-
if hasattr(module, "Page"):
|
|
182
|
-
return module.Page
|
|
183
|
-
|
|
184
178
|
except Exception as e:
|
|
185
|
-
|
|
186
|
-
|
|
179
|
+
# Fallback to regular import if JSX transformer fails
|
|
180
|
+
try:
|
|
181
|
+
spec = importlib.util.spec_from_file_location(
|
|
182
|
+
file_path.stem,
|
|
183
|
+
file_path
|
|
184
|
+
)
|
|
185
|
+
if spec and spec.loader:
|
|
186
|
+
module = importlib.util.module_from_spec(spec)
|
|
187
|
+
spec.loader.exec_module(module)
|
|
188
|
+
|
|
189
|
+
for func_name in ["handler", "page", "get", "post", "default"]:
|
|
190
|
+
if hasattr(module, func_name):
|
|
191
|
+
return getattr(module, func_name)
|
|
192
|
+
except Exception:
|
|
193
|
+
pass # Silently fail if both methods fail
|
|
194
|
+
|
|
187
195
|
return None
|
|
188
196
|
|
|
189
197
|
def _sort_routes(self) -> None:
|
|
@@ -131,34 +131,57 @@ class NextPyApp:
|
|
|
131
131
|
# Add all routes from the router
|
|
132
132
|
for route in self.router.get_all_routes():
|
|
133
133
|
if route.is_api:
|
|
134
|
-
# API routes
|
|
134
|
+
# API routes - FIXED: use default argument to capture route correctly
|
|
135
|
+
def create_api_handler(route_obj):
|
|
136
|
+
def api_handler(request, route=route_obj):
|
|
137
|
+
return self._handle_api_request(request, route, {})
|
|
138
|
+
return api_handler
|
|
139
|
+
|
|
135
140
|
self.app.add_api_route(
|
|
136
141
|
route.path,
|
|
137
|
-
|
|
142
|
+
create_api_handler(route),
|
|
138
143
|
methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
|
139
144
|
)
|
|
140
145
|
else:
|
|
141
|
-
# Page routes
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
# Page routes - FIXED: use default argument to capture route correctly
|
|
147
|
+
def create_page_handler(route_path):
|
|
148
|
+
async def page_handler(request, path=route_path):
|
|
149
|
+
return await self._handle_request(request, path)
|
|
150
|
+
return page_handler
|
|
144
151
|
|
|
145
152
|
self.app.add_route(
|
|
146
153
|
route.path,
|
|
147
|
-
|
|
154
|
+
create_page_handler(route.path),
|
|
148
155
|
methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
|
149
156
|
)
|
|
150
157
|
|
|
151
158
|
def _load_module_from_file(self, file_path: Path) -> Optional[Any]:
|
|
152
|
-
"""Load a Python module from a file path"""
|
|
159
|
+
"""Load a Python module from a file path with caching"""
|
|
153
160
|
try:
|
|
161
|
+
# Convert relative path to absolute path
|
|
162
|
+
if not file_path.is_absolute():
|
|
163
|
+
file_path = Path.cwd() / file_path
|
|
164
|
+
|
|
165
|
+
# Create cache key
|
|
166
|
+
cache_key = str(file_path.resolve())
|
|
167
|
+
|
|
168
|
+
# Check cache first (unless in debug mode)
|
|
169
|
+
if not self.debug and cache_key in self._modules_cache:
|
|
170
|
+
return self._modules_cache[cache_key]
|
|
171
|
+
|
|
154
172
|
module_name = f"nextpy_page_{file_path.stem}_{hash(str(file_path))}"
|
|
155
173
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
174
|
+
# Use JSX transformer for JSX files
|
|
175
|
+
from nextpy.jsx_transformer import JSXTransformer
|
|
176
|
+
transformer = JSXTransformer()
|
|
177
|
+
module = transformer.load_jsx_module(file_path, module_name)
|
|
178
|
+
|
|
179
|
+
# Cache the module (unless in debug mode)
|
|
180
|
+
if module and not self.debug:
|
|
181
|
+
self._modules_cache[cache_key] = module
|
|
182
|
+
|
|
183
|
+
return module
|
|
184
|
+
|
|
162
185
|
except Exception as e:
|
|
163
186
|
if self.debug:
|
|
164
187
|
print(f"Error loading module from {file_path}: {e}")
|
|
@@ -210,13 +233,29 @@ class NextPyApp:
|
|
|
210
233
|
|
|
211
234
|
if module:
|
|
212
235
|
props = await execute_data_fetching(module, context)
|
|
236
|
+
|
|
237
|
+
# Execute the page component to get JSX
|
|
238
|
+
content = ""
|
|
239
|
+
if hasattr(module, 'default'):
|
|
240
|
+
component = module.default
|
|
241
|
+
component_props = {**props, "params": params}
|
|
242
|
+
jsx_element = component(component_props)
|
|
213
243
|
|
|
244
|
+
# Convert JSX to HTML
|
|
245
|
+
try:
|
|
246
|
+
from nextpy.jsx import render_jsx
|
|
247
|
+
content = render_jsx(jsx_element)
|
|
248
|
+
except ImportError:
|
|
249
|
+
# Fail fast - JSX renderer is required
|
|
250
|
+
raise RuntimeError("JSX renderer not available. Please install nextpy.jsx module.")
|
|
251
|
+
|
|
214
252
|
template_name = self._get_template_name(route, module)
|
|
215
253
|
|
|
216
254
|
html = await self.renderer.render_async(
|
|
217
255
|
template_name,
|
|
218
256
|
context={
|
|
219
257
|
**props,
|
|
258
|
+
"content": content,
|
|
220
259
|
"params": params,
|
|
221
260
|
"query": dict(request.query_params),
|
|
222
261
|
"request": request,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nextpy-framework"
|
|
7
|
-
version = "2.4.
|
|
7
|
+
version = "2.4.6"
|
|
8
8
|
description = "A Python web framework inspired by Next.js with file-based routing, SSR, and SSG and more"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/feedback.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/form.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/head.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/image.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/layout.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/link.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/loader.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/navigation.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/toast.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/components/visual.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/data_fetching.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/demo_pages_simple.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/core/demo_router.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/hooks_provider.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/hooks_provider_new.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/jsx_preprocessor.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/jsx_transformer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/builtin.py
RENAMED
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/plugins/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/server/middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/file_upload.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nextpy_framework-2.4.4 → nextpy_framework-2.4.6}/.nextpy_framework/nextpy/utils/validators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|