File size: 35,053 Bytes
72eef4f
 
85354fe
 
 
 
 
 
72eef4f
85354fe
 
72eef4f
 
 
85354fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6af31ea
 
 
85354fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6af31ea
 
85354fe
6af31ea
 
85354fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6af31ea
 
 
 
 
 
 
 
 
 
 
85354fe
 
 
 
 
6af31ea
 
85354fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6af31ea
 
 
 
 
 
 
 
 
 
 
85354fe
 
 
 
 
 
 
6af31ea
 
 
 
 
 
 
 
 
 
 
 
 
 
85354fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72eef4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85354fe
72eef4f
 
 
 
 
 
85354fe
72eef4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
# your_app/page_features.py

import os
import json
import requests
from flask import Blueprint, request, jsonify, redirect, render_template_string, flash

# Assuming extensions.py exists and is configured correctly
from .extensions import mongo
# For standalone running, we'll create a mock mongo object


page_bp = Blueprint('pages', __name__)

# --- Vercel Configuration (as provided) ---
VERCEL_TOKEN = "azm0JC5lyPwah6qPGhbN5DL5"
PROJECT_ID = "prj_4RemrVT2H255cTcdXxkLqFJUD6Dq"
# Vercel Team ID is optional. Only include it if your project is under a team.
TEAM_ID = None # Set to your Team ID string if applicable, otherwise None or False
PROJECT_NAME = "matax-express"

# --- Default Data Structures (as provided) ---
# These are used as fallbacks if fetching from Vercel fails.
DEFAULT_WHY_US_FEATURES_DATA = [
  { "icon": "EnergySavingsLeafIcon", "title": "Peak Freshness", "description": "Guaranteed farm-to-door freshness in every order." },
  { "icon": "YardIcon", "title": "Local Sourcing", "description": "Partnering with local farms to support the community." },
  { "icon": "CategoryIcon", "title": "Wide Selection", "description": "A diverse range of produce, dairy, and pantry staples." },
  { "icon": "LocalShippingIcon", "title": "Reliable Delivery", "description": "On-time, refrigerated delivery you can count on." },
]

DEFAULT_FAQS_DATA = [
  { "question": "What regions do you deliver to?", "answer": "We currently deliver to all major metropolitan areas within the state. We are actively expanding our delivery network, so please check back for updates on new regions." },
  { "question": "How do I place an order?", "answer": "Once you register for an account and are approved, you can log in to our customer portal. From there, you can browse our product catalog, select quantities, and schedule your delivery." },
  { "question": "What are your quality standards?", "answer": "We pride ourselves on sourcing only the freshest, Grade A produce from trusted local and national farms. Every item is inspected for quality and freshness before it leaves our facility." },
  { "question": "Is there a minimum order requirement?", "answer": "Yes, there is a minimum order value for delivery. This amount varies by region. You can find the specific minimum for your area in your customer portal after logging in." },
]

# --- Vercel API Helper Functions (Integrated into Flask App) ---
# Note: These functions have been slightly modified to append log messages to a list
# for display in the UI, rather than printing to the console.

def get_existing_env_var(key, headers, params, logs):
    """Fetches a specific environment variable by key."""
    api_url = f"https://api.vercel.com/v9/projects/{PROJECT_ID}/env"
    try:
        response = requests.get(api_url, headers=headers, params=params, timeout=10)
        response.raise_for_status()
        all_vars = response.json().get('envs', [])
        for var in all_vars:
            if var['key'] == key:
                logs.append(f"INFO: Found existing variable '{key}' with ID: {var['id']}")
                return var
        logs.append(f"INFO: No existing environment variable found with key '{key}'.")
        return None
    except requests.exceptions.RequestException as err:
        logs.append(f"❌ ERROR: Error fetching environment variables: {err}")
        return None

def delete_env_var(var_id, headers, params, logs):
    """Deletes an environment variable by its ID."""
    logs.append(f"ATTEMPT: Deleting variable with ID: {var_id}")
    api_url = f"https://api.vercel.com/v9/projects/{PROJECT_ID}/env/{var_id}"
    try:
        response = requests.delete(api_url, headers=headers, params=params, timeout=10)
        response.raise_for_status()
        logs.append(f"✅ SUCCESS: Successfully deleted variable.")
        return True
    except requests.exceptions.RequestException as err:
        logs.append(f"❌ ERROR: Error deleting environment variable: {err}")
        return False

