one-for-all-framework 2.0.0 → 3.0.0

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.
data/app/views/docs.erb CHANGED
@@ -1,6 +1,6 @@
1
1
  <div class="space-y-12 pb-20">
2
2
  <div class="text-left">
3
- <div class="badge-premium">Documentation v2.0</div>
3
+ <div class="badge-premium">Documentation v3.0.0</div>
4
4
  <h1 class="text-5xl font-black tracking-tighter mb-4 text-slate-700 dark:text-white">Framework <span class="text-primary">Guide</span></h1>
5
5
  <p class="text-xl text-slate-500 max-w-2xl leading-relaxed">Everything you need to know about building premium web applications with the One-For-All framework.</p>
6
6
  </div>
@@ -15,6 +15,8 @@
15
15
  <a href="#structure" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Project Structure</a>
16
16
  <a href="#routing" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Routing System</a>
17
17
  <a href="#cms" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">CMS & Features</a>
18
+ <a href="#ecommerce" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">E-Commerce</a>
19
+ <a href="#deploy" class="block px-4 py-2 rounded-xl hover:bg-primary/5 text-slate-600 hover:text-primary transition-all font-semibold border-l-2 border-transparent hover:border-primary">Deployment</a>
18
20
  </nav>
19
21
  </aside>
20
22
 
@@ -26,7 +28,7 @@
26
28
  <i class="fas fa-star text-primary"></i> Introduction
27
29
  </h2>
28
30
  <div class="markdown-content">
29
- <p><strong>One-For-All (OFA)</strong> is a high-performance Ruby web framework focused on speed and aesthetics. It uses a modular architecture built on top of the <em>Eks-Cent</em> engine, allowing you to scale from simple landing pages to complex CMS-driven sites effortlessly.</p>
31
+ <p><strong>One-For-All (OFA)</strong> is a premium, ultra-fast Ruby MVC framework designed for developers who value both high performance and modern aesthetics. Built on the powerful <strong>Eks-Cent</strong> engine and optimized with <strong>Eksa Server</strong>, OFA v3.0 now supports <strong>Full E-Commerce integration</strong> alongside its stunning "Glassmorphism" UI.</p>
30
32
  <p>Our philosophy is "Premium by Default". You shouldn't have to spend hours tweaking CSS just to get a modern look. With OFA, you get Glassmorphism, animations, and responsive layouts baked in.</p>
31
33
  </div>
32
34
  </section>
@@ -36,71 +38,114 @@
36
38
  <h2 class="text-3xl font-black tracking-tight flex items-center gap-3 ml-2">
37
39
  <i class="fas fa-terminal text-primary"></i> CLI Power Tools
38
40
  </h2>
39
- <div class="glass-panel overflow-hidden">
40
- <table class="w-full text-left border-collapse">
41
- <thead class="bg-primary/5 border-b border-white/10">
41
+
42
+ <!-- Desktop Table View -->
43
+ <div class="hidden md:block glass-panel overflow-hidden">
44
+ <table class="w-full text-left border-collapse text-sm">
45
+ <thead class="bg-primary/5 border-b border-white/10 text-xs font-black uppercase text-slate-400">
42
46
  <tr>
43
- <th class="px-6 py-4 text-xs font-black uppercase text-slate-400">Command</th>
44
- <th class="px-6 py-4 text-xs font-black uppercase text-slate-400">Action</th>
47
+ <th class="px-6 py-4">Command</th>
48
+ <th class="px-6 py-4">Detailed Description</th>
45
49
  </tr>
46
50
  </thead>
47
51
  <tbody class="divide-y divide-white/5">
48
- <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Project Management</td></tr>
52
+ <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Project Lifecycle</td></tr>
49
53
  <tr>
50
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa new [name]</td>
51
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates a new project from scratch.</td>
54
+ <td class="px-6 py-4 font-mono text-primary">./ofa new NAME [TYPE]</td>
55
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Create a new project. Generates structure and runs bundle install automatically.</td>
52
56
  </tr>
53
57
  <tr>
54
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa init</td>
55
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Initializes environment & DB via wizard.</td>
58
+ <td class="px-6 py-4 font-mono text-primary">./ofa init [TYPE]</td>
59
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Initialize in current folder via interactive wizard for DB & Cloudinary.</td>
56
60
  </tr>
57
61
  <tr>
