import gradio as gr
import logging
from config import config
from utils import get_status_display
from linkedin_api import post_to_linkedin
from styles import CUSTOM_CSS
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('feedhire.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
logger.info("Starting FeedHire Job Poster application")
# Get missing configuration variables
missing_vars = config.get_missing_vars()
# Build Gradio Interface
with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="yellow"), css=CUSTOM_CSS) as demo:
logger.info("Building Gradio interface")
# Hero Section with Animated Logo and Status
with gr.Group(elem_id="hero-section"):
with gr.Row():
with gr.Column(scale=20, elem_classes="hero-column"):
gr.HTML("""
FeedHire Job Poster
Post jobs instantly to LinkedIn & reach thousands of candidates 🚀
""")
with gr.Column(scale=4, min_width=280):
status_display = gr.HTML(get_status_display())
refresh_status_btn = gr.Button("↺ Refresh", size="sm", elem_classes="refresh-btn")
# Visibility Info Banner
gr.HTML("""
""")
if missing_vars:
logger.warning(f"Displaying warning for missing vars: {missing_vars}")
gr.Warning(f"⚠️ Missing configuration: {', '.join(missing_vars)}")
# Main Content: Two-Column Layout
with gr.Row(equal_height=True):
# LEFT COLUMN - Job Posting Form
# with gr.Column(scale=1, elem_classes="form-section transparent-box", elem_id="job-form"):
with gr.Column(scale=1, elem_classes="form-section"):
gr.HTML("📝 Create Your Job Post
")
name_input = gr.Textbox(
label="👤 Your Name",
placeholder="e.g., Arif Raafi",
lines=1
)
job_post_input = gr.Textbox(
label="💼 Job Post Content",
placeholder="✨ Craft your perfect job post here...\n\n🎯 Role: \n📋 Responsibilities: \n📍 Location: \n💰 Salary Range: \n📧 How to Apply: ",
lines=12
)
submit_btn = gr.Button("🚀 Publish to LinkedIn", variant="primary", size="lg")
output = gr.Textbox(label="📊 Status", lines=2, interactive=False)
success_link = gr.Markdown(
"",
visible=False,
elem_id="success-link-box"
)
# RIGHT COLUMN - Benefits & Marketing
# with gr.Column(scale=1, elem_id="job-form", elem_classes="benefits-section transparent-box"):
with gr.Column(scale=1, elem_classes="benefits-section"):
gr.HTML("""
🌟 Why Choose FeedHire?
""")
gr.Image(
value="analytics_map.png",
show_label=False,
show_download_button=False,
container=False,
elem_classes="benefits-image",
)
gr.HTML("""
🌍
Massive Reach - Tap into LinkedIn's network and FeedHire's global ecosystem
⚡
Lightning Fast - Post once, go live instantly on multiple platforms
💯
100% Free - No hidden fees, no subscriptions—just pure visibility
🎯
Quality Candidates - Attract serious applicants
""")
# How It Works Section
gr.HTML("""
✨ How FeedHire Works
📝
Create
Fill out the form with your name and job details—make it compelling!
🚀
Publish
Hit publish and watch it go live on LinkedIn instantly via API
⚡
Go Live
Our AI refines your post before publishing it live on FeedHire.me—start attracting applicants immediately!
""")
# Footer Disclaimer
gr.HTML("""
⚠️ Important: FeedHire is not responsible for job post content.
Ensure all submissions are accurate and lawful. Fake or misleading posts will be removed.
""")
# Event Handlers
logger.info("Setting up event handlers")
submit_btn.click(
fn=post_to_linkedin,
inputs=[name_input, job_post_input],
outputs=[output, success_link],
show_progress="full"
)
def refresh_status():
logger.info("Refreshing status display")
return get_status_display()
refresh_status_btn.click(
fn=refresh_status,
outputs=[status_display]
)
demo.load(
fn=refresh_status,
outputs=[status_display]
)
if __name__ == "__main__":
logger.info("Launching Gradio application")
demo.launch(allowed_paths=["."])