def create_env_var(key, value_obj, target_environments, headers, params, logs):
    """Creates a new environment variable."""
    logs.append(f"ATTEMPT: Creating new environment variable '{key}'...")
    api_url = f"https://api.vercel.com/v9/projects/{PROJECT_ID}/env"
    payload = {
        "key": key,
        "value": json.dumps(value_obj),
        "type": "encrypted",
        "target": target_environments,
    }
    try:
        response = requests.post(api_url, headers=headers, json=payload, params=params, timeout=10)
        response.raise_for_status()
        logs.append(f"✅ SUCCESS: Successfully created environment variable '{key}'.")
        return True
    except requests.exceptions.RequestException as err:
        logs.append(f"❌ ERROR: HTTP Error creating '{key}': {err}")
        if err.response:
            logs.append(f"   Response Body: {err.response.text}")
        return False

def set_vercel_env_var(key, value_obj, target_environments, logs):
    """Orchestrates deleting and recreating a Vercel environment variable."""
    logs.append(f"--- Processing environment variable: {key} ---")
    headers = {"Authorization": f"Bearer {VERCEL_TOKEN}"}
    params = {"teamId": TEAM_ID} if TEAM_ID else {}

    existing_var = get_existing_env_var(key, headers, params, logs)

    if existing_var:
        if not delete_env_var(existing_var['id'], headers, params, logs):
            logs.append(f"CRITICAL: Aborting update for '{key}' due to deletion failure.")
            return False

    return create_env_var(key, value_obj, target_environments, headers, params, logs)

def get_project_git_info(headers, params, logs):
    """Fetches project Git info required for deployment."""
    logs.append("INFO: Fetching project details to find Git repo ID...")
    api_url = f"https://api.vercel.com/v9/projects/{PROJECT_ID}"
    try:
        response = requests.get(api_url, headers=headers, params=params, timeout=10)
        response.raise_for_status()
        project_data = response.json()
        link_info = project_data.get('link')
        if not link_info or 'repoId' not in link_info or 'type' not in link_info:
            logs.append("❌ ERROR: Could not find linked Git repository information (repoId).")
            logs.append("   Ensure your Vercel project is connected to a Git repository.")
            return None, None

        repo_id = link_info['repoId']
        git_type = link_info['type']
        logs.append(f"✅ SUCCESS: Found Git repo ID: {repo_id} (type: {git_type})")
        return repo_id, git_type
    except requests.exceptions.RequestException as err:
        logs.append(f"❌ ERROR: Error fetching project details: {err}")
        return None, None

def trigger_vercel_deployment(logs):
    """Triggers a new Vercel deployment."""
    logs.append("\n--- Triggering new Vercel deployment ---")
    headers = {"Authorization": f"Bearer {VERCEL_TOKEN}", "Content-Type": "application/json"}
    params = {"teamId": TEAM_ID} if TEAM_ID else {}

    repo_id, git_type = get_project_git_info(headers, params, logs)
    if not repo_id:
        logs.append("CRITICAL: Aborting deployment trigger due to missing Git info.")
        return False

    api_url = "https://api.vercel.com/v13/deployments"
    payload = {
        "name": PROJECT_NAME,
        "target": "production",
        "gitSource": {
            "type": git_type,
            "repoId": repo_id,
            "ref": "main" # Change 'main' to your default branch if it's different
        }
    }

    try:
        response = requests.post(api_url, headers=headers, json=payload, params=params, timeout=15)
        response.raise_for_status()
        deployment_url = response.json().get('url')
        logs.append(f"✅✅✅ SUCCESS: Successfully triggered new deployment!")
        logs.append(f"   Inspect deployment status at: https://{deployment_url}")
        return True
    except requests.exceptions.HTTPError as err:
        logs.append(f"❌ ERROR: HTTP Error triggering deployment: {err}")
        logs.append(f"   Response Body: {err.response.text}")
        return False
    except Exception as err:
        logs.append(f"❌ ERROR: An unexpected error occurred while triggering deployment: {err}")
        return False


# --- NEW ENDPOINT AND UI FOR HOMEPAGE CONTENT ---

