Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| ACCESS_PASSWORD = "lb123" | |
| TOOLS = { | |
| "Orders": { | |
| "icon": "📦", | |
| "color": "#2563eb", | |
| "bg": "#eff6ff", | |
| "items": [ | |
| ("📄 Open Order", "https://open-order-1019372524488.us-west1.run.app"), | |
| ("🧾 Order Processing", "https://order-processing-1019372524488.asia-east1.run.app"), | |
| ("🏷️ Ammu Order", "https://ammu-order-1019372524488.asia-east1.run.app"), | |
| ], | |
| }, | |
| "Shipping Tools": { | |
| "icon": "🚚", | |
| "color": "#059669", | |
| "bg": "#ecfdf5", | |
| "items": [ | |
| ("📮 EC-Ship App", "https://shipping-ec-ship-1019372524488.asia-east1.run.app"), | |
| ("✈️ FedEx App", "https://shipping-fedex-1019372524488.us-west1.run.app"), | |
| ("🌐 YunExpress App", "https://shipping-yunexpress-1019372524488.asia-east1.run.app"), | |
| ("🚚 DealerSend App", "https://dealersend-1019372524488.asia-east1.run.app"), | |
| ("📤 Tracking Upload", "https://tracking-upload-1019372524488.asia-east1.run.app"), | |
| ], | |
| }, | |
| "Admin / Marketing": { | |
| "icon": "⚙️", | |
| "color": "#7c3aed", | |
| "bg": "#f5f3ff", | |
| "items": [ | |
| ("✉️ Email Template", "https://email-template-1019372524488.asia-east1.run.app"), | |
| ], | |
| }, | |
| "External Service Websites": { | |
| "icon": "🔗", | |
| "color": "#ea580c", | |
| "bg": "#fff7ed", | |
| "items": [ | |
| ("🛒 Shopify Website", "https://www.shopify.com/"), | |
| ("📮 Hongkong Post EC-Ship Website", "https://ec-ship.hongkongpost.hk/"), | |
| ("✈️ FedEx Hong Kong Website", "https://www.fedex.com/secure-login/en-hk/#/credentials"), | |
| ("🌐 YunExpress Website", "https://passport.yunexpress.cn/login/#/"), | |
| ("🔎 YunTrack Tracking Website", "https://www.yuntrack.com/"), | |
| ("📍 17TRACK Tracking Website", "https://www.17track.net/en"), | |
| ("🚚 DealerSend Login Page", "https://dealer-send.com/zh-HK/login"), | |
| ], | |
| }, | |
| } | |
| def build_html(): | |
| html = """ | |
| <meta name="robots" content="noindex, nofollow"> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| background: #f8fafc; | |
| } | |
| .dashboard-wrap { | |
| max-width: 1180px; | |
| margin: 0 auto; | |
| padding: 28px 20px 40px; | |
| } | |
| .hero { | |
| background: #ffffff; | |
| border: 1px solid #e5e7eb; | |
| border-radius: 20px; | |
| padding: 24px 28px; | |
| margin-bottom: 24px; | |
| box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06); | |
| } | |
| .hero-title-wrap h1 { | |
| margin: 0; | |
| font-size: 30px; | |
| line-height: 1.2; | |
| color: #111827; | |
| font-weight: 700; | |
| } | |
| .hero-title-wrap p { | |
| margin: 10px 0 0 0; | |
| color: #6b7280; | |
| font-size: 15px; | |
| } | |
| .section { | |
| margin-top: 24px; | |
| border-radius: 18px; | |
| padding: 18px; | |
| box-shadow: 0 6px 20px rgba(0,0,0,0.05); | |
| } | |
| .section-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 16px; | |
| } | |
| .section-icon { | |
| font-size: 24px; | |
| } | |
| .section-title { | |
| font-size: 24px; | |
| font-weight: 700; | |
| } | |
| .tool-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); | |
| gap: 16px; | |
| } | |
| .tool-card { | |
| display: block; | |
| padding: 18px; | |
| border-radius: 16px; | |
| text-decoration: none; | |
| color: #111827; | |
| background: #ffffff; | |
| border: 1px solid rgba(0,0,0,0.06); | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.05); | |
| transition: all 0.18s ease; | |
| } | |
| .tool-card:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 24px rgba(0,0,0,0.10); | |
| } | |
| .tool-title { | |
| font-size: 18px; | |
| font-weight: 700; | |
| margin-bottom: 8px; | |
| } | |
| .tool-sub { | |
| font-size: 13px; | |
| color: #6b7280; | |
| } | |
| @media (max-width: 640px) { | |
| .dashboard-wrap { | |
| padding: 20px 14px 32px; | |
| } | |
| .hero { | |
| padding: 22px 20px; | |
| } | |
| .hero-title-wrap h1 { | |
| font-size: 25px; | |
| } | |
| .section-title { | |
| font-size: 21px; | |
| } | |
| } | |
| </style> | |
| <div class="dashboard-wrap"> | |
| <div class="hero"> | |
| <div class="hero-title-wrap"> | |
| <h1>Leading Bridge Admin Dashboard</h1> | |
| <p>Internal tools portal for order processing, shipping and administration.</p> | |
| </div> | |
| </div> | |
| """ | |
| for section_name, section_data in TOOLS.items(): | |
| color = section_data["color"] | |
| bg = section_data["bg"] | |
| icon = section_data["icon"] | |
| items = section_data["items"] | |
| html += f""" | |
| <div class="section" style="background:{bg}; border-top: 5px solid {color};"> | |
| <div class="section-header"> | |
| <div class="section-icon">{icon}</div> | |
| <div class="section-title" style="color:{color};">{section_name}</div> | |
| </div> | |
| <div class="tool-grid"> | |
| """ | |
| for name, url in items: | |
| subtitle = "Open website" if section_name == "External Service Websites" else "Open tool" | |
| html += f""" | |
| <a href="{url}" target="_blank" class="tool-card"> | |
| <div class="tool-title">{name}</div> | |
| <div class="tool-sub">{subtitle}</div> | |
| </a> | |
| """ | |
| html += """ | |
| </div> | |
| </div> | |
| """ | |
| html += """ | |
| </div> | |
| """ | |
| return html | |
| def check_password(password): | |
| if password == ACCESS_PASSWORD: | |
| return ( | |
| gr.update(visible=False), | |
| gr.update(visible=True), | |
| "" | |
| ) | |
| return ( | |
| gr.update(visible=True), | |
| gr.update(visible=False), | |
| "Incorrect password. Please try again." | |
| ) | |
| with gr.Blocks(title="Leading Bridge Admin Dashboard") as demo: | |
| login_box = gr.Column(visible=True) | |
| dashboard_box = gr.Column(visible=False) | |
| with login_box: | |
| gr.Markdown("## Leading Bridge Admin Dashboard") | |
| gr.Markdown("Please enter the access password.") | |
| password_input = gr.Textbox( | |
| label="Password", | |
| type="password", | |
| placeholder="Enter password" | |
| ) | |
| login_btn = gr.Button("Login") | |
| login_message = gr.Markdown("") | |
| with dashboard_box: | |
| gr.HTML(build_html()) | |
| login_btn.click( | |
| check_password, | |
| inputs=password_input, | |
| outputs=[login_box, dashboard_box, login_message] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |