Spaces:
Running
Running
import gradio as gr | |
import sqlite3 | |
import pandas as pd | |
from datetime import datetime, time, timedelta, date | |
import plotly.express as px | |
import plotly.graph_objects as go | |
from plotly.subplots import make_subplots | |
import calendar | |
import random | |
import json | |
DB_FILE = "life_tracker.db" | |
def create_tables(): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS users ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
name TEXT UNIQUE | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS daily_activities ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
date TEXT, | |
category TEXT, | |
subcategory TEXT, | |
start_time TEXT, | |
end_time TEXT, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS qualitative_metrics ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
date TEXT, | |
life_score INTEGER, | |
work_score INTEGER, | |
health_score INTEGER, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS quantitative_metrics ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
date TEXT, | |
wake_up_time TEXT, | |
workouts INTEGER, | |
meditation_minutes INTEGER, | |
brain_training_minutes INTEGER, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS goals ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
category TEXT, | |
description TEXT, | |
target_value REAL, | |
current_value REAL, | |
start_date TEXT, | |
end_date TEXT, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS user_settings ( | |
user_id INTEGER PRIMARY KEY, | |
default_wake_time TEXT, | |
work_weight REAL, | |
life_weight REAL, | |
health_weight REAL, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS custom_categories ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
category_name TEXT, | |
subcategories TEXT, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS daily_checklist ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_id INTEGER, | |
date TEXT, | |
checklist_data TEXT, | |
notes TEXT, | |
FOREIGN KEY (user_id) REFERENCES users (id) | |
) | |
''') | |
conn.commit() | |
conn.close() | |
def create_connection(): | |
return sqlite3.connect(DB_FILE) | |
def add_user_profile(name): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute("INSERT INTO users (name) VALUES (?)", (name,)) | |
conn.commit() | |
conn.close() | |
def delete_user_profile(name): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute("DELETE FROM users WHERE name = ?", (name,)) | |
conn.commit() | |
conn.close() | |
def generate_placeholder_data(user_name): | |
conn = create_connection() | |
cursor = conn.cursor() | |
# Get user ID | |
cursor.execute("SELECT id FROM users WHERE name = ?", (user_name,)) | |
user_id = cursor.fetchone()[0] | |
# Generate placeholder data for the last 30 days | |
end_date = datetime.now().date() | |
start_date = end_date - timedelta(days=30) | |
categories = ["Work", "Life", "Health", "Sleep"] | |
subcategories = { | |
"Work": ["Meetings", "Project A", "Project B"], | |
"Life": ["Family", "Friends", "Hobbies"], | |
"Health": ["Exercise", "Meditation", "Personal Care"], | |
"Sleep": ["Night Sleep"] | |
} | |
for day in range(31): | |
current_date = start_date + timedelta(days=day) | |
# Daily activities | |
for category in categories: | |
for _ in range(random.randint(1, 3)): | |
subcategory = random.choice(subcategories[category]) | |
start_time = time(hour=random.randint(0, 23), minute=random.randint(0, 59)) | |
duration = timedelta(hours=random.randint(1, 4)) | |
end_time = (datetime.combine(current_date, start_time) + duration).time() | |
cursor.execute(''' | |
INSERT INTO daily_activities (user_id, date, category, subcategory, start_time, end_time) | |
VALUES (?, ?, ?, ?, ?, ?) | |
''', (user_id, current_date.isoformat(), category, subcategory, start_time.isoformat(), end_time.isoformat())) | |
# Qualitative metrics | |
cursor.execute(''' | |
INSERT INTO qualitative_metrics (user_id, date, life_score, work_score, health_score) | |
VALUES (?, ?, ?, ?, ?) | |
''', (user_id, current_date.isoformat(), random.randint(1, 10), random.randint(1, 10), random.randint(1, 10))) | |
# Quantitative metrics | |
wake_up_time = time(hour=random.randint(5, 9), minute=random.randint(0, 59)) | |
cursor.execute(''' | |
INSERT INTO quantitative_metrics (user_id, date, wake_up_time, workouts, meditation_minutes, brain_training_minutes) | |
VALUES (?, ?, ?, ?, ?, ?) | |
''', (user_id, current_date.isoformat(), wake_up_time.isoformat(), | |
random.randint(0, 2), random.randint(0, 60), random.randint(0, 60))) | |
# Generate some goals | |
goal_categories = ["Work", "Life", "Health"] | |
for category in goal_categories: | |
cursor.execute(''' | |
INSERT INTO goals (user_id, category, description, target_value, current_value, start_date, end_date) | |
VALUES (?, ?, ?, ?, ?, ?, ?) | |
''', (user_id, category, f"Improve {category.lower()} balance", random.randint(50, 100), | |
random.randint(0, 50), start_date.isoformat(), end_date.isoformat())) | |
# Set user settings | |
default_wake_time = time(hour=6, minute=0) | |
cursor.execute(''' | |
INSERT OR REPLACE INTO user_settings (user_id, default_wake_time, work_weight, life_weight, health_weight) | |
VALUES (?, ?, ?, ?, ?) | |
''', (user_id, default_wake_time.isoformat(), 1.0, 1.0, 1.0)) | |
conn.commit() | |
conn.close() | |
def get_weekly_data(user_name): | |
conn = create_connection() | |
end_date = datetime.now().date() | |
start_date = end_date - timedelta(days=7) | |
query = ''' | |
SELECT date, category, subcategory, start_time, end_time | |
FROM daily_activities | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date BETWEEN ? AND ? | |
ORDER BY date, start_time | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name, start_date, end_date)) | |
conn.close() | |
# Convert date column to datetime | |
df['date'] = pd.to_datetime(df['date']) | |
# Convert start_time and end_time to datetime | |
df['start_time'] = pd.to_datetime(df['date'].dt.strftime('%Y-%m-%d') + ' ' + df['start_time']) | |
df['end_time'] = pd.to_datetime(df['date'].dt.strftime('%Y-%m-%d') + ' ' + df['end_time']) | |
return df | |
def get_monthly_data(user_name, year=None, month=None): | |
if year is None or month is None: | |
current_date = datetime.now() | |
year = year or current_date.year | |
month = month or current_date.month | |
conn = create_connection() | |
start_date = f"{year}-{month:02d}-01" | |
end_date = f"{year}-{month:02d}-{calendar.monthrange(year, month)[1]}" | |
query = ''' | |
SELECT date, category, subcategory, start_time, end_time | |
FROM daily_activities | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date BETWEEN ? AND ? | |
ORDER BY date, start_time | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name, start_date, end_date)) | |
conn.close() | |
# Convert date column to datetime | |
df['date'] = pd.to_datetime(df['date']) | |
# Convert start_time and end_time to datetime | |
df['start_time'] = pd.to_datetime(df['date'].dt.strftime('%Y-%m-%d') + ' ' + df['start_time']) | |
df['end_time'] = pd.to_datetime(df['date'].dt.strftime('%Y-%m-%d') + ' ' + df['end_time']) | |
return df | |
def format_monthly_data(df, year, month): | |
# Create a DataFrame with all days of the month | |
all_days = pd.date_range(start=f"{year}-{month:02d}-01", end=f"{year}-{month:02d}-{calendar.monthrange(year, month)[1]}", freq='D') | |
calendar_df = pd.DataFrame({'date': all_days}) | |
# Calculate total hours for each category | |
df['duration'] = (df['end_time'] - df['start_time']).dt.total_seconds() / 3600 | |
category_hours = df.groupby(['date', 'category'])['duration'].sum().unstack(fill_value=0) | |
# Merge with the calendar DataFrame | |
calendar_df = calendar_df.merge(category_hours, left_on='date', right_index=True, how='left') | |
calendar_df = calendar_df.fillna(0) | |
return calendar_df | |
def save_day_activities(user_name, date, work, life, health, sleep): | |
conn = create_connection() | |
cursor = conn.cursor() | |
# Delete existing activities for the day | |
cursor.execute(''' | |
DELETE FROM daily_activities | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date = ? | |
''', (user_name, date)) | |
# Insert new activities | |
activities = [ | |
('Work', work), | |
('Life', life), | |
('Health', health), | |
('Sleep', sleep) | |
] | |
for category, hours in activities: | |
if hours > 0: | |
start_time = '00:00' | |
end_time = f'{int(hours):02d}:{int((hours % 1) * 60):02d}' | |
cursor.execute(''' | |
INSERT INTO daily_activities (user_id, date, category, subcategory, start_time, end_time) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, 'Default', ?, ?) | |
''', (user_name, date, category, start_time, end_time)) | |
conn.commit() | |
conn.close() | |
def log_activity(user_name, date, category, subcategory, start_time, end_time): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT INTO daily_activities (user_id, date, category, subcategory, start_time, end_time) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?, ?, ?) | |
''', (user_name, date, category, subcategory, start_time, end_time)) | |
conn.commit() | |
conn.close() | |
def get_activities(user_name, date): | |
conn = create_connection() | |
categories, _ = get_custom_categories(user_name) | |
category_list = ', '.join([f"'{cat}'" for cat in categories]) | |
query = f''' | |
SELECT category, subcategory, start_time, end_time | |
FROM daily_activities | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date = ? AND category IN ({category_list}) | |
ORDER BY start_time | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name, date)) | |
conn.close() | |
return df | |
def log_qualitative_metrics(user_name, date, life_score, work_score, health_score): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT INTO qualitative_metrics (user_id, date, life_score, work_score, health_score) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?, ?) | |
''', (user_name, date, life_score, work_score, health_score)) | |
conn.commit() | |
conn.close() | |
def log_quantitative_metrics(user_name, date, wake_up_time, workouts, meditation_minutes, brain_training_minutes): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT INTO quantitative_metrics (user_id, date, wake_up_time, workouts, meditation_minutes, brain_training_minutes) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?, ?, ?) | |
''', (user_name, date, wake_up_time, workouts, meditation_minutes, brain_training_minutes)) | |
conn.commit() | |
conn.close() | |
def get_metrics(user_name, date): | |
conn = create_connection() | |
qual_query = ''' | |
SELECT life_score, work_score, health_score | |
FROM qualitative_metrics | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date = ? | |
''' | |
quant_query = ''' | |
SELECT wake_up_time, workouts, meditation_minutes, brain_training_minutes | |
FROM quantitative_metrics | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date = ? | |
''' | |
qual_df = pd.read_sql_query(qual_query, conn, params=(user_name, date)) | |
quant_df = pd.read_sql_query(quant_query, conn, params=(user_name, date)) | |
conn.close() | |
return pd.concat([qual_df, quant_df], axis=1) | |
def analyze_weekly_data(user_name): | |
df = get_weekly_data(user_name) | |
df['duration'] = (df['end_time'] - df['start_time']).dt.total_seconds() / 3600 | |
category_summary = df.groupby('category')['duration'].sum().sort_values(ascending=False) | |
total_hours = category_summary.sum() | |
category_percentages = (category_summary / total_hours * 100).round(2) | |
# Create a more detailed pie chart | |
pie_chart = go.Figure(data=[go.Pie( | |
labels=category_percentages.index, | |
values=category_percentages.values, | |
hole=.3, | |
textinfo='label+percent', | |
insidetextorientation='radial' | |
)]) | |
pie_chart.update_layout(title="Weekly Activity Distribution") | |
daily_scores = get_weekly_scores(user_name) | |
# Create a more detailed line chart | |
line_chart = go.Figure() | |
for column in ['life_score', 'work_score', 'health_score']: | |
line_chart.add_trace(go.Scatter( | |
x=daily_scores['date'], | |
y=daily_scores[column], | |
mode='lines+markers', | |
name=column.replace('_', ' ').title() | |
)) | |
line_chart.update_layout(title="Weekly Score Trends", xaxis_title="Date", yaxis_title="Score") | |
return pie_chart, line_chart, total_hours | |
def analyze_monthly_data(user_name): | |
year, month = datetime.now().year, datetime.now().month | |
df = get_monthly_data(user_name, year, month) | |
df['duration'] = (df['end_time'] - df['start_time']).dt.total_seconds() / 3600 | |
category_summary = df.groupby('category')['duration'].sum().sort_values(ascending=False) | |
total_hours = category_summary.sum() | |
category_percentages = (category_summary / total_hours * 100).round(2) | |
pie_chart = px.pie(values=category_percentages.values, names=category_percentages.index, title="Monthly Activity Distribution") | |
weekly_scores = get_monthly_scores(user_name) | |
# Use 'date' instead of 'week' for the x-axis | |
line_chart = px.line(weekly_scores, x='date', y=['life_score', 'work_score', 'health_score'], title="Monthly Score Trends") | |
return pie_chart, line_chart, total_hours | |
def get_monthly_scores(user_name): | |
conn = create_connection() | |
end_date = datetime.now().date() | |
start_date = end_date.replace(day=1) | |
query = ''' | |
SELECT | |
date, | |
AVG(life_score) as life_score, | |
AVG(work_score) as work_score, | |
AVG(health_score) as health_score | |
FROM qualitative_metrics | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date BETWEEN ? AND ? | |
GROUP BY date | |
ORDER BY date | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name, start_date, end_date)) | |
conn.close() | |
return df | |
def get_weekly_scores(user_name): | |
conn = create_connection() | |
end_date = datetime.now().date() | |
start_date = end_date - timedelta(days=7) | |
query = ''' | |
SELECT | |
date, | |
life_score, | |
work_score, | |
health_score | |
FROM qualitative_metrics | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date BETWEEN ? AND ? | |
ORDER BY date | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name, start_date, end_date)) | |
conn.close() | |
return df | |
def set_goal(user_name, category, description, target_value, start_date, end_date): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT INTO goals (user_id, category, description, target_value, current_value, start_date, end_date) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?, 0, ?, ?) | |
''', (user_name, category, description, float(target_value), start_date, end_date)) | |
conn.commit() | |
conn.close() | |
def get_goals(user_name): | |
conn = create_connection() | |
query = ''' | |
SELECT category, description, target_value, current_value, start_date, end_date | |
FROM goals | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) | |
''' | |
df = pd.read_sql_query(query, conn, params=(user_name,)) | |
conn.close() | |
return df | |
def update_goal_progress(user_name, goal_id, current_value): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
UPDATE goals | |
SET current_value = ? | |
WHERE id = ? AND user_id = (SELECT id FROM users WHERE name = ?) | |
''', (current_value, goal_id, user_name)) | |
conn.commit() | |
conn.close() | |
def get_user_settings(user_name): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
SELECT default_wake_time, work_weight, life_weight, health_weight | |
FROM user_settings | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) | |
''', (user_name,)) | |
settings = cursor.fetchone() | |
conn.close() | |
return settings if settings else (None, 1.0, 1.0, 1.0) | |
def update_user_settings(user_name, default_wake_time, work_weight, life_weight, health_weight): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT OR REPLACE INTO user_settings (user_id, default_wake_time, work_weight, life_weight, health_weight) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?, ?) | |
''', (user_name, default_wake_time, work_weight, life_weight, health_weight)) | |
conn.commit() | |
conn.close() | |
def parse_date(date_str): | |
if date_str.lower() == 'today': | |
return datetime.now().date() | |
else: | |
return datetime.strptime(date_str, "%Y-%m-%d").date() | |
# Define a custom theme with a more modern look | |
custom_theme = gr.themes.Soft( | |
primary_hue="blue", | |
secondary_hue="gray", | |
neutral_hue="slate", | |
font=("Inter", "sans-serif") | |
) | |
# Custom CSS for full-screen layout | |
custom_css = """ | |
html, body { | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
font-size: 16px; /* Base font size */ | |
} | |
.gradio-container { | |
width: 100vw !important; | |
max-width: 100vw !important; | |
padding: 0 !important; | |
margin: 0 !important; | |
font-size: 1rem; /* Use relative units */ | |
} | |
#component-0 { | |
max-height: none !important; | |
overflow: visible; | |
} | |
.main { | |
height: auto !important; | |
max-height: none !important; | |
display: flex; | |
flex-direction: row; | |
} | |
.contain { | |
max-width: 100% !important; | |
height: auto !important; | |
flex-grow: 1; | |
display: flex; | |
flex-direction: column; | |
} | |
.tabs { | |
flex-grow: 1; | |
display: flex; | |
flex-direction: column; | |
} | |
.tab-content { | |
flex-grow: 1; | |
overflow-y: visible; | |
} | |
.main-content { | |
height: auto; | |
display: flex; | |
flex-direction: column; | |
} | |
footer { | |
display: none !important; | |
} | |
/* Increase text size for various elements */ | |
.gradio-container, .gradio-container *, .gradio-container .form, .gradio-container input, .gradio-container select, .gradio-container textarea { | |
font-size: 1.1rem !important; | |
} | |
/* Increase text size for headers */ | |
.gradio-container h1 { font-size: 2.5rem !important; } | |
.gradio-container h2 { font-size: 2rem !important; } | |
.gradio-container h3 { font-size: 1.75rem !important; } | |
.gradio-container h4 { font-size: 1.5rem !important; } | |
/* Increase text size for buttons */ | |
.gradio-container button { | |
font-size: 1.1rem !important; | |
padding: 0.5rem 1rem !important; | |
} | |
/* Increase text size for dropdown options */ | |
.gradio-container select option { | |
font-size: 1.1rem !important; | |
} | |
/* Adjust padding and margins for better spacing */ | |
.gradio-container .form > *, .gradio-container .form > div > * { | |
margin-bottom: 1rem !important; | |
} | |
<script> | |
function edit_day(date) { | |
document.querySelector('input[data-testid="textbox"]').value = date; | |
document.querySelector('button[data-testid="button"]').click(); | |
} | |
</script> | |
""" | |
# Create the main Gradio interface with the custom theme and CSS | |
with gr.Blocks(theme=custom_theme, css=custom_css) as demo: | |
create_tables() | |
with gr.Row(equal_height=True): | |
# Left sidebar | |
with gr.Column(scale=1, min_width=200): | |
gr.Markdown("## Life Tracking System") | |
user_name = gr.Dropdown(label="User Name", choices=["John Doe"], value="John Doe") | |
date = gr.Textbox(label="Date", value="today", placeholder="YYYY-MM-DD") | |
with gr.Group(): | |
gr.Markdown("### Quick Glance") | |
today_life_score = gr.Number(label="Today's Life Score", value=0) | |
today_work_score = gr.Number(label="Today's Work Score", value=0) | |
today_health_score = gr.Number(label="Today's Health Score", value=0) | |
wake_up_time = gr.Textbox(label="Wake-up Time", value="") | |
total_activities = gr.Number(label="Total Activities", value=0) | |
quick_log_btn = gr.Button("Quick Log") | |
# Add buttons for adding and deleting user profiles | |
new_user_name = gr.Textbox(label="New User Name") | |
add_user_btn = gr.Button("Add User") | |
delete_user_btn = gr.Button("Delete User") | |
# Main content area | |
with gr.Column(scale=4): | |
with gr.Tabs() as tabs: | |
# Dashboard Tab | |
with gr.TabItem("Dashboard"): | |
with gr.Row(): | |
with gr.Column(scale=2): | |
gr.Markdown("### Log Daily Metrics") | |
life_score = gr.Slider(label="Life Score", minimum=1, maximum=10, step=1) | |
work_score = gr.Slider(label="Work Score", minimum=1, maximum=10, step=1) | |
health_score = gr.Slider(label="Health Score", minimum=1, maximum=10, step=1) | |
workouts = gr.Number(label="Workouts", minimum=0, step=1) | |
meditation_minutes = gr.Number(label="Meditation (minutes)", minimum=0) | |
brain_training_minutes = gr.Number(label="Brain Training (minutes)", minimum=0) | |
log_metrics_btn = gr.Button("Log Metrics") | |
with gr.Column(scale=2): | |
gr.Markdown("### Log Activity") | |
category = gr.Dropdown(label="Category", choices=["Work", "Life", "Health", "Sleep"]) | |
subcategory = gr.Textbox(label="Subcategory") | |
start_time = gr.Textbox(label="Start Time (HH:MM)") | |
end_time = gr.Textbox(label="End Time (HH:MM)") | |
log_activity_btn = gr.Button("Log Activity") | |
gr.Markdown("### Today's Overview") | |
with gr.Row(): | |
today_activities = gr.DataFrame(label="Today's Activities") | |
today_metrics = gr.DataFrame(label="Today's Metrics") | |
gr.Markdown("### Weekly Summary") | |
with gr.Row(): | |
weekly_pie_chart = gr.Plot(label="Activity Distribution") | |
weekly_line_chart = gr.Plot(label="Score Trends") | |
update_dashboard_btn = gr.Button("Refresh Dashboard") | |
# Analysis Tab | |
with gr.TabItem("Analysis"): | |
analysis_period = gr.Radio(["Weekly", "Monthly"], label="Analysis Period", value="Weekly") | |
update_analysis_btn = gr.Button("Update Analysis") | |
with gr.Row(): | |
analysis_pie_chart = gr.Plot(label="Activity Distribution") | |
analysis_line_chart = gr.Plot(label="Score Trends") | |
analysis_total_hours = gr.Number(label="Total Hours", precision=2) | |
# Add a detailed breakdown table | |
analysis_breakdown = gr.DataFrame(label="Detailed Breakdown") | |
def update_analysis(user_name, period): | |
if period == "Weekly": | |
pie_chart, line_chart, total_hours = analyze_weekly_data(user_name) | |
breakdown_data = get_weekly_data(user_name) | |
else: | |
pie_chart, line_chart, total_hours = analyze_monthly_data(user_name) | |
breakdown_data = get_monthly_data(user_name) | |
breakdown_data['duration'] = breakdown_data['end_time'] - breakdown_data['start_time'] | |
breakdown_data['duration_hours'] = breakdown_data['duration'].dt.total_seconds() / 3600 | |
breakdown_summary = breakdown_data.groupby(['category', 'subcategory'])['duration_hours'].sum().reset_index() | |
breakdown_summary = breakdown_summary.sort_values('duration_hours', ascending=False) | |
return pie_chart, line_chart, total_hours, breakdown_summary | |
update_analysis_btn.click(update_analysis, inputs=[user_name, analysis_period], outputs=[analysis_pie_chart, analysis_line_chart, analysis_total_hours, analysis_breakdown]) | |
# Goals Tab | |
with gr.TabItem("Goals"): | |
with gr.Row(): | |
goal_category = gr.Dropdown(label="Category", choices=["Work", "Life", "Health"]) | |
goal_description = gr.Textbox(label="Goal Description") | |
goal_target = gr.Number(label="Target Value") | |
with gr.Row(): | |
goal_start_date = gr.Textbox(label="Start Date", placeholder="YYYY-MM-DD") | |
goal_end_date = gr.Textbox(label="End Date", placeholder="YYYY-MM-DD") | |
set_goal_btn = gr.Button("Set Goal") | |
goals_table = gr.DataFrame(label="Current Goals") | |
# Settings Tab | |
with gr.TabItem("Settings"): | |
preset_dropdown = gr.Dropdown(label="Preset Templates", choices=["Custom", "Rob Dyrdek", "Student"]) | |
default_wake_time = gr.Textbox(label="Default Wake-up Time (HH:MM)") | |
with gr.Row(): | |
work_weight = gr.Slider(label="Work Weight", minimum=0, maximum=2, step=0.1, value=1.0) | |
life_weight = gr.Slider(label="Life Weight", minimum=0, maximum=2, step=0.1, value=1.0) | |
health_weight = gr.Slider(label="Health Weight", minimum=0, maximum=2, step=0.1, value=1.0) | |
update_settings_btn = gr.Button("Update Settings") | |
# New: Documentation Tab | |
with gr.TabItem("Documentation"): | |
gr.Markdown(""" | |
# Life Tracking System Documentation | |
Welcome to the Life Tracking System, inspired by Rob Dyrdek's philosophy of maintaining a "Rhythm of Existence". This system is designed to help you monitor and optimize various aspects of your life, including work, health, personal life, and sleep. | |
## Getting Started | |
1. Use the Setup tab to configure your profile and preferences. | |
2. Choose a preset template or customize your own categories and subcategories. | |
3. Set your default wake-up time and adjust weights for work, life, and health. | |
4. Use the Dashboard to log your daily activities and metrics. | |
5. Review your progress in the Analysis tab. | |
6. Set and track your goals in the Goals tab. | |
## Key Features | |
- Guided setup process | |
- Daily activity tracking | |
- Qualitative and quantitative metric logging | |
- Weekly and monthly analysis | |
- Visualization and reporting | |
- Goal setting and progress monitoring | |
- Customizable categories and subcategories | |
## Tips for Success | |
- Be consistent in logging your activities and metrics. | |
- Review your weekly and monthly analyses regularly. | |
- Adjust your goals as needed based on your progress. | |
- Use the preset templates to get started quickly. | |
- Customize your categories and subcategories to fit your lifestyle. | |
## Rob Dyrdek's Philosophy | |
Rob Dyrdek's approach to life and success emphasizes: | |
1. Passion-driven productivity | |
2. Taking calculated risks | |
3. Setting big goals | |
4. Hard work and perseverance | |
5. Innovation and creativity | |
6. Authenticity in decision-making | |
7. Learning from failures | |
Incorporate these principles into your daily routine to maximize your potential and achieve your goals. | |
For more detailed information on how to use specific features, please refer to the respective tabs in the application. | |
""") | |
# New: Daily Checklist Tab | |
with gr.TabItem("Daily Checklist"): | |
gr.Markdown("## Daily Checklist and Notes") | |
checklist_date = gr.Textbox(label="Date", value=datetime.now().strftime("%Y-%m-%d"), placeholder="YYYY-MM-DD") | |
with gr.Row(): | |
with gr.Column(scale=2): | |
checklist_items = [ | |
gr.Checkbox(label="Wake up & Mindfulness (30 minutes)"), | |
gr.Checkbox(label="Exercise (30-45 minutes)"), | |
gr.Checkbox(label="Meditation (20 minutes)"), | |
gr.Checkbox(label="Morning Walk with Nala (1 hour 15 minutes)"), | |
gr.Checkbox(label="Active Learning with Breakfast (1 hour)"), | |
gr.Checkbox(label="Work (3 hours 30 minutes)"), | |
gr.Checkbox(label="Lunch Break (30 minutes)"), | |
gr.Checkbox(label="Work (4 hours)"), | |
gr.Checkbox(label="Active Learning (20 mins - 1 hour, 3x a week)"), | |
gr.Checkbox(label="Brain Training"), | |
gr.Checkbox(label="Reading"), | |
gr.Checkbox(label="Journaling"), | |
gr.Checkbox(label="Evening Reflection"), | |
gr.Checkbox(label="Plan for Tomorrow"), | |
] | |
with gr.Column(scale=1): | |
notes = gr.TextArea(label="Daily Notes") | |
save_checklist_btn = gr.Button("Save Daily Checklist") | |
load_checklist_btn = gr.Button("Load Checklist for Selected Date") | |
def get_daily_checklist(user_name, date): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
SELECT checklist_data, notes FROM daily_checklist | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) AND date = ? | |
''', (user_name, date)) | |
result = cursor.fetchone() | |
conn.close() | |
if result: | |
return json.loads(result[0]), result[1] | |
return {}, "" | |
def save_daily_checklist(user_name, date, checklist_data, notes): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(''' | |
INSERT OR REPLACE INTO daily_checklist (user_id, date, checklist_data, notes) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?, ?) | |
''', (user_name, date, json.dumps(checklist_data), notes)) | |
conn.commit() | |
conn.close() | |
def save_checklist(user_name, date_str, notes, *checklist_values): | |
try: | |
date_obj = datetime.strptime(date_str, "%Y-%m-%d").date() | |
checklist_data = {item.label: value for item, value in zip(checklist_items, checklist_values)} | |
save_daily_checklist(user_name, date_obj, checklist_data, notes) | |
return "Checklist saved successfully!" | |
except ValueError: | |
return "Invalid date format. Please use YYYY-MM-DD." | |
def load_checklist(user_name, date_str): | |
try: | |
date_obj = datetime.strptime(date_str, "%Y-%m-%d").date() | |
checklist_data, notes_text = get_daily_checklist(user_name, date_obj) | |
checkbox_values = [checklist_data.get(item.label, False) for item in checklist_items] | |
return checkbox_values + [notes_text, "Checklist loaded successfully!"] | |
except ValueError: | |
return [False] * len(checklist_items) + ["", "Invalid date format. Please use YYYY-MM-DD."] | |
save_checklist_btn.click( | |
save_checklist, | |
inputs=[user_name, checklist_date, notes] + checklist_items, | |
outputs=[gr.Text(label="Save Status")] | |
) | |
load_checklist_btn.click( | |
load_checklist, | |
inputs=[user_name, checklist_date], | |
outputs=checklist_items + [notes, gr.Text(label="Load Status")] | |
) | |
# Monthly Calendar Tab | |
with gr.TabItem("Monthly Calendar"): | |
gr.Markdown("## Monthly Time Allocation") | |
with gr.Row(): | |
calendar_date = gr.Textbox(label="Select Month (YYYY-MM)", value=datetime.now().strftime("%Y-%m")) | |
update_calendar_btn = gr.Button("Update Calendar") | |
monthly_calendar = gr.DataFrame(label="Monthly Time Allocation") | |
day_edit_form = gr.Group(visible=False) | |
with day_edit_form: | |
selected_date = gr.Textbox(label="Date") | |
work_hours = gr.Number(label="Work Hours", minimum=0, maximum=24) | |
life_hours = gr.Number(label="Life Hours", minimum=0, maximum=24) | |
health_hours = gr.Number(label="Health Hours", minimum=0, maximum=24) | |
sleep_hours = gr.Number(label="Sleep Hours", minimum=0, maximum=24) | |
save_day_btn = gr.Button("Save") | |
edit_buttons = gr.HTML() # This will hold our edit buttons | |
def open_day_edit_form(date): | |
return gr.update(visible=True), gr.update(value=date) | |
def save_day_data(user_name, date, work, life, health, sleep): | |
save_day_activities(user_name, date, work, life, health, sleep) | |
return gr.update(visible=False), update_monthly_calendar(user_name, calendar_date.value) | |
save_day_btn.click( | |
save_day_data, | |
inputs=[user_name, selected_date, work_hours, life_hours, health_hours, sleep_hours], | |
outputs=[day_edit_form, monthly_calendar] | |
) | |
def update_monthly_calendar(user_name, date): | |
try: | |
year, month = map(int, date.split('-')) | |
except ValueError: | |
year, month = datetime.now().year, datetime.now().month | |
df = get_monthly_data(user_name, year, month) | |
calendar_df = format_monthly_data(df, year, month) | |
return calendar_df | |
def create_day_buttons(df): | |
buttons_html = "" | |
for _, row in df.iterrows(): | |
date = row['date'] | |
buttons_html += f'<button onclick="edit_day(\'{date}\')">{date}</button>' | |
return buttons_html | |
update_calendar_btn.click( | |
lambda user, date: (update_monthly_calendar(user, date), create_day_buttons(update_monthly_calendar(user, date))), | |
inputs=[user_name, calendar_date], | |
outputs=[monthly_calendar, edit_buttons] | |
) | |
# Event handlers and function definitions | |
def log_and_display(user_name, date, category, subcategory, start_time, end_time): | |
log_activity(user_name, date, category, subcategory, start_time, end_time) | |
activities = get_activities(user_name, date) | |
return activities, len(activities) | |
def log_and_display_metrics(user_name, date, life_score, work_score, health_score, wake_up_time, workouts, meditation_minutes, brain_training_minutes): | |
log_qualitative_metrics(user_name, date, life_score, work_score, health_score) | |
log_quantitative_metrics(user_name, date, wake_up_time, workouts, meditation_minutes, brain_training_minutes) | |
metrics = get_metrics(user_name, date) | |
return metrics, life_score, work_score, health_score, wake_up_time | |
def update_dashboard(user_name, date): | |
today_activities_data = get_activities(user_name, date) | |
today_metrics_data = get_metrics(user_name, date) | |
weekly_pie_chart_data, weekly_line_chart_data, total_hours = analyze_weekly_data(user_name) | |
# Calculate quick glance metrics | |
life_score = today_metrics_data['life_score'].values[0] if not today_metrics_data.empty else 0 | |
work_score = today_metrics_data['work_score'].values[0] if not today_metrics_data.empty else 0 | |
health_score = today_metrics_data['health_score'].values[0] if not today_metrics_data.empty else 0 | |
wake_up = today_metrics_data['wake_up_time'].values[0] if not today_metrics_data.empty else "" | |
total_acts = len(today_activities_data) | |
return (today_activities_data, today_metrics_data, weekly_pie_chart_data, weekly_line_chart_data, | |
life_score, work_score, health_score, wake_up, total_acts) | |
def update_analysis(user_name, period): | |
current_date = datetime.now() | |
year, month = current_date.year, current_date.month | |
if period == "Weekly": | |
df = get_weekly_data(user_name) | |
scores = get_weekly_scores(user_name) | |
else: # Monthly | |
df = get_monthly_data(user_name, year, month) | |
scores = get_monthly_scores(user_name) | |
# Ensure df is not empty | |
if df.empty: | |
return px.pie(), px.line(), 0, pd.DataFrame() | |
# Calculate duration in hours | |
df['duration'] = (df['end_time'] - df['start_time']).dt.total_seconds() / 3600 | |
breakdown_data = df.groupby(['category', 'subcategory'])['duration'].sum().reset_index() | |
breakdown_data = breakdown_data.sort_values('duration', ascending=False) | |
total_hours = breakdown_data['duration'].sum() | |
pie_chart = px.pie(breakdown_data, values='duration', names='category', title=f"{period} Activity Distribution") | |
# Ensure 'date' column exists in scores DataFrame | |
if 'date' not in scores.columns: | |
scores['date'] = scores.index if isinstance(scores.index, pd.DatetimeIndex) else pd.to_datetime(scores.index) | |
line_chart = px.line(scores, x='date', y=['life_score', 'work_score', 'health_score'], title=f"{period} Score Trends") | |
return pie_chart, line_chart, total_hours, breakdown_data | |
def set_new_goal(user_name, category, description, target, start_date, end_date): | |
set_goal(user_name, category, description, target, start_date, end_date) | |
return get_goals(user_name) | |
def load_user_settings(user_name): | |
settings = get_user_settings(user_name) | |
return settings[0], settings[1], settings[2], settings[3] | |
def save_user_settings(user_name, wake_time, w_weight, l_weight, h_weight): | |
update_user_settings(user_name, wake_time, w_weight, l_weight, h_weight) | |
return "Settings updated successfully" | |
def create_preset_template(preset_name): | |
if preset_name == "Rob Dyrdek": | |
return { | |
"default_wake_time": "05:00", | |
"work_weight": 1.0, | |
"life_weight": 1.0, | |
"health_weight": 1.0, | |
"categories": ["Work", "Life", "Health", "Sleep"], | |
"subcategories": { | |
"Work": ["Drydek Machine", "Television", "Other"], | |
"Life": ["Rob & Bre", "Kids", "Friends & Social", "Other"], | |
"Health": ["Gym", "Meditation", "Personal Care", "Other"], | |
"Sleep": [] | |
} | |
} | |
elif preset_name == "Student": | |
return { | |
"default_wake_time": "07:00", | |
"work_weight": 1.2, | |
"life_weight": 0.8, | |
"health_weight": 1.0, | |
"categories": ["Study", "Life", "Health", "Sleep"], | |
"subcategories": { | |
"Study": ["Classes", "Homework", "Research", "Other"], | |
"Life": ["Family", "Friends", "Hobbies", "Other"], | |
"Health": ["Exercise", "Meditation", "Personal Care", "Other"], | |
"Sleep": [] | |
} | |
} | |
else: | |
# Return None or a default preset if the preset name is not recognized | |
return None | |
def update_settings_from_preset(preset_name): | |
if preset_name == "Custom": | |
return gr.update(), gr.update(), gr.update(), gr.update() | |
preset = create_preset_template(preset_name) | |
if preset is None: | |
return gr.update(), gr.update(), gr.update(), gr.update() | |
return ( | |
gr.update(value=preset.get("default_wake_time", "")), | |
gr.update(value=preset.get("work_weight", 1.0)), | |
gr.update(value=preset.get("life_weight", 1.0)), | |
gr.update(value=preset.get("health_weight", 1.0)) | |
) | |
def finish_guided_setup(user_name, preset, wake_time, w_weight, l_weight, h_weight, categories, subcategories, initial_goal): | |
# Save user settings | |
update_user_settings(user_name, wake_time, w_weight, l_weight, h_weight) | |
# Save categories and subcategories | |
save_custom_categories(user_name, categories, subcategories) | |
# Set initial goal | |
set_goal(user_name, "General", initial_goal, 100, datetime.now().date(), datetime.now().date() + timedelta(days=30)) | |
return "Setup completed successfully!" | |
# Connect event handlers to UI components | |
log_activity_btn.click(log_and_display, inputs=[user_name, date, category, subcategory, start_time, end_time], outputs=[today_activities, total_activities]) | |
log_metrics_btn.click(log_and_display_metrics, inputs=[user_name, date, life_score, work_score, health_score, wake_up_time, workouts, meditation_minutes, brain_training_minutes], outputs=[today_metrics, today_life_score, today_work_score, today_health_score, wake_up_time]) | |
update_dashboard_btn.click(update_dashboard, inputs=[user_name, date], outputs=[today_activities, today_metrics, weekly_pie_chart, weekly_line_chart, today_life_score, today_work_score, today_health_score, wake_up_time, total_activities]) | |
update_analysis_btn.click(update_analysis, inputs=[user_name, analysis_period], outputs=[analysis_pie_chart, analysis_line_chart, analysis_total_hours]) | |
set_goal_btn.click(set_new_goal, inputs=[user_name, goal_category, goal_description, goal_target, goal_start_date, goal_end_date], outputs=[goals_table]) | |
update_settings_btn.click(save_user_settings, inputs=[user_name, default_wake_time, work_weight, life_weight, health_weight], outputs=[gr.Textbox(label="Settings Status")]) | |
preset_dropdown.change(update_settings_from_preset, inputs=[preset_dropdown], outputs=[default_wake_time, work_weight, life_weight, health_weight]) | |
# Additional functions that might be needed | |
def save_custom_categories(user_name, categories, subcategories): | |
conn = create_connection() | |
cursor = conn.cursor() | |
# First, delete existing custom categories for the user | |
cursor.execute("DELETE FROM custom_categories WHERE user_id = (SELECT id FROM users WHERE name = ?)", (user_name,)) | |
# Insert new custom categories | |
for category in categories: | |
cursor.execute(""" | |
INSERT INTO custom_categories (user_id, category_name, subcategories) | |
VALUES ((SELECT id FROM users WHERE name = ?), ?, ?) | |
""", (user_name, category, ','.join(subcategories.get(category, [])))) | |
conn.commit() | |
conn.close() | |
def get_custom_categories(user_name): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute(""" | |
SELECT category_name, subcategories | |
FROM custom_categories | |
WHERE user_id = (SELECT id FROM users WHERE name = ?) | |
""", (user_name,)) | |
results = cursor.fetchall() | |
conn.close() | |
categories = [row[0] for row in results] | |
subcategories = {row[0]: row[1].split(',') for row in results} | |
return categories, subcategories | |
# Add this function to update the category dropdown in the UI | |
def update_category_dropdown(user_name): | |
categories, _ = get_custom_categories(user_name) | |
return gr.update(choices=categories) | |
# Connect the update_category_dropdown function to the user_name input | |
user_name.change(update_category_dropdown, inputs=[user_name], outputs=[category]) | |
# Add event handlers for adding and deleting user profiles | |
def add_user(new_name): | |
add_user_profile(new_name) | |
generate_placeholder_data(new_name) | |
return gr.update(choices=get_user_list(), value=new_name) | |
def delete_user(name): | |
delete_user_profile(name) | |
return gr.update(choices=get_user_list(), value=get_user_list()[0] if get_user_list() else None) | |
add_user_btn.click(add_user, inputs=[new_user_name], outputs=[user_name]) | |
delete_user_btn.click(delete_user, inputs=[user_name], outputs=[user_name]) | |
# Function to get the list of users | |
def get_user_list(): | |
conn = create_connection() | |
cursor = conn.cursor() | |
cursor.execute("SELECT name FROM users") | |
users = [row[0] for row in cursor.fetchall()] | |
if not users: | |
cursor.execute("INSERT INTO users (name) VALUES (?)", ("John Doe",)) | |
conn.commit() | |
users = ["John Doe"] | |
conn.close() | |
return users | |
# Update the user_name dropdown when the interface loads | |
demo.load(lambda: gr.update(choices=get_user_list()), outputs=[user_name]) | |
# Launch the application | |
demo.launch() |