@page_bp.route('/edit_homepage', methods=['GET', 'POST'])
def edit_homepage():
    """

    Provides a UI to edit homepage content (FAQs, Why Us) and deploy changes to Vercel.

    """
    logs = []
    
    # --- POST Request: Handle form submission ---
    if request.method == 'POST':
        # The form data for 'why_us_features' and 'faqs' is now assembled by client-side JavaScript
        # into JSON strings, so the backend logic can remain the same.
        why_us_json_str = request.form.get('why_us_features')
        faqs_json_str = request.form.get('faqs')
        
        # Get the price slider value. request.form.get will be 'on' if checked, None if not.
        price_enabled_bool = True if request.form.get('price_enabled') == 'on' else False

        try:
            # Validate and parse the submitted JSON
            why_us_data = json.loads(why_us_json_str)
            faqs_data = json.loads(faqs_json_str)
        except json.JSONDecodeError as e:
            # If JSON is invalid, render the result page with an error
            logs.append(f"❌ CRITICAL ERROR: Invalid JSON format submitted. Please correct and try again.")
            logs.append(f"   Details: {e}")
            return render_template_string(RESULT_PAGE_TEMPLATE, logs="\n".join(logs), status_class="error")

        target_environments = ["production", "preview", "development"]
        
        # Update the environment variables on Vercel
        success1 = set_vercel_env_var("REACT_APP_WHY_US_FEATURES", why_us_data, target_environments, logs)
        logs.append("\n")
        success2 = set_vercel_env_var("REACT_APP_FAQS", faqs_data, target_environments, logs)
        logs.append("\n")
        success3 = set_vercel_env_var("REACT_APP_PRICE", price_enabled_bool, target_environments, logs)
        
        # If ALL variable updates were successful, trigger deployment
        if success1 and success2 and success3:
            trigger_vercel_deployment(logs)
        else:
            logs.append("\nSkipping deployment due to errors in updating environment variables.")

        status_class = "success" if "✅✅✅ SUCCESS" in "".join(logs) else "error"
        return render_template_string(RESULT_PAGE_TEMPLATE, logs="\n".join(logs), status_class=status_class)

    # --- GET Request: Display the editor UI ---
    else:
        # Fetch current data from Vercel to populate the editor
        headers = {"Authorization": f"Bearer {VERCEL_TOKEN}"}
        params = {"teamId": TEAM_ID} if TEAM_ID else {}

        # Fetch "Why Us" data
        why_us_var = get_existing_env_var("REACT_APP_WHY_US_FEATURES", headers, params, [])
        if why_us_var and 'value' in why_us_var:
            try:
                why_us_data = json.loads(why_us_var['value'])
            except json.JSONDecodeError:
                why_us_data = DEFAULT_WHY_US_FEATURES_DATA
        else:
            why_us_data = DEFAULT_WHY_US_FEATURES_DATA

        # Fetch "FAQs" data
        faqs_var = get_existing_env_var("REACT_APP_FAQS", headers, params, [])
        if faqs_var and 'value' in faqs_var:
            try:
                faqs_data = json.loads(faqs_var['value'])
            except json.JSONDecodeError:
                faqs_data = DEFAULT_FAQS_DATA
        else:
            faqs_data = DEFAULT_FAQS_DATA

        # Fetch Price Enabled status
        price_var = get_existing_env_var("REACT_APP_PRICE", headers, params, [])
        price_enabled = False # Default to false
        if price_var and 'value' in price_var:
            try:
                # The value from Vercel is a JSON string, e.g., 'true' or 'false'
                price_enabled = json.loads(price_var['value'])
            except (json.JSONDecodeError, TypeError):
                 # Fallback for older non-JSON values if they exist
                price_enabled = price_var['value'].lower() == 'true'
        
        # Pass the Python objects directly to the template for the interactive UI
        return render_template_string(
            EDITOR_UI_TEMPLATE, 
            why_us_data=why_us_data,
            faqs_data=faqs_data,
            price_enabled=price_enabled
        )

# --- HTML Templates for the new endpoint ---

EDITOR_UI_TEMPLATE = """

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Edit Homepage Content & Deploy</title>

    <style>

        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; background-color: #f8f9fa; color: #212529; }

        .container { max-width: 960px; margin: 2em auto; padding: 0 1em; }

        h1, h2 { color: #343a40; border-bottom: 2px solid #dee2e6; padding-bottom: 0.5em; margin-top: 1.5em;}

        form { background: white; padding: 2em; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }

        

        /* New Interactive Editor Styles */

        .editor-section { margin-bottom: 2.5em; }

        .editor-item {

            background-color: #f8f9fa;

            border: 1px solid #dee2e6;

            border-radius: 6px;

            padding: 1.5em;

            margin-bottom: 1em;

            position: relative;

        }

        .input-group { margin-bottom: 1em; }

        .input-group:last-child { margin-bottom: 0; }

        .input-group label {

            display: block;

            margin-bottom: 0.5em;

            font-weight: bold;

            color: #495057;

            font-size: 0.9em;

        }

        .input-group input[type="text"], .input-group textarea {

            width: 100%;

            padding: 0.8em;

            border: 1px solid #ced4da;

            border-radius: 4px;

            box-sizing: border-box;

            font-size: 0.95rem;

            font-family: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace;

        }

        .input-group textarea {

            min-height: 100px;

            resize: vertical;

        }

        .remove-btn {

            position: absolute;

            top: 10px;

            right: 10px;

            background-color: #dc3545;

            color: white;

            border: none;

            border-radius: 50%;

            width: 24px;

            height: 24px;

            font-size: 16px;

            line-height: 24px;

            text-align: center;

            cursor: pointer;

            font-weight: bold;

        }

        .remove-btn:hover { background-color: #c82333; }

        .add-btn {

            background-color: #007bff;

            color: white;

            padding: 0.6em 1.2em;

            border: none;

            border-radius: 4px;

            cursor: pointer;

            font-size: 1em;

            font-weight: bold;

            display: inline-block;

            margin-top: 0.5em;

        }

        .add-btn:hover { background-color: #0056b3; }



        .deploy-button { background-color: #28a745; color: white; padding: 0.8em 1.5em; border: none; border-radius: 4px; cursor: pointer; font-size: 1.2em; font-weight: bold; display: block; width: 100%; margin-top: 2em; transition: background-color 0.2s; }

        .deploy-button:hover { background-color: #218838; }



        /* --- Slider switch styles --- */

        .setting-group { display: flex; align-items: center; justify-content: space-between; padding: 0 0.5em; }

        .setting-group > label { margin-bottom: 0; font-size: 1em; font-weight: normal; color: #212529; }

        .switch { position: relative; display: inline-block; width: 60px; height: 34px; }

        .switch input { opacity: 0; width: 0; height: 0; }

        .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; border-radius: 34px; }

        .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; border-radius: 50%; }

        input:checked + .slider { background-color: #28a745; }

        input:focus + .slider { box-shadow: 0 0 1px #28a745; }

        input:checked + .slider:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); }

    </style>

</head>

<body>

    <div class="container">

        <h1>Edit Homepage Content & Deploy</h1>

        <form id="main-form" action="/api/pages/edit_homepage" method="post">

            

            <!-- --- Price Enable/Disable Slider --- -->

            <div class="editor-section">

                <h2>General Settings</h2>

                <div class="editor-item">

                    <div class="setting-group">

                        <label for="price-toggle">Enable Price Display</label>

                        <label class="switch">

                            <input type="checkbox" id="price-toggle" name="price_enabled" {% if price_enabled %}checked{% endif %}>

                            <span class="slider"></span>

                        </label>

                    </div>

                </div>

            </div>



            <div class="editor-section">

                <h2>'Why Us' Features</h2>

                <div id="why-us-editor">

                    {% for feature in why_us_data %}

                    <div class="editor-item why-us-item">

                        <button type="button" class="remove-btn" title="Remove Feature">×</button>

                        <div class="input-group">

                            <label>Icon Name (e.g., EnergySavingsLeafIcon)</label>

                            <input type="text" class="why-us-icon" value="{{ feature.icon | e }}">

                        </div>

                        <div class="input-group">

                            <label>Title</label>

                            <input type="text" class="why-us-title" value="{{ feature.title | e }}">

                        </div>

                        <div class="input-group">

                            <label>Description</label>

                            <input type="text" class="why-us-desc" value="{{ feature.description | e }}">

                        </div>

                    </div>

                    {% endfor %}

                </div>

                <button type="button" id="add-why-us-btn" class="add-btn">+ Add Feature</button>

                <textarea id="why_us_features" name="why_us_features" style="display: none;"></textarea>

            </div>



            <div class="editor-section">

                <h2>FAQs</h2>

                 <div id="faq-editor">

                    {% for faq in faqs_data %}

                    <div class="editor-item faq-item">

                        <button type="button" class="remove-btn" title="Remove FAQ">×</button>

                        <div class="input-group">

                            <label>Question</label>

                            <input type="text" class="faq-question" value="{{ faq.question | e }}">

                        </div>

                        <div class="input-group">

                            <label>Answer</label>

                            <textarea class="faq-answer">{{ faq.answer }}</textarea>

                        </div>

                    </div>

                    {% endfor %}

                </div>

                <button type="button" id="add-faq-btn" class="add-btn">+ Add FAQ</button>

                <textarea id="faqs" name="faqs" style="display: none;"></textarea>

            </div>

            

            <button type="submit" class="deploy-button">Save and Deploy to Vercel</button>

        </form>

    </div>



<script>

document.addEventListener('DOMContentLoaded', function() {

    

    // --- 'Why Us' Section Logic ---



    const whyUsEditor = document.getElementById('why-us-editor');

    const addWhyUsBtn = document.getElementById('add-why-us-btn');



    // Add new 'Why Us' feature

    addWhyUsBtn.addEventListener('click', () => {

        const newItem = document.createElement('div');

        newItem.className = 'editor-item why-us-item';

        newItem.innerHTML = `

            <button type="button" class="remove-btn" title="Remove Feature">×</button>

            <div class="input-group">

                <label>Icon Name (e.g., EnergySavingsLeafIcon)</label>

                <input type="text" class="why-us-icon" value="">

            </div>

            <div class="input-group">

                <label>Title</label>

                <input type="text" class="why-us-title" value="">

            </div>

            <div class="input-group">

                <label>Description</label>

                <input type="text" class="why-us-desc" value="">

            </div>

        `;

        whyUsEditor.appendChild(newItem);

    });



    // Remove 'Why Us' feature (using event delegation)

    whyUsEditor.addEventListener('click', (e) => {

        if (e.target && e.target.classList.contains('remove-btn')) {

            e.target.closest('.editor-item').remove();

        }

    });





    // --- FAQ Section Logic ---



    const faqEditor = document.getElementById('faq-editor');

    const addFaqBtn = document.getElementById('add-faq-btn');



    // Add new FAQ

    addFaqBtn.addEventListener('click', () => {

        const newItem = document.createElement('div');

        newItem.className = 'editor-item faq-item';

        newItem.innerHTML = `

            <button type="button" class="remove-btn" title="Remove FAQ">×</button>

            <div class="input-group">

                <label>Question</label>

                <input type="text" class="faq-question" value="">

            </div>

            <div class="input-group">

                <label>Answer</label>

                <textarea class="faq-answer"></textarea>

            </div>

        `;

        faqEditor.appendChild(newItem);

    });



    // Remove FAQ (using event delegation)

    faqEditor.addEventListener('click', (e) => {

        if (e.target && e.target.classList.contains('remove-btn')) {

            e.target.closest('.editor-item').remove();

        }

    });





    // --- Form Submission Logic ---



    const mainForm = document.getElementById('main-form');

    mainForm.addEventListener('submit', (e) => {

        // Serialize 'Why Us' data into hidden textarea

        const whyUsData = [];

        document.querySelectorAll('.why-us-item').forEach(item => {

            const icon = item.querySelector('.why-us-icon').value.trim();

            const title = item.querySelector('.why-us-title').value.trim();

            const description = item.querySelector('.why-us-desc').value.trim();

            if (icon && title && description) {

                whyUsData.push({ icon, title, description });

            }

        });

        document.getElementById('why_us_features').value = JSON.stringify(whyUsData, null, 2);



        // Serialize FAQ data into hidden textarea

        const faqsData = [];

        document.querySelectorAll('.faq-item').forEach(item => {

            const question = item.querySelector('.faq-question').value.trim();

            const answer = item.querySelector('.faq-answer').value.trim();

            if (question && answer) {

                faqsData.push({ question, answer });

            }

        });

        document.getElementById('faqs').value = JSON.stringify(faqsData, null, 2);

        

        // Quick validation to prevent submitting empty arrays

        if (document.querySelectorAll('.why-us-item').length > 0 && whyUsData.length === 0) {

             alert('A "Why Us" feature has empty fields. Please fill them out or remove the item.');

             e.preventDefault(); // Stop form submission

             return;

        }

        if (document.querySelectorAll('.faq-item').length > 0 && faqsData.length === 0) {

             alert('An FAQ has empty fields. Please fill them out or remove the item.');

             e.preventDefault(); // Stop form submission

             return;

        }



    });



});

</script>



</body>

</html>

"""