58
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa run</td>
59
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Starts the development server.</td>
62
+ <td class="px-6 py-4 font-mono text-primary">./ofa run</td>
63
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Starts the high-performance Eksa Server on port 3000.</td>
60
64
  </tr>
61
65
  <tr>
62
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa deploy</td>
63
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Deploys to production environment.</td>
66
+ <td class="px-6 py-4 font-mono text-primary">./ofa deploy</td>
67
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs italic">Railway/Docker/Git auto-detection for production.</td>
64
68
  </tr>
65
69
 
66
- <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Generators</td></tr>
70
+ <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Generators (Scaffolding)</td></tr>
67
71
  <tr>
68
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa g controller [name]</td>
69
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Generates a RESTful controller.</td>
72
+ <td class="px-6 py-4 font-mono text-primary">./ofa g controller NAME</td>
73
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Generates <code>app/controllers/{name}_controller.rb</code>.</td>
70
74
  </tr>
71
75
  <tr>
72
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa g model [name]</td>
73
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Generates a model & migration.</td>
76
+ <td class="px-6 py-4 font-mono text-primary">./ofa g model NAME</td>
77
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates model & migration linked to Sequel/NoSQL.</td>
74
78
  </tr>
75
79
  <tr>
76
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa g migration [name]</td>
77
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates a new schema migration.</td>
78
- </tr>
79
- <tr>
80
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa g post [title]</td>
81
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates a Markdown-based blog post.</td>
80
+ <td class="px-6 py-4 font-mono text-primary">./ofa g migration NAME</td>
81
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Creates timestamped migration in <code>db/migrations/</code>.</td>
82
82
  </tr>
83
83
 
84
- <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Configuration</td></tr>
85
- <tr>
86
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa theme [name]</td>
87
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Switch between UI themes instantly.</td>
88
- </tr>
84
+ <tr class="bg-slate-500/5"><td colspan="2" class="px-6 py-2 text-[10px] font-black uppercase tracking-tighter text-slate-400">Customization</td></tr>
89
85
  <tr>
90
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa type [type]</td>
91
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Change app mode (blog, portfolio, etc).</td>
86
+ <td class="px-6 py-4 font-mono text-primary">./ofa theme NAME</td>
87
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Switch UI: light_glass, dark_glass, cyber_sidebar, light_sidebar, retro_terminal.</td>
92
88
  </tr>
93
89
  <tr>
94
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa storage [name]</td>
95
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Configure Local or Cloudinary storage.</td>
90
+ <td class="px-6 py-4 font-mono text-primary">./ofa type NAME</td>
91
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Change mode: portfolio, blog, landing_page, e_commerce.</td>
96
92
  </tr>
97
93
  <tr>
98
- <td class="px-6 py-4 font-mono text-sm text-primary">./ofa db switch [name]</td>
99
- <td class="px-6 py-4 text-slate-600 dark:text-slate-400">Switch DB adapter (SQLite, MySQL, etc).</td>
94
+ <td class="px-6 py-4 font-mono text-primary">./ofa storage NAME</td>
95
+ <td class="px-6 py-4 text-slate-600 dark:text-slate-400 text-xs">Hot-swap storage: <code>local</code> or <code>cloudinary</code>.</td>
100
96
  </tr>
101
97
  </tbody>
102
98
  </table>
103
99
  </div>
