Liori25 commited on
Commit
d3f3f60
ยท
verified ยท
1 Parent(s): b9b8f74

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +271 -1
app.py CHANGED
@@ -148,4 +148,274 @@ body, .gradio-container { background-color: #f0f2f5; }
148
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
149
  }
150
 
151
- .logo-area { display: flex; align-items: center; gap:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
149
  }
150
 
151
+ .logo-area { display: flex; align-items: center; gap: 20px; }
152
+ .logo-img { height: 120px; width: 120px; border-radius: 12px; object-fit: cover; border: 1px solid #ddd; }
153
+ .text-area { display: flex; flex-direction: column; }
154
+ .app-name {
155
+ font-weight: 800;
156
+ font-size: 32px;
157
+ background: -webkit-linear-gradient(45deg, #1877f2, #6b21a8);
158
+ -webkit-background-clip: text;
159
+ -webkit-text-fill-color: transparent;
160
+ line-height: 1.2;
161
+ }
162
+ .app-slogan { font-size: 16px; color: #65676b; font-weight: 500; }
163
+
164
+ /* Sidebar Navigation */
165
+ .nav-btn {
166
+ text-align: left !important;
167
+ justify-content: flex-start !important;
168
+ background: transparent !important;
169
+ border: none !important;
170
+ box-shadow: none !important;
171
+ color: #65676b !important;
172
+ font-weight: 600 !important;
173
+ font-size: 16px !important;
174
+ padding: 12px 16px !important;
175
+ border-radius: 10px !important;
176
+ transition: all 0.2s ease;
177
+ }
178
+ .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
179
+ .nav-btn.selected {
180
+ background-color: #e7f3ff !important;
181
+ color: #1877f2 !important;
182
+ border-left: 4px solid #1877f2 !important;
183
+ }
184
+
185
+ /* General Cards */
186
+ .content-card {
187
+ background: white;
188
+ border-radius: 12px;
189
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
190
+ border: 1px solid #ddd;
191
+ padding: 20px;
192
+ margin-bottom: 20px;
193
+ height: 100%;
194
+ overflow: visible !important;
195
+ }
196
+
197
+ /* Similar Recipe Cards */
198
+ .sim-card {
199
+ background: #fff;
200
+ border: 1px solid #eee;
201
+ border-radius: 8px;
202
+ padding: 15px;
203
+ height: 100%;
204
+ border-top: 4px solid #1877f2;
205
+ display: flex;
206
+ flex-direction: column;
207
+ justify-content: space-between;
208
+ }
209
+
210
+ /* FIX 1: Increased height to 400px */
211
+ .sim-scroll {
212
+ height: 400px;
213
+ overflow-y: auto;
214
+ margin-bottom: 10px;
215
+ padding-right: 5px;
216
+ font-size: 14px;
217
+ color: #4b4f56;
218
+ }
219
+
220
+ /* Right Side Trending Box */
221
+ .trend-box {
222
+ background:white;
223
+ padding:10px;
224
+ border-radius:8px;
225
+ margin-bottom:10px;
226
+ box-shadow:0 1px 2px rgba(0,0,0,0.1);
227
+ transition: background 0.2s;
228
+ }
229
+ .trend-box:hover { background: #f0f2f5; cursor: pointer; }
230
+
231
+ /* Gap Fix */
232
+ .gap-fix { gap: 25px !important; }
233
+
234
+ /* FIX 4: Center Quick Start Images */
235
+ .gradio-examples {
236
+ display: flex;
237
+ justify-content: center;
238
+ width: 100%;
239
+ }
240
+
241
+ /* Image Pop Hover Effect */
242
+ button.gallery-item {
243
+ transition: transform 0.2s ease, box-shadow 0.2s ease !important;
244
+ z-index: 1;
245
+ }
246
+ button.gallery-item:hover {
247
+ transform: scale(2.5) !important;
248
+ z-index: 1000 !important;
249
+ box-shadow: 0 10px 25px rgba(0,0,0,0.3) !important;
250
+ border: 2px solid white !important;
251
+ border-radius: 8px !important;
252
+ }
253
+ """
254
+
255
+ # ==========================================
256
+ # 5. LAYOUT CONSTRUCTION
257
+ # ==========================================
258
+ with gr.Blocks(title="Legacy Kitchen") as demo:
259
+
260
+ # --- HEADER ---
261
+ gr.HTML(f"""
262
+ <div class="custom-header">
263
+ <div class="logo-area">
264
+ <img src="data:image/jpeg;base64,{logo_b64}" class="logo-img">
265
+ <div class="text-area">
266
+ <span class="app-name">Legacy Kitchen</span>
267
+ <span class="app-slogan">Turning Handwritten Notes into a Digital Cookbook.</span>
268
+ </div>
269
+ </div>
270
+ <div style="color: #65676b; font-weight: 600;">v3.5</div>
271
+ </div>
272
+ """)
273
+
274
+ with gr.Row():
275
+
276
+ # --- LEFT SIDEBAR ---
277
+ with gr.Column(scale=1, min_width=200):
278
+ gr.HTML(f"""
279
+ <div style="display:flex; align-items:center; padding: 10px 10px 5px 10px;">
280
+ <img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; margin-right:10px; object-fit:cover;">
281
+ <b style="font-size: 16px;">My Profile</b>
282
+ </div>
283
+ """)
284
+ gr.HTML("<hr style='border: 0; border-top: 1px solid #e4e6eb; margin: 10px 0 20px 0;'>")
285
+
286
+ nav_digital = gr.Button("โœจ AI Digitizer", elem_classes=["nav-btn", "selected"])
287
+ nav_feed = gr.Button("๐Ÿ“ฐ News Feed", elem_classes=["nav-btn"])
288
+ nav_about = gr.Button("โ„น๏ธ About", elem_classes=["nav-btn"])
289
+
290
+ # --- CENTER CONTENT ---
291
+ with gr.Column(scale=3):
292
+
293
+ # === VIEW 1: AI DIGITALIZER ===
294
+ with gr.Group(visible=True) as digitalizer_view:
295
+
296
+ # SECTION 1: UPLOAD & TEXT
297
+ with gr.Row(elem_classes=["gap-fix"]):
298
+
299
+ # Left: Upload & Examples
300
+ with gr.Column(scale=1):
301
+ with gr.Group(elem_classes=["content-card"]):
302
+ input_img = gr.Image(type="filepath", label="Upload", height=300)
303
+ magic_btn = gr.Button("โœจ Convert to Digital", variant="primary", size="lg")
304
+
305
+ # Examples (Centered via CSS)
306
+ gr.Examples(
307
+ examples=[
308
+ ["quick_tries_images/applecrisp.jpg"],
309
+ ["quick_tries_images/meatballs recipe.jpg"],
310
+ ["quick_tries_images/tofu.jfif"]
311
+ ],
312
+ inputs=input_img,
313
+ label="Or try these examples:",
314
+ cache_examples=False
315
+ )
316
+
317
+ # Right: Text
318
+ with gr.Column(scale=1):
319
+ with gr.Group(elem_classes=["content-card"]):
320
+ out_text = gr.Textbox(
321
+ label="Result",
322
+ value="Here your digitalized recipe will be presented",
323
+ lines=20,
324
+ interactive=False,
325
+ show_label=False
326
+ )
327
+
328
+ gr.HTML("<div style='height: 35px;'></div>")
329
+
330
+ # SECTION 2: SIMILAR RECIPES
331
+ gr.Markdown("### 3. Similar Recipes from Database")
332
+
333
+ with gr.Row():
334
+ # CARD 1 (Always Visible, Buttons Hidden initially)
335
+ with gr.Column(elem_classes=["sim-card"]) as c1_box:
336
+ sim1 = gr.Markdown("Once you will upload your scanned recipe, we will share similar recipes!")
337
+ # FIX 2: Hidden initially
338
+ with gr.Row(visible=False) as c1_btns:
339
+ gr.Button("๐Ÿ‘ Like", size="sm", variant="secondary")
340
+ gr.Button("โ†—๏ธ Share", size="sm", variant="secondary")
341
+
342
+ # CARD 2 (Hidden initially)
343
+ with gr.Column(elem_classes=["sim-card"], visible=False) as c2_box:
344
+ sim2 = gr.Markdown("")
345
+ with gr.Row():
346
+ gr.Button("๐Ÿ‘ Like", size="sm", variant="secondary")
347
+ gr.Button("โ†—๏ธ Share", size="sm", variant="secondary")
348
+
349
+ # CARD 3 (Hidden initially)
350
+ with gr.Column(elem_classes=["sim-card"], visible=False) as c3_box:
351
+ sim3 = gr.Markdown("")
352
+ with gr.Row():
353
+ gr.Button("๐Ÿ‘ Like", size="sm", variant="secondary")
354
+ gr.Button("โ†—๏ธ Share", size="sm", variant="secondary")
355
+
356
+ # UPDATED: Button click triggers the new wrapper function
357
+ magic_btn.click(
358
+ ui_update_pipeline,
359
+ input_img,
360
+ [out_text, sim1, c1_btns, c2_box, sim2, c3_box, sim3]
361
+ )
362
+
363
+ # === VIEW 2: FEED ===
364
+ with gr.Group(visible=False) as feed_view:
365
+ with gr.Group(elem_classes=["content-card"]):
366
+ with gr.Row():
367
+ gr.HTML(f'<img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; object-fit:cover;">')
368
+ gr.Textbox(placeholder=f"What recipe are you cooking today?", show_label=False, container=False, scale=10)
369
+
370
+ if not df_recipes.empty:
371
+ feed_samples = df_recipes.sample(10)
372
+ for index, row in feed_samples.iterrows():
373
+ user_name = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
374
+ emoji = random.choice(["๐Ÿฅ˜", "๐Ÿฅ—", "๐Ÿฐ", "๐ŸŒฎ"])
375
+ with gr.Group(elem_classes=["content-card"]):
376
+ gr.HTML(f"""
377
+ <div style="display:flex; gap:10px; align-items:center; margin-bottom:12px;">
378
+ <div style="width:40px; height:40px; background:#e4e6eb; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:20px;">{emoji}</div>
379
+ <div><b>{user_name}</b><br><span style="color:gray; font-size:12px;">2h ยท ๐ŸŒ Public</span></div>
380
+ </div>
381
+ """)
382
+ gr.Markdown(f"### {row['Title']}")
383
+ gr.Markdown(f"{str(row['Raw_Output'])[:250]}...")
384
+ with gr.Row():
385
+ gr.Button("๐Ÿ‘ Like", size="sm", variant="secondary")
386
+ gr.Button("๐Ÿ’ฌ Comment", size="sm", variant="secondary")
387
+ gr.Button("โ†—๏ธ Share", size="sm", variant="secondary")
388
+ else:
389
+ gr.Markdown("โš ๏ธ Database is empty.")
390
+
391
+ # === VIEW 3: ABOUT ===
392
+ with gr.Group(visible=False) as about_view:
393
+ with gr.Group(elem_classes=["content-card"]):
394
+ gr.Markdown("# โ„น๏ธ About Legacy Kitchen\n\n**Turning Handwritten Notes into a Digital Cookbook.**")
395
+
396
+ # --- RIGHT COLUMN ---
397
+ with gr.Column(scale=1, min_width=200):
398
+ gr.Markdown("### Trending Recipes")
399
+ def trend_box(title, likes):
400
+ return f"<div class='trend-box'><b>{title}</b><br><span style='color:gray; font-size:12px;'>{likes} likes</span></div>"
401
+ gr.HTML(trend_box("๐Ÿœ Ramen Hack", "12k") + trend_box("๐Ÿช Best Cookies", "8k") + trend_box("๐Ÿฐ Cheese Cake", "15k") + trend_box("๐Ÿช Nana's Tahini Cookies", "9k"))
402
+
403
+ # ==========================================
404
+ # 6. JAVASCRIPT LOGIC
405
+ # ==========================================
406
+ def go_digi():
407
+ return (gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(elem_classes=["nav-btn", "selected"]), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn"]))
408
+
409
+ def go_feed():
410
+ return (gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn", "selected"]), gr.update(elem_classes=["nav-btn"]))
411
+
412
+ def go_about():
413
+ return (gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn", "selected"]))
414
+
415
+ outputs_ui = [digitalizer_view, feed_view, about_view, nav_digital, nav_feed, nav_about]
416
+ nav_digital.click(go_digi, None, outputs_ui)
417
+ nav_feed.click(go_feed, None, outputs_ui)
418
+ nav_about.click(go_about, None, outputs_ui)
419
+
420
+ if __name__ == "__main__":
421
+ demo.launch(theme=theme, css=modern_css)