RESULT_PAGE_TEMPLATE = """

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Deployment Status</title>

    <style>

        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; background-color: #f8f9fa; color: #212529; }

        .container { max-width: 960px; margin: 2em auto; padding: 2em; background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }

        h1 { color: #343a40; border-bottom: 2px solid #dee2e6; padding-bottom: 0.5em; margin-bottom: 1em; }

        h1.success { color: #28a745; }

        h1.error { color: #dc3545; }

        pre { background-color: #e9ecef; color: #495057; padding: 1.5em; border-radius: 4px; white-space: pre-wrap; word-wrap: break-word; font-size: 0.9rem; line-height: 1.6; }

        .back-link { display: inline-block; margin-top: 1.5em; background-color: #007bff; color: white; padding: 0.6em 1.2em; border-radius: 4px; text-decoration: none; font-weight: bold; }

        .back-link:hover { background-color: #0056b3; }

    </style>

</head>

<body>

    <div class="container">

        <h1 class="{{ status_class }}">Deployment Process Log</h1>

        <pre>{{ logs }}</pre>

        <a href="/api/pages/edit_homepage" class="back-link">&larr; Back to Editor</a>

    </div>

</body>

</html>

"""


# --- PRE-EXISTING CODE (UNCHANGED) ---

# Default data for initialization if pages don't exist in the database
DEFAULT_ABOUT_DATA = {
    "_id": "about",
    "title": "Our Commitment to You",
    "slogan": "It's more than produce — it's about being your daily, trusted partner.",
    "paragraphs": [
        "Welcome to Matax Express Ltd, your trusted wholesale produce provider serving the Greater Toronto Area for over 30 years!",
        "At Matax Express Ltd, our commitment to service has always been at the core of what we do. From day one, we’ve focused on understanding the needs of our customers and working tirelessly to meet them. Whether delivering to bustling restaurants, local markets, or retail stores, we strive to ensure your success and satisfaction every step of the way.",
        "We’re proud of the journey we’ve taken over the past three decades, and we also understand the importance of continuous improvement. Your feedback has been crucial in helping us grow and adapt, and we are working hard to ensure every interaction reflects the high standard of service you deserve.",
        "While freshness remains an important priority, we are equally dedicated to creating a service experience that exceeds expectations. From reliable deliveries to personalized support, our team is here to make partnering with Matax Express Ltd seamless and efficient.",
        "For us, it’s not just about providing produce—it’s about being a dependable partner that you can count on daily. We look forward to building stronger relationships and delivering better service for years to come."
    ]
}