100
+
101
+ <!-- Mobile Card View -->
102
+ <div class="md:hidden space-y-4">
103
+ <div class="glass-panel p-6 space-y-4">
104
+ <h4 class="text-[10px] font-black uppercase tracking-widest text-primary border-b border-white/5 pb-2">Project Lifecycle</h4>
105
+ <div class="space-y-4">
106
+ <div>
107
+ <code class="text-primary font-bold text-xs">./ofa new NAME [TYPE]</code>
108
+ <p class="text-slate-500 text-xs mt-1">Create a new project. Generates structure and runs bundle install automatically.</p>
109
+ </div>
110
+ <div>
111
+ <code class="text-primary font-bold text-xs">./ofa init [TYPE]</code>
112
+ <p class="text-slate-500 text-xs mt-1">Initialize in current folder via interactive wizard for DB & Cloudinary.</p>
113
+ </div>
114
+ <div>
115
+ <code class="text-primary font-bold text-xs">./ofa run</code>
116
+ <p class="text-slate-500 text-xs mt-1">Starts the high-performance Eksa Server on port 3000.</p>
117
+ </div>
118
+ </div>
119
+ </div>
120
+
121
+ <div class="glass-panel p-6 space-y-4">
122
+ <h4 class="text-[10px] font-black uppercase tracking-widest text-primary border-b border-white/5 pb-2">Scaffolding</h4>
123
+ <div class="space-y-4">
124
+ <div>
125
+ <code class="text-primary font-bold text-xs">./ofa g controller NAME</code>
126
+ <p class="text-slate-500 text-xs mt-1">Generates <code>app/controllers/{name}_controller.rb</code>.</p>
127
+ </div>
128
+ <div>
129
+ <code class="text-primary font-bold text-xs">./ofa g model NAME</code>
130
+ <p class="text-slate-500 text-xs mt-1">Creates model & migration linked to Sequel/NoSQL.</p>
131
+ </div>
132
+ </div>
133
+ </div>
134
+
135
+ <div class="glass-panel p-6 space-y-4">
136
+ <h4 class="text-[10px] font-black uppercase tracking-widest text-primary border-b border-white/5 pb-2">Customization</h4>
137
+ <div class="space-y-4">
138
+ <div>
139
+ <code class="text-primary font-bold text-xs">./ofa theme NAME</code>
140
+ <p class="text-slate-500 text-xs mt-1">Switch UI: light_glass, dark_glass, cyber_sidebar, light_sidebar, retro_terminal.</p>
141
+ </div>
142
+ <div>
143
+ <code class="text-primary font-bold text-xs">./ofa type NAME</code>
144
+ <p class="text-slate-500 text-xs mt-1">Change mode: portfolio, blog, landing_page, e_commerce.</p>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
104
149
  </section>
105
150
 
106
151
  <!-- Structure -->
@@ -108,24 +153,32 @@
108
153
  <h2 class="text-3xl font-black tracking-tight mb-6 flex items-center gap-3">
109
154
  <i class="fas fa-folder-tree text-primary"></i> Project Structure
110
155
  </h2>
111
- <div class="space-y-4">
112
- <div class="p-4 bg-slate-900 rounded-2xl font-mono text-sm text-blue-400 overflow-x-auto">
156
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
157
+ <div>
158
+ <p class="text-slate-600 dark:text-slate-400 mb-4 text-sm">OFA follows a strict MVC pattern to keep your code organized and maintainable as your project grows.</p>
159
+ <ul class="space-y-2 text-xs">
160
+ <li><strong class="text-primary uppercase tracking-widest font-black text-[10px]">/app</strong>: Core logic, models, and UI templates.</li>
161
+ <li><strong class="text-primary uppercase tracking-widest font-black text-[10px]">/config</strong>: Routing and application features.</li>
162
+ <li><strong class="text-primary uppercase tracking-widest font-black text-[10px]">/db</strong>: Migrations and data store.</li>
163
+ <li><strong class="text-primary uppercase tracking-widest font-black text-[10px]">/public</strong>: Optimized assets (CSS/JS).</li>
164
+ </ul>
165
+ </div>
166
+ <div class="p-4 bg-slate-900 rounded-2xl font-mono text-[11px] text-blue-400 overflow-x-auto border border-white/5">
113
167
  <pre>
114
168
  /app
115
- /controllers # Logic handlers
116
- /models # Database entities
117
- /views # ERB templates
169
+ /controllers # Controllers
170
+ /models # Models (Sequel/NoSQL)
171
+ /views # Views (ERB)
118
172
  /config
119
- /database.json # DB configurations
120
- /features.json # Feature toggles
173
+ /routes.rb # URL Mapping
174
+ /features.json # Feature Management
121
175
  /db
122
- /migrations # Schema versions
176
+ /migrations # Schema Evolution
123
177
  /public
124
- /images # Static assets
125
- /css # Custom styles
178
+ /images # Multimedia
179
+ /css # Tailwind/Custom
126
180
  </pre>
127
181
  </div>
128
- <p class="text-slate-500 text-sm">Most of your work will happen inside the <code>/app</code> directory following the standard MVC pattern.</p>
129
182
  </div>
130
183
  </section>
131
184
 
@@ -163,6 +216,58 @@ resources :posts
163
216
  <p>Authentication is handled via BCrypt hashing with an 8-hour session sliding expiration window for optimal security.</p>
164
217
  </div>
165
218
  </section>
219
+
220
+ <!-- E-Commerce -->
221
+ <section id="ecommerce" class="space-y-6 text-left">
222
+ <h2 class="text-3xl font-black tracking-tight flex items-center gap-3 ml-2">
223
+ <i class="fas fa-shopping-bag text-primary"></i> E-Commerce Module
224
+ </h2>
225
+ <div class="glass-panel p-8">
226
+ <p class="text-slate-600 dark:text-slate-400 mb-6">Version 3.0.0 introduces a full-featured e-commerce system. Activate it with a single command:</p>
227
+ <div class="p-4 bg-slate-900 rounded-2xl font-mono text-sm text-green-400 mb-6">
228
+ ./ofa type e_commerce
229
+ </div>
230
+ <ul class="space-y-3">
231
+ <li class="flex items-start gap-3">
232
+ <i class="fas fa-check-circle text-primary mt-1"></i>
233
+ <div><strong class="text-slate-700 dark:text-white">Shopping Cart:</strong> Fully functional cart with real-time quantity updates and session persistence.</div>
234
+ </li>
235
+ <li class="flex items-start gap-3">
236
+ <i class="fas fa-check-circle text-primary mt-1"></i>
237
+ <div><strong class="text-slate-700 dark:text-white">Product CMS:</strong> Dedicated management interface for products, inventory, and categories.</div>
238
+ </li>
239
+ <li class="flex items-start gap-3">
240
+ <i class="fas fa-check-circle text-primary mt-1"></i>
241
+ <div><strong class="text-slate-700 dark:text-white">Mobile Optimized:</strong> 100% responsive checkout and product listing pages.</div>
242
+ </li>
243
+ </ul>
244
+ </div>
245
+ </section>
246
+
247
+ <!-- Deployment -->
248
+ <section id="deploy" class="glass-panel p-8 md:p-12 text-left border-primary/20">
249
+ <h2 class="text-3xl font-black tracking-tight mb-6 flex items-center gap-3">
250
+ <i class="fas fa-rocket text-primary"></i> Deployment Guide
251
+ </h2>
252
+ <div class="space-y-8">
253
+ <div>
254
+ <h4 class="font-bold text-lg mb-2">1. Railway (Recommended)</h4>
255
+ <p class="text-slate-500 text-sm mb-4">Run <code>./ofa deploy</code>. The CLI will automatically detect your project and push it to Railway using the included Procfile.</p>
256
+ </div>
257
+ <div>
258
+ <h4 class="font-bold text-lg mb-2">2. Docker Support</h4>
259
+ <p class="text-slate-500 text-sm mb-4">Use the provided <code>Dockerfile</code> for containerized hosting on any cloud provider.</p>
260
+ <div class="p-4 bg-slate-900 rounded-2xl font-mono text-xs text-slate-400">
261
+ docker build -t ofa-app .<br>
262
+ docker run -p 3000:3000 ofa-app
263
+ </div>
264
+ </div>
265
+ <div>
266
+ <h4 class="font-bold text-lg mb-2">3. VPS Deployment</h4>
267
+ <p class="text-slate-500 text-sm mb-4">On a raw Linux server, use PM2 to manage the process and Nginx as a reverse proxy.</p>
268
+ </div>
269
+ </div>
270
+ </section>
166
271
  </div>
167
272
  </div>
168
273
  </div>
@@ -171,9 +276,17 @@ resources :posts
171
276
  document.querySelectorAll('a[href^="#"]').forEach(anchor => {
172
277
  anchor.addEventListener('click', function (e) {
173
278
  e.preventDefault();
174
- document.querySelector(this.getAttribute('href')).scrollIntoView({
175
- behavior: 'smooth'
176
- });
279
+ const target = document.querySelector(this.getAttribute('href'));
280
+ if (target) {
281
+ const headerOffset = 100;
282
+ const elementPosition = target.getBoundingClientRect().top;
283
+ const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
284
+
285
+ window.scrollTo({
286
+ top: offsetPosition,
287
+ behavior: 'smooth'
288
+ });
289
+ }
177
290
  });
178
291
  });
179
292
  </script>
data/app/views/index.erb CHANGED
@@ -1,6 +1,6 @@
1
1
  <div class="text-center space-y-6 max-w-2xl mx-auto py-12">
2
2
  <div class="inline-flex items-center px-4 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-primary text-xs font-bold uppercase tracking-wider animate-pulse">
3
- Framework Version 2.0.0
3
+ Framework Version 3.0.0
4
4
  </div>
5
5
 
6
6
  <h1 class="text-5xl md:text-7xl font-black tracking-tight leading-tight">
