kluvin's picture
Upload folder using huggingface_hub
3d366c1 verified
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8">
<title>Tweet Sentiment Classifier</title>
<link href="https://cdn.jsdelivr.net/npm/daisyui@4.12.10/dist/full.min.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body class="min-h-screen text-slate-700">
<main class="flex min-h-screen items-start justify-center px-4 py-8 sm:py-12 lg:items-center lg:max-h-screen">
<div class="w-full max-w-5xl">
<div class="rounded-3xl bg-white/95 shadow-xl ring-1 ring-slate-100 backdrop-blur lg:max-h-[90vh] lg:overflow-y-auto">
<div class="grid gap-8 p-6 md:p-8 lg:grid-cols-3 lg:p-10">
<section class="space-y-6 lg:col-span-2">
<header class="text-center lg:text-left">
<h1 class="text-3xl font-semibold text-slate-800">
<img class="mr-2 inline h-8 w-8 align-middle" src="../{{ url_for('static', filename='images/bird.png') }}" alt="bird icon">
Tweet Sentiment Classifier
</h1>
</header>
<form
class="space-y-4"
hx-post="/classify"
hx-target="#result"
hx-trigger="input changed delay:300ms from:textarea[name='text'], submit"
hx-sync="this:replace"
>
<div>
<textarea
id="text-input"
name="text"
rows="5"
placeholder="Type or paste a tweet..."
class="textarea textarea-bordered w-full resize-none rounded-2xl border border-slate-200 bg-slate-50/80 p-4 text-base text-slate-700 shadow-sm focus:border-sky-400 focus:outline-none focus:ring-2 focus:ring-sky-200"
required>{{ default_preset }}</textarea>
</div>
<div class="flex flex-wrap items-center gap-3">
<button type="submit" class="btn btn-primary rounded-full border-none bg-sky-500 px-6 text-white shadow hover:bg-sky-600">
Analyze Sentiment
</button>
<span class="text-sm text-slate-500">
Auto-analyze on
</span>
</div>
</form>
</section>
<aside class="rounded-2xl border border-slate-200 bg-slate-50/80 p-6 shadow-sm lg:self-start">
<h2 class="text-lg font-semibold text-slate-800">
Examples
</h2>
<ul class="mt-5 space-y-2">
{% for preset in presets %}
<li>
<button
type="button"
class="btn btn-sm w-full justify-start rounded-xl border border-transparent bg-white/70 text-left font-normal text-slate-600 shadow-sm transition hover:border-sky-200 hover:bg-sky-50"
data-preset-index="{{ loop.index0 }}"
>
{{ preset }}
</button>
</li>
{% endfor %}
</ul>
</aside>
<section class="lg:col-span-3">
<div id="result" class="space-y-4">{{ initial_results|safe }}</div>
</section>
</div>
</div>
</div>
</main>
<script>
const presets = {{ presets | tojson }};
const textarea = document.querySelector('#text-input');
const presetButtons = document.querySelectorAll('[data-preset-index]');
function setPreset(text, activeButton, options = {}) {
if (!textarea) {
return;
}
const { trigger = true, focus = true } = options;
textarea.value = text;
if (focus) {
textarea.focus({ preventScroll: true });
}
presetButtons.forEach((button) => {
button.classList.remove('btn-active', 'border-sky-300', 'bg-sky-100', 'text-sky-800');
button.setAttribute('aria-pressed', 'false');
});
if (activeButton) {
activeButton.classList.add('btn-active', 'border-sky-300', 'bg-sky-100', 'text-sky-800');
activeButton.setAttribute('aria-pressed', 'true');
}
if (trigger) {
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.dispatchEvent(new Event('change', { bubbles: true }));
}
}
presetButtons.forEach((button) => {
button.addEventListener('click', () => {
const index = Number.parseInt(button.dataset.presetIndex, 10);
const presetText = presets[index] ?? '';
setPreset(presetText, button);
});
});
window.addEventListener('load', () => {
if (!textarea) {
return;
}
const firstButton = presetButtons[0] ?? null;
const initialText = presets.length ? presets[0] : (textarea.value || '');
setPreset(initialText, firstButton, { trigger: false, focus: false });
});
</script>
</body>
</html>