DEFAULT_CONTACT_DATA = {
    "_id": "contact",
    "title": "Contact Us",
    "intro": "We're here to help! Reach out to us through any of the channels below. We aim to respond to all inquiries within 24 business hours.",
    "details": [
        {"type": "Phone Support", "value": "+1 (800) 123-4567"},
        {"type": "Email Support", "value": "support@mataxexpress.com"},
        {"type": "Business Hours", "value": "Monday - Friday, 9:00 AM - 5:00 PM (EST)"},
        {"type": "Mailing Address", "value": "123 Fresh Produce Lane, Farmville, ST 54321"}
    ]
}

@page_bp.route('/<page_name>', methods=['GET'])
def get_page_content(page_name):
    """API endpoint for the frontend to fetch page content."""
    content = mongo.db.pages.find_one({'_id': page_name})
    if not content:
        # If content doesn't exist, create it from default and return it
        if page_name == 'about':
            mongo.db.pages.insert_one(DEFAULT_ABOUT_DATA)
            content = DEFAULT_ABOUT_DATA
        elif page_name == 'contact':
            mongo.db.pages.insert_one(DEFAULT_CONTACT_DATA)
            content = DEFAULT_CONTACT_DATA
        else:
            return jsonify({"msg": "Page not found"}), 404
    # Ensure _id is a string if it's an ObjectId
    if '_id' in content and not isinstance(content['_id'], str):
        content['_id'] = str(content['_id'])
    return jsonify(content)

@page_bp.route('/update', methods=['POST'])
def update_page_content():
    """Handles form submission from the /update UI to save changes."""
    page_name = request.form.get('page_name')
    if page_name == 'about':
        paragraphs = request.form.get('paragraphs', '').strip().split('\n')
        paragraphs = [p.strip() for p in paragraphs if p.strip()]
        
        update_data = {
            "title": request.form.get('title'),
            "slogan": request.form.get('slogan'),
            "paragraphs": paragraphs
        }
    elif page_name == 'contact':
        update_data = {
            "title": request.form.get('title'),
            "intro": request.form.get('intro'),
            "details": [
                {"type": "Phone Support", "value": request.form.get('phone_value')},
                {"type": "Email Support", "value": request.form.get('email_value')},
                {"type": "Business Hours", "value": request.form.get('hours_value')},
                {"type": "Mailing Address", "value": request.form.get('address_value')}
            ]
        }
    else:
        return redirect('/api/pages/update')

    mongo.db.pages.update_one(
        {'_id': page_name},
        {'$set': update_data},
        upsert=True
    )
    return redirect('/api/pages/update_ui') # Corrected redirect to the UI page

@page_bp.route('/update_ui', methods=['GET'])
def update_ui():
    """Serves the simple HTML UI for editing page content."""
    about_data = mongo.db.pages.find_one({'_id': 'about'}) or DEFAULT_ABOUT_DATA
    contact_data = mongo.db.pages.find_one({'_id': 'contact'}) or DEFAULT_CONTACT_DATA

    about_paragraphs_text = "\n".join(about_data.get('paragraphs', []))
    contact_details = {item['type']: item['value'] for item in contact_data.get('details', [])}

    html = f"""

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>Update Page Content</title>

        <style>

            body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 2em; background-color: #f8f9fa; color: #212529; }}

            .container {{ max-width: 800px; margin: auto; }}

            h1, h2 {{ color: #343a40; border-bottom: 2px solid #dee2e6; padding-bottom: 0.5em; }}

            form {{ background: white; padding: 2em; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.05); margin-bottom: 2em; }}

            label {{ display: block; margin-top: 1em; margin-bottom: 0.5em; font-weight: bold; color: #495057; }}

            input[type="text"], textarea {{ width: 100%; padding: 0.8em; border: 1px solid #ced4da; border-radius: 4px; box-sizing: border-box; font-size: 1rem; }}

            textarea {{ height: 250px; resize: vertical; }}

            button {{ background-color: #007bff; color: white; padding: 0.8em 1.5em; border: none; border-radius: 4px; cursor: pointer; font-size: 1em; font-weight: bold; }}

            button:hover {{ background-color: #0056b3; }}

        </style>

    </head>

    <body>

        <div class="container">

            <h1>Update Website Content</h1>



            <!-- About Us Page Form -->

            <h2>About Us Page</h2>

            <form action="/api/pages/update" method="post">

                <input type="hidden" name="page_name" value="about">

                <label for="about_title">Title:</label>

                <input type="text" id="about_title" name="title" value="{about_data.get('title', '')}">



                <label for="about_slogan">Slogan:</label>

                <input type="text" id="about_slogan" name="slogan" value="{about_data.get('slogan', '')}">

                

                <label for="about_paragraphs">Paragraphs (one paragraph per line):</label>

                <textarea id="about_paragraphs" name="paragraphs">{about_paragraphs_text}</textarea>

                

                <br><br>

                <button type="submit">Update About Page</button>

            </form>



            <!-- Contact Page Form -->

            <h2>Customer Care Page</h2>

            <form action="/api/pages/update" method="post">

                <input type="hidden" name="page_name" value="contact">



                <label for="contact_title">Title:</label>

                <input type="text" id="contact_title" name="title" value="{contact_data.get('title', '')}">



                <label for="contact_intro">Intro Text:</label>

                <input type="text" id="contact_intro" name="intro" value="{contact_data.get('intro', '')}">



                <label for="phone_value">Phone Support:</label>

                <input type="text" id="phone_value" name="phone_value" value="{contact_details.get('Phone Support', '')}">



                <label for="email_value">Email Support:</label>

                <input type="text" id="email_value" name="email_value" value="{contact_details.get('Email Support', '')}">



                <label for="hours_value">Business Hours:</label>

                <input type="text" id="hours_value" name="hours_value" value="{contact_details.get('Business Hours', '')}">



                <label for="address_value">Mailing Address:</label>

                <input type="text" id="address_value" name="address_value" value="{contact_details.get('Mailing Address', '')}">

                

                <br><br>

                <button type="submit">Update Contact Page</button>

            </form>

        </div>

    </body>

    </html>

    """
    return html