data/app/views/layout.erb CHANGED
@@ -316,7 +316,7 @@
316
316
  <!-- Sidebar Layout -->
317
317
  <div class="flex min-h-screen">
318
318
  <!-- Sidebar -->
319
- <aside class="fixed left-0 top-0 bottom-0 w-64 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'glass-panel !rounded-none border-r border-black/5' : 'bg-black border-r-4 border-primary' %> p-6 z-50 hidden md:flex flex-col gap-10">
319
+ <aside class="fixed left-0 top-0 bottom-0 w-64 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'glass-panel !rounded-none border-r border-black/5' : 'bg-black border-r-4 border-primary shadow-[10px_0_30px_rgba(0,0,0,0.5)]' %> p-6 pb-12 z-50 hidden md:flex flex-col gap-10 overflow-y-auto custom-scrollbar">
320
320
  <div class="flex items-center gap-3">
321
321
  <% if FEATURES_CONFIG['theme'] == 'light_sidebar' %>
322
322
  <div class="w-10 h-10 bg-primary text-white flex items-center justify-center font-black text-xl rounded-xl shadow-lg shadow-primary/20">OF</div>
@@ -331,6 +331,11 @@
331
331
  <a href="/" class="p-4 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? (req.path == '/' ? 'bg-primary/10 text-primary rounded-xl' : 'text-slate-600 hover:bg-primary/5 rounded-xl') : (req.path == '/' ? 'bg-primary text-white border-primary border-2 rounded-2xl' : 'border-white/10 text-white hover:border-primary border-2 rounded-2xl') %> font-bold transition-all">
332
332
  <i class="fas fa-grid-2 mr-3"></i> OVERVIEW
333
333
  </a>
334
+ <% if FEATURES_CONFIG['type'] == 'e_commerce' %>
335
+ <a href="/cart" class="p-4 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? (req.path == '/cart' ? 'bg-primary/10 text-primary rounded-xl' : 'text-slate-600 hover:bg-primary/5 rounded-xl') : (req.path == '/cart' ? 'bg-primary text-white border-primary border-2 rounded-2xl' : 'border-white/10 text-white hover:border-primary border-2 rounded-2xl') %> font-bold transition-all">
336
+ <i class="fas fa-shopping-cart mr-3"></i> MY CART
337
+ </a>
338
+ <% end %>
334
339
  <% Page.where(is_nav: true, is_active: true).all.each do |p| %>
335
340
  <a href="/<%= p.slug %>" class="p-4 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? (req.path == "/#{p.slug}" ? 'bg-primary/10 text-primary rounded-xl' : 'text-slate-600 hover:bg-primary/5 rounded-xl') : (req.path == "/#{p.slug}" ? 'bg-primary text-white border-primary border-2 rounded-2xl' : 'border-white/10 text-white hover:border-primary border-2 rounded-2xl') %> font-bold transition-all">
336
341
  <i class="fas fa-file-code mr-3"></i> <%= p.title.upcase %>
@@ -351,7 +356,7 @@
351
356
  UPLINK: <span class="text-primary">ENCRYPTED</span>
352
357
  <% end %>
353
358
  </div>
354
- <a href="https://github.com/IshikawaUta/one-for-all-framework" class="flex items-center justify-center w-full p-4 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'bg-slate-900 text-white rounded-xl shadow-lg shadow-slate-200' : 'bg-primary text-black border-2 border-primary rounded-2xl shadow-[4px_4px_0px_var(--secondary)]' %> font-black hover:opacity-90 hover:-translate-y-0.5 transition-all">
359
+ <a href="https://github.com/IshikawaUta/one-for-all-framework" class="flex items-center justify-center w-full p-4 mb-4 <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'bg-slate-900 text-white rounded-xl shadow-lg shadow-slate-200' : 'bg-primary text-black border-2 border-primary rounded-2xl shadow-[4px_4px_0px_var(--secondary)]' %> font-black hover:opacity-90 hover:-translate-y-0.5 transition-all">
355
360
  <i class="fab fa-github mr-2 text-lg"></i> <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'VIEW SOURCE' : 'ACCESS REPO' %>
356
361
  </a>
357
362
  </div>
@@ -368,6 +373,11 @@
368
373
  <div class="max-w-5xl mx-auto">
369
374
  <%= @content %>
370
375
  </div>
