carrier / app.py
farone11's picture
Update app.py
2610fc1 verified
Raw
History Blame Contribute Delete
11.7 kB
import gradio as gr
import pandas as pd
import plotly.express as px
df = pd.read_csv("sample_100_jobs.csv")
def filter_data(industry, country, max_risk, min_salary):
d = df.copy()
if industry != "All": d = d[d["Industry"] == industry]
if country != "All": d = d[d["Country"] == country]
d = d[(d["AI_Replacement_Risk"] <= max_risk) & (d["Average_Salary_USD"] >= min_salary)]
return d.sort_values("Demand_Risk_Ratio", ascending=False)
def scatter():
fig = px.scatter(df, x="AI_Replacement_Risk", y="Average_Salary_USD",
color="AI_Risk_Category", size="Demand_Risk_Ratio",
hover_data=["Job_Title"], template="plotly_dark", height=420,
color_discrete_map={"Low":"#10B981","Medium":"#3B82F6","High":"#EF4444"})
fig.update_layout(
paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)",
margin=dict(l=10,r=10,t=40,b=10), font=dict(family="Inter")
)
return fig
def top_jobs():
top = df.nlargest(10, "Demand_Risk_Ratio")
fig = px.bar(top, x="Demand_Risk_Ratio", y="Job_Title", orientation="h",
template="plotly_dark", color="Demand_Risk_Ratio", height=420,
color_continuous_scale="Viridis")
fig.update_layout(
paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)",
yaxis={"categoryorder":"total ascending"}, font=dict(family="Inter")
)
return fig
css = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');
* {font-family: 'Inter', sans-serif !important;}
body{
background: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(120,119,198,0.3), transparent),
radial-gradient(ellipse 80% 50% at 50% 120%, rgba(79,70,229,0.2), transparent),
linear-gradient(180deg, #020617 0%, #0F172A 50%, #020617 100%) !important;
background-attachment: fixed !important;
}
.gradio-container{
width:96% !important;
max-width:1400px !important;
margin: 0 auto !important;
}
/* ANIMASI GRADIENT BERJALAN */
@keyframes gradientFlow {
0% {background-position: 0% 50%;}
50% {background-position: 100% 50%;}
100% {background-position: 0% 50%;}
}
.animated-gradient {
background: linear-gradient(90deg, #60A5FA, #A855F7, #EC4899, #60A5FA);
background-size: 300% 300%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientFlow 4s ease infinite;
}
/* NAVBAR */
.navbar{
display: flex;justify-content: space-between;align-items: center;
padding: 20px 0;margin-bottom: 30px;
}
.nav-left{display:flex;align-items:center;gap:40px}
.logo{display:flex;align-items:center;gap:12px;font-weight:900;font-size:22px;color:#fff}
.logo-icon{
width:32px;height:32px;border-radius:8px;
background:linear-gradient(135deg,#6366F1,#A855F7);
display:flex;align-items:center;justify-content:center;
box-shadow:0 0 20px rgba(99,102,241,.6);
}
.nav-links{display:flex;gap:32px}
.nav-links a{color:#94A3B8;text-decoration:none;font-weight:600;font-size:14px}
.nav-links a:hover{color:#fff}
.nav-right{display:flex;gap:12px}
.btn-ghost{
background:rgba(30,41,59,.6);border:1px solid rgba(99,102,241,.3);
color:#fff;padding:10px 20px;border-radius:12px;font-weight:700;cursor:pointer;
}
.btn-primary{
background:linear-gradient(90deg,#6366F1,#A855F7);
color:#fff;padding:10px 24px;border-radius:12px;border:none;
font-weight:700;cursor:pointer;
box-shadow:0 4px 20px rgba(99,102,241,.4), 0 0 40px rgba(99,102,241,.2);
}
/* HERO */
.hero{
padding:70px 45px;
border-radius:24px;
background: linear-gradient(135deg, rgba(15,23,42,.8), rgba(30,41,59,.6));
border:1px solid rgba(99,102,241,.2);
box-shadow: 0 0 60px rgba(99,102,241,.15), inset 0 1px 0 rgba(255,255,255,.1);
margin-bottom:40px;
text-align: center;
backdrop-filter: blur(20px);
position:relative;overflow:hidden;
}
.hero::before{
content:'';position:absolute;top:-50%;left:50%;transform:translateX(-50%);
width:600px;height:600px;
background:radial-gradient(circle, rgba(99,102,241,.25), transparent 70%);
filter:blur(80px);z-index:0;
}
.hero-badge{
display:inline-flex;align-items:center;gap:8px;
padding:8px 16px;background:rgba(99,102,241,.1);
border:1px solid rgba(99,102,241,.3);border-radius:99px;
font-size:14px;color:#A5B4FC;margin-bottom:24px;position:relative;z-index:1;font-weight:600;
}
.hero h1{
font-size:68px;line-height:1.1;font-weight:900;
margin:0 0 16px 0;position:relative;z-index:1;
color:#FFFFFF;
letter-spacing:-1px;
}
.hero h1 .gradient{
font-weight:900;
display:block;
margin-top:8px;
}
.hero p{
font-size:18px;color:#CBD5E1;max-width:700px;
margin:0 auto 32px auto;line-height:1.7;position:relative;z-index:1;font-weight:500;
}
.hero-cta{display:flex;gap:16px;justify-content:center;position:relative;z-index:1}
/* STATS */
.stats{
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 80px;
}
.stat-card{
padding:28px 24px;
border-radius:20px;
background: linear-gradient(135deg, rgba(99,102,241,.1), rgba(168,85,247,.05));
backdrop-filter: blur(20px);
border: 1px solid rgba(99,102,241,.2);
text-align: center;
box-shadow: 0 8px 32px rgba(99,102,241,.1);
}
.stat-card .label{
display:flex;align-items:center;gap:8px;justify-content:center;
color:#94A3B8;font-size:14px;margin-bottom:12px;font-weight:600;
}
.stat-card .value{
font-size:36px;font-weight:900;
background: linear-gradient(90deg, #6366F1, #A855F7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* DASHBOARD */
.section-header{margin-bottom:32px}
.section-header h2{font-size:32px;margin:0 0 8px 0;font-weight:900;color:#fff}
.section-header p{color:#94A3B8;margin:0;font-size:15px;font-weight:500}
.card{
padding:24px;border-radius:20px;
background: rgba(15,23,42,.6) !important;
backdrop-filter: blur(20px) !important;
border: 1px solid rgba(99,102,241,.15) !important;
margin-bottom:24px;box-shadow: 0 8px 32px rgba(0,0,0,.3);
}
.footer{
margin-top:60px;padding:40px 30px;text-align:center;
color: #64748B;border-top: 1px solid rgba(99,102,241,.1);font-weight: 600;
}
@media (max-width: 768px) {
.nav-links{display:none}
.hero h1 { font-size: 42px; }
.stats { grid-template-columns: repeat(2, 1fr); }
.hero-cta{flex-direction:column}
}
"""
with gr.Blocks(css=css, fill_width=True, theme=gr.themes.Base()) as demo:
# NAVBAR
gr.HTML("""
<div class='navbar'>
<div class='nav-left'>
<div class='logo'>
<div class='logo-icon'>β—†</div>
AI DataLab
</div>
<div class='nav-links'>
<a href='#dashboard'>Dashboard</a>
<a href='#'>Reports</a>
<a href='#'>Insights</a>
<a href='#'>About</a>
</div>
</div>
<div class='nav-right'>
<button class='btn-ghost'>Sign In</button>
<button class='btn-primary'>Get Started</button>
</div>
</div>
""")
# HERO - FONT TEBEL + GRADIENT ANIMASI
gr.HTML("""
<div class='hero'>
<div class='hero-badge'>β˜… Powered by AI-Driven Analytics</div>
<h1>
Future-Proof Your Career
<span class='gradient animated-gradient'>with AI Insights</span>
</h1>
<p>
Analyze job market trends, salary projections, and AI automation risks.
Make data-driven decisions for 2031 and beyond with real-time predictive analytics.
</p>
<div class='hero-cta'>
<button class='btn-primary' onclick="document.getElementById('dashboard').scrollIntoView({behavior:'smooth'})">
Explore Dashboard β†’
</button>
<button class='btn-ghost'>β–Ά Watch Demo</button>
</div>
</div>
""")
# STATS
gr.HTML("""
<div class='stats'>
<div class='stat-card'>
<div class='label'>⚑ Total Jobs Analyzed</div>
<div class='value'>3,000+</div>
</div>
<div class='stat-card'>
<div class='label'>$ Average Salary 2031</div>
<div class='value'>$96K</div>
</div>
<div class='stat-card'>
<div class='label'>⚠ High Risk Jobs</div>
<div class='value'>856</div>
</div>
<div class='stat-card'>
<div class='label'>✦ Future-Proof Score</div>
<div class='value'>87.5%</div>
</div>
</div>
""")
# DASHBOARD
gr.HTML("""
<div class='section-header' id='dashboard'>
<h2>Live Data Analysis Dashboard</h2>
<p>Filter and explore 100+ jobs with real-time risk scoring</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1, min_width=300):
with gr.Group(elem_classes="card"):
gr.Markdown("### πŸ” FILTERS")
industry = gr.Dropdown(["All"] + sorted(df["Industry"].unique()), value="All", label="Industry")
country = gr.Dropdown(["All"] + sorted(df["Country"].unique()), value="All", label="Country")
risk = gr.Slider(0, 1, value=.5, label="Max AI Risk")
salary = gr.Slider(0, 200000, value=50000, label="Min Salary (USD)")
btn = gr.Button("Analyze Data β†’", variant="primary")
with gr.Column(scale=4):
with gr.Group(elem_classes="card"):
gr.Plot(value=scatter())
with gr.Group(elem_classes="card"):
gr.Plot(value=top_jobs())
with gr.Group(elem_classes="card"):
gr.Markdown("### πŸ“‹ Job Dataset")
table = gr.Dataframe(value=df.head(20), interactive=False)
btn.click(filter_data, [industry,country,risk,salary], table)
# FOOTER + AUTHOR
gr.HTML("""
<div class='footer'>
<div style='margin-bottom:24px;'>
<h3 style='font-size:20px;font-weight:800;margin:0 0 8px 0;color:#fff;'>πŸ‘¨β€πŸ’» Author</h3>
<p style='font-size:18px;font-weight:700;margin:0 0 4px 0;color:#E2E8F0;'>Farly Setiawan</p>
<p style='font-size:14px;margin:0 0 16px 0;color:#94A3B8;'>Founder @ Aitopia | Specialist Data Engineer</p>
<p style='font-size:14px;margin:0 0 20px 0;color:#64748B;'>Helping 2M Indonesian traders lose less money</p>
</div>
<div style='display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-bottom:24px;'>
<a href='https://www.linkedin.com/in/faronecapital' target='_blank'>
<img src='https://img.shields.io/badge/LinkedIn-Farly_Setiawan-0077B5?style=for-the-badge&logo=linkedin&logoColor=white'>
</a>
<a href='https://huggingface.co/farone11' target='_blank'>
<img src='https://img.shields.io/badge/πŸ€—_Hugging_Face-farone11-yellow?style=for-the-badge'>
</a>
<a href='https://github.com/farone11' target='_blank'>
<img src='https://img.shields.io/badge/GitHub-farone11-181717?style=for-the-badge&logo=github'>
</a>
</div>
<div style='padding-top:24px;border-top:1px solid rgba(99,102,241,.1);'>
<p style='font-size:13px;margin:0 0 8px 0;color:#64748B;font-weight:600;'>πŸ“œ License</p>
<p style='font-size:13px;margin:0;color:#475569;'>
Commercial License Required. Demo is free for evaluation.<br>
Full datasheet & source code require purchase. Contact farone2013@gmail.com
</p>
</div>
<div style='margin-top:24px;font-size:12px;color:#475569;'>
Β© 2026 FarOneCapital Institutional Analytics Platform
</div>
</div>
""")
demo.launch()