|
import json |
|
import gradio as gr |
|
import os |
|
|
|
|
|
lists = {} |
|
|
|
|
|
def unishare_app(): |
|
|
|
with gr.Blocks(css=""" |
|
.list-card { |
|
background: white; |
|
padding: 16px; |
|
border-radius: 10px; |
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1); |
|
margin-bottom: 16px; |
|
cursor: pointer; |
|
} |
|
.list-card:hover { |
|
transform: scale(1.02); |
|
transition: transform 0.2s; |
|
} |
|
.item-grid { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); |
|
gap: 16px; |
|
} |
|
.item-card { |
|
background: #f9f9f9; |
|
padding: 16px; |
|
border-radius: 10px; |
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05); |
|
} |
|
.back-btn { |
|
margin-bottom: 16px; |
|
} |
|
""") as demo: |
|
gr.Markdown("# UniShare") |
|
|
|
|
|
with gr.Tab("Overview"): |
|
overview_container = gr.HTML() |
|
|
|
def update_overview(): |
|
html = "" |
|
if lists: |
|
for list_name, list_data in lists.items(): |
|
html += f""" |
|
<div class="list-card" onclick="switchToList('{list_name}')"> |
|
<h3>{list_name}</h3> |
|
<p>{len(list_data)} sections</p> |
|
</div> |
|
""" |
|
else: |
|
html = "<p>No lists found. Add some data first!</p>" |
|
|
|
|
|
html += """ |
|
<script> |
|
function switchToList(name) { |
|
// Using Gradio's built-in tab switching |
|
const tabs = document.querySelectorAll('.tabs > button'); |
|
if (tabs.length > 1) { |
|
tabs[1].click(); // Click the "View List" tab |
|
// Set the list name in the dropdown |
|
const listSelect = document.getElementById('list-selector'); |
|
for (let i = 0; i < listSelect.options.length; i++) { |
|
if (listSelect.options[i].value === name) { |
|
listSelect.selectedIndex = i; |
|
// Trigger change event |
|
const event = new Event('change'); |
|
listSelect.dispatchEvent(event); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
</script> |
|
""" |
|
return html |
|
|
|
|
|
demo.load(update_overview, [], [overview_container]) |
|
|
|
|
|
with gr.Tab("View List"): |
|
gr.Markdown("## View List") |
|
|
|
|
|
list_selector = gr.Dropdown( |
|
label="Select a list", |
|
choices=list(lists.keys()) if lists else [], |
|
interactive=True, |
|
elem_id="list-selector" |
|
) |
|
|
|
|
|
list_content = gr.HTML() |
|
|
|
|
|
gr.Button("Back to Overview", elem_classes=["back-btn"]).click( |
|
lambda: gr.Tabs(selected=0), |
|
[], |
|
[] |
|
) |
|
|
|
|
|
def display_list(list_name): |
|
if not list_name or list_name not in lists: |
|
return "<p>Please select a valid list</p>" |
|
|
|
sections = lists[list_name] |
|
html = "" |
|
|
|
for section in sections: |
|
html += f"<div class='section-card'><h3>{section.get('sectionTitle', 'Untitled Section')}</h3>" |
|
html += "<div class='item-grid'>" |
|
|
|
for item in section.get('items', []): |
|
title = item.get('title', 'Untitled') |
|
link = item.get('link', '#') |
|
|
|
html += f"<div class='item-card'>" |
|
html += f"<strong>{title}</strong><br>" |
|
|
|
if link.lower().endswith(('.jpeg', '.jpg', '.gif', '.png')): |
|
html += f"<img src='{link}' alt='{title}' style='max-width:100%; max-height:150px; margin:10px 0;'><br>" |
|
|
|
html += f"<a href='{link}' download style='color:#3b82f6; text-decoration:none;'>Download</a>" |
|
html += "</div>" |
|
|
|
html += "</div></div>" |
|
|
|
return html |
|
|
|
|
|
list_selector.change( |
|
display_list, |
|
[list_selector], |
|
[list_content] |
|
) |
|
|
|
|
|
with gr.Tab("Admin"): |
|
gr.Markdown("## Data Management") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("### Add New List Data") |
|
list_name_input = gr.Textbox(label="List Name") |
|
json_data = gr.Textbox( |
|
label="Section Data (JSON format)", |
|
lines=10, |
|
placeholder=''' |
|
{ |
|
"sectionTitle": "Sample Section", |
|
"items": [ |
|
{ |
|
"title": "Sample Item", |
|
"link": "https://example.com/sample.jpg" |
|
} |
|
] |
|
}''' |
|
) |
|
|
|
add_button = gr.Button("Add Data") |
|
add_result = gr.Markdown() |
|
|
|
def add_data(list_name, data_json): |
|
if not list_name: |
|
return "Error: List name is required" |
|
|
|
try: |
|
data = json.loads(data_json) |
|
if list_name not in lists: |
|
lists[list_name] = [] |
|
|
|
lists[list_name].append(data) |
|
|
|
|
|
list_selector.choices = list(lists.keys()) |
|
|
|
return f"Success: Data added to {list_name}" |
|
except json.JSONDecodeError: |
|
return "Error: Invalid JSON format" |
|
except Exception as e: |
|
return f"Error: {str(e)}" |
|
|
|
add_button.click( |
|
add_data, |
|
[list_name_input, json_data], |
|
[add_result] |
|
) |
|
|
|
with gr.Column(): |
|
gr.Markdown("### View All Data") |
|
view_data_button = gr.Button("View All Data") |
|
data_output = gr.JSON() |
|
|
|
def get_all_data(): |
|
return lists |
|
|
|
view_data_button.click( |
|
get_all_data, |
|
[], |
|
[data_output] |
|
) |
|
|
|
|
|
clear_button = gr.Button("Clear All Data", variant="stop") |
|
clear_result = gr.Markdown() |
|
|
|
def clear_data(): |
|
lists.clear() |
|
list_selector.choices = [] |
|
return "All data cleared" |
|
|
|
clear_button.click( |
|
clear_data, |
|
[], |
|
[clear_result] |
|
) |
|
|
|
|
|
|
|
|
|
def refresh_ui(): |
|
list_selector.choices = list(lists.keys()) |
|
|
|
|
|
add_button.click(lambda: None, [], [], js="() => {window.location.reload()}") |
|
clear_button.click(lambda: None, [], [], js="() => {window.location.reload()}") |
|
|
|
return demo |
|
|
|
|
|
demo = unishare_app() |
|
demo.launch() |