376
+
377
+ <!-- Footer -->
378
+ <footer class="w-full py-12 mt-20 border-t <%= FEATURES_CONFIG['theme'] == 'light_sidebar' ? 'border-black/5' : 'border-white/5' %> text-center text-slate-500 text-sm">
379
+ <p>&copy; <%= Time.now.year %> One-For-All Framework.</p>
380
+ </footer>
371
381
  </main>
372
382
  </div>
373
383
  <% else %>
@@ -380,6 +390,9 @@
380
390
 
381
391
  <ul class="hidden md:flex items-center gap-8">
382
392
  <li><a href="/" class="nav-item <%= req.path == '/' ? 'active' : '' %>">Home</a></li>
393
+ <% if FEATURES_CONFIG['type'] == 'e_commerce' %>
394
+ <li><a href="/cart" class="nav-item <%= req.path == '/cart' ? 'active' : '' %>"><i class="fas fa-shopping-cart mr-1"></i> Cart</a></li>
395
+ <% end %>
383
396
  <% Page.where(is_nav: true, is_active: true).all.each do |p| %>
384
397
  <li><a href="/<%= p.slug %>" class="nav-item <%= req.path == "/#{p.slug}" ? 'active' : '' %>"><%= p.title %></a></li>
385
398
  <% end %>
@@ -396,8 +409,13 @@
396
409
  </header>
397
410
 
398
411
 
399
- <main class="container mx-auto max-w-4xl px-6 py-12">
412
+ <main class="container mx-auto max-w-6xl px-6 py-12">
400
413
  <%= @content %>
414
+
415
+ <!-- Footer -->
416
+ <footer class="w-full py-12 mt-20 border-t border-white/5 text-center text-slate-500 text-sm">
417
+ <p>&copy; <%= Time.now.year %> One-For-All Framework.</p>
418
+ </footer>
401
419
  </main>
402
420
  <% end %>
403
421
 
@@ -416,6 +434,11 @@
416
434
  <a href="/" class="text-lg font-bold <%= req.path == '/' ? 'text-primary' : 'text-slate-500' %>">
417
435
  <i class="fas fa-home w-8"></i> Home
418
436
  </a>
437
+ <% if FEATURES_CONFIG['type'] == 'e_commerce' %>
438
+ <a href="/cart" class="text-lg font-bold <%= req.path == '/cart' ? 'text-primary' : 'text-slate-500' %>">
439
+ <i class="fas fa-shopping-cart w-8"></i> Cart
440
+ </a>
441
+ <% end %>
419
442
  <% Page.where(is_nav: true, is_active: true).all.each do |p| %>
420
443
  <a href="/<%= p.slug %>" class="text-lg font-bold <%= req.path == "/#{p.slug}" ? 'text-primary' : 'text-slate-500' %>">
421
444
  <i class="fas fa-file-alt w-8"></i> <%= p.title %>
@@ -435,10 +458,6 @@
435
458
  </div>
436
459
  </div>
437
460
 
438
- <!-- Footer -->
439
- <footer class="w-full py-12 mt-20 border-t border-white/5 text-center text-slate-500 text-sm">
440
- <p>&copy; <%= Time.now.year %> One-For-All Framework.</p>
441
- </footer>
442
461
 
443
462
  <script>
444
463
  document.addEventListener('DOMContentLoaded', () => {
@@ -0,0 +1,42 @@
1
+ <div class="mb-8">
2
+ <a href="/products" class="text-slate-400 hover:text-primary transition-colors">
3
+ <i class="fas fa-arrow-left mr-2"></i> Back to Shop
4
+ </a>
5
+ </div>
6
+
7
+ <div class="glass-panel p-8 md:p-12">
8
+ <div class="flex flex-col md:flex-row gap-12">
9
+ <div class="w-full md:w-1/2 aspect-square rounded-3xl overflow-hidden bg-slate-900/50 shadow-2xl">
10
+ <img src="<%= @product.image_url || '/images/logo.png' %>" class="w-full h-full object-cover">
11
+ </div>
12
+
13
+ <div class="w-full md:w-1/2 flex flex-col justify-center">
14
+ <div class="badge-premium"><%= @product.category || 'General' %></div>
15
+ <h1 class="text-4xl md:text-5xl font-black mb-4 tracking-tighter"><%= @product.name %></h1>
16
+ <div class="text-3xl font-bold text-primary mb-6">$<%= @product.price %></div>
17
+
18
+ <div class="markdown-content mb-10">
19
+ <%= markdown(@product.description) %>
20
+ </div>
21
+
22
+ <div class="flex items-center gap-6">
23
+ <form action="/cart/add" method="POST" class="flex items-center gap-4">
24
+ <%= csrf_tag %>
25
+ <input type="hidden" name="product_id" value="<%= @product.id %>">
26
+ <div class="flex items-center glass-panel !rounded-xl overflow-hidden">
27
+ <button type="button" onclick="this.nextElementSibling.stepDown()" class="px-4 py-2 hover:bg-white/5">-</button>
28
+ <input type="number" name="qty" value="1" min="1" class="w-12 bg-transparent text-center font-bold focus:outline-none">
29
+ <button type="button" onclick="this.previousElementSibling.stepUp()" class="px-4 py-2 hover:bg-white/5">+</button>
30
+ </div>
31
+ <button type="submit" class="btn-premium flex-1">
32
+ <i class="fas fa-shopping-cart mr-2"></i> Add to Cart
33
+ </button>
34
+ </form>
35
+ </div>
36
+
37
+ <div class="mt-8 pt-8 border-t border-white/5 text-sm text-slate-500">
38
+ <i class="fas fa-cubes mr-2"></i> Stock available: <%= @product.stock %> items
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
@@ -0,0 +1,40 @@
1
+ <div class="text-center mb-16">
2
+ <div class="badge-premium">E-Commerce Mode</div>
3
+ <h1 class="text-5xl font-black mb-4 tracking-tighter">Premium Shop</h1>
4
+ <p class="text-slate-500 text-lg">Curated collection of state-of-the-art digital assets.</p>
5
+ </div>
6
+
7
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
8
+ <% @products.each do |product| %>
9
+ <div class="glass-card group">
10
+ <div class="card-glow"></div>
11
+ <div class="aspect-video mb-6 rounded-2xl overflow-hidden bg-slate-900/50 relative">
12
+ <img src="<%= product.image_url || '/images/logo.png' %>" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700">
13
+ <div class="absolute top-4 right-4 bg-primary text-white font-black px-4 py-2 rounded-xl shadow-xl">
14
+ $<%= product.price %>
15
+ </div>
16
+ </div>
17
+ <h3 class="text-2xl font-black mb-2"><%= product.name %></h3>
18
+ <p class="text-slate-500 mb-6 line-clamp-2"><%= product.description %></p>
19
+
20
+ <div class="flex items-center justify-between mt-auto">
21
+ <a href="/products/<%= product.slug %>" class="btn-secondary">Details</a>
22
+ <form action="/cart/add" method="POST">
23
+ <%= csrf_tag %>
24
+ <input type="hidden" name="product_id" value="<%= product.id %>">
25
+ <button type="submit" class="btn-premium">
26
+ <i class="fas fa-shopping-cart mr-2"></i> Add to Cart
27
+ </button>
28
+ </form>
29
+ </div>
30
+ </div>
31
+ <% end %>
32
+
33
+ <% if @products.empty? %>
34
+ <div class="col-span-full glass-card text-center py-20">
35
+ <i class="fas fa-box-open text-6xl text-slate-300 mb-6"></i>
36
+ <h2 class="text-2xl font-bold text-slate-400">No products available yet.</h2>
37
+ <p class="text-slate-500">Visit dashboard to add your first product.</p>
38
+ </div>
39
+ <% end %>
40
+ </div>
data/bin/ofa CHANGED
@@ -34,7 +34,7 @@ def help
34
34
  puts " ofa g migration NAME - Generate a new migration"
35
35
  puts " ofa g post TITLE - Create a new post [args: --category, --author, --image]"
36
36
  puts " ofa feature ACTION F - Toggle features: action=enable/disable, F=cms/auth"
37
- puts " ofa type NAME - Set application type: portfolio, blog, landing_page"
37
+ puts " ofa type NAME - Set application type: portfolio, blog, landing_page, e_commerce"
38
38
  puts " ofa theme NAME - Set UI theme: light_glass, dark_glass, cyber_sidebar, retro_terminal, light_sidebar"
39
39
  puts " ofa storage NAME - Set image storage: local, cloudinary"
40
40
  puts " ofa reset-password USR PWD - Reset admin account password"
@@ -49,6 +49,7 @@ end
49
49
 
50
50
  def run_migrations
51
51
  Object.const_set(:APP_ROOT, PROJECT_ROOT) unless defined?(APP_ROOT)
52
+ ENV['SKIP_MODELS'] = '1'
52
53
  require File.join(FRAMEWORK_ROOT, 'config', 'boot')
53
54
  puts "Running migrations..."
54
55
  migration_path = File.join(PROJECT_ROOT, "db/migrations")
@@ -322,6 +323,14 @@ when 'init'
322
323
  def index; end
323
324
  end
324
325
  RUBY
326
+ when 'e_commerce'
327
+ puts " Scaffolding E-Commerce starter..."
328
+ File.write(File.join(PROJECT_ROOT, 'app/controllers/products_controller.rb'), <<~RUBY)
329
+ require_relative 'application_controller'
330
+ class ProductsController < ApplicationController
331
+ def index; end
332
+ end
333
+ RUBY
325
334
  end
326
335
 
327
336
  puts "Done! Run 'ofa run' to start your app."
@@ -396,8 +405,8 @@ when 'feature'
396
405
  when 'type'
397
406
  ensure_initialized!
398
407
  name = ARGV.shift
399
- unless %w[landing_page portfolio blog].include?(name)
400
- puts "❌ Error: Invalid app type '#{name}'. Choose: landing_page, portfolio, blog."
408
+ unless %w[landing_page portfolio blog e_commerce].include?(name)
409
+ puts "❌ Error: Invalid app type '#{name}'. Choose: landing_page, portfolio, blog, e_commerce."
401
410
  exit 1
402
411
  end
403
412
  config_path = File.join(PROJECT_ROOT, 'config', 'features.json')
data/config/boot.rb CHANGED
@@ -76,6 +76,7 @@ require_relative 'database'
76
76
  # Autoloading (Framework Core first, then APP_ROOT)
77
77
  framework_app = File.expand_path('../app', __dir__)
78
78
  ['controllers', 'models', 'middleware', 'helpers'].each do |folder|
79
+ next if folder == 'models' && ENV['SKIP_MODELS']
79
80
  loaded = []
80
81
  # Load framework core
81
82
  Dir.glob(File.join(framework_app, folder, '*.rb')).each do |f|
data/config/routes.rb CHANGED
@@ -11,11 +11,42 @@ ROUTES = EksCent::Router.new do
11
11
  when 'blog'
12
12
  posts = Post.where(is_active: true).order(Sequel.desc(:created_at)).all
13
13
  res.render 'blog_home', title: "Blog - One-For-All", posts: posts
14
+ when 'e_commerce'
15
+ ProductsController.new(req, res).index
14
16
  else
15
17
  res.render 'index', title: "One-For-All Framework"
16
18
  end
17
19
  end
18
20
 
21
+ # --- E-Commerce Routes ---
22
+ get '/products' do |req, res|
23
+ ProductsController.new(req, res).index
24
+ end
25
+
26
+ get '/products/:slug' do |req, res|
27
+ ProductsController.new(req, res).show
28
+ end
29
+
30
+ get '/cart' do |req, res|
31
+ CartController.new(req, res).index
32
+ end
33
+
34
+ post '/cart/add' do |req, res|
35
+ CartController.new(req, res).add
36
+ end
37
+
38
+ post '/cart/update' do |req, res|
39
+ CartController.new(req, res).update
40
+ end
41
+
42
+ post '/cart/remove' do |req, res|
43
+ CartController.new(req, res).remove
44
+ end
45
+
46
+ post '/cart/clear' do |req, res|
47
+ CartController.new(req, res).clear
48
+ end
49
+
19
50
  get '/docs' do |req, res|
20
51
  res.render 'docs', title: "Documentation - One-For-All"
21
52
  end
@@ -33,6 +64,7 @@ ROUTES = EksCent::Router.new do
33
64
  resources :pages, prefix: '/dashboard'
34
65
  resources :posts, prefix: '/dashboard'
35
66
  resources :projects, prefix: '/dashboard'
67
+ resources :products, prefix: '/dashboard'
36
68
 
37
69
  # Auth Routes
38
70
  get '/login' do |req, res|
Binary file
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table(:products) do
4
+ primary_key :id
5
+ String :name, null: false
6
+ String :slug, null: false, unique: true
7
+ String :description, text: true
8
+ Float :price, default: 0.0
9
+ Integer :stock, default: 0
10
+ String :image_url
11
+ String :category
12
+ TrueClass :is_active, default: true
13
+ DateTime :created_at
14
+ DateTime :updated_at
15
+ end
16
+ end
17
+ end