Files
myprojplanet_vite/_LIMBO/Casi d'Uso Ollama - Esempi Pratici.html
Surya Paolo 89a8d10eae - verifica email se non è stata verificata (componente)
- altri aggiornamenti grafica PAGERIS.
- OLLAMA AI
2025-12-11 18:34:39 +01:00

1778 lines
77 KiB
HTML

<!DOCTYPE html>
<!-- saved from url=(0055)file:///Users/suryapaolo/Downloads/esempi-casi-uso.html -->
<html lang="it"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Casi d'Uso Ollama - Esempi Pratici</title>
<script src="./Casi d&#39;Uso Ollama - Esempi Pratici_files/browser@4"></script><style>/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */
@layer properties;
@layer theme, base, components, utilities;
@layer theme {
:root, :host {
--font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
monospace;
--color-red-400: oklch(70.4% 0.191 22.216);
--color-green-400: oklch(79.2% 0.209 151.711);
--color-green-600: oklch(62.7% 0.194 149.214);
--color-green-700: oklch(52.7% 0.154 150.069);
--color-purple-400: oklch(71.4% 0.203 305.504);
--color-purple-500: oklch(62.7% 0.265 303.9);
--color-purple-600: oklch(55.8% 0.288 302.321);
--color-purple-700: oklch(49.6% 0.265 301.924);
--color-pink-500: oklch(65.6% 0.241 354.308);
--color-gray-300: oklch(87.2% 0.01 258.338);
--color-gray-400: oklch(70.7% 0.022 261.325);
--color-gray-700: oklch(37.3% 0.034 259.733);
--color-gray-800: oklch(27.8% 0.033 256.848);
--color-gray-900: oklch(21% 0.034 264.665);
--color-white: #fff;
--spacing: 0.25rem;
--container-6xl: 72rem;
--text-sm: 0.875rem;
--text-sm--line-height: calc(1.25 / 0.875);
--text-xl: 1.25rem;
--text-xl--line-height: calc(1.75 / 1.25);
--text-2xl: 1.5rem;
--text-2xl--line-height: calc(2 / 1.5);
--text-4xl: 2.25rem;
--text-4xl--line-height: calc(2.5 / 2.25);
--font-weight-semibold: 600;
--font-weight-bold: 700;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
--default-font-family: var(--font-sans);
--default-mono-font-family: var(--font-mono);
}
}
@layer base {
*, ::after, ::before, ::backdrop, ::file-selector-button {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0 solid;
}
html, :host {
line-height: 1.5;
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji');
font-feature-settings: var(--default-font-feature-settings, normal);
font-variation-settings: var(--default-font-variation-settings, normal);
-webkit-tap-highlight-color: transparent;
}
hr {
height: 0;
color: inherit;
border-top-width: 1px;
}
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
h1, h2, h3, h4, h5, h6 {
font-size: inherit;
font-weight: inherit;
}
a {
color: inherit;
-webkit-text-decoration: inherit;
text-decoration: inherit;
}
b, strong {
font-weight: bolder;
}
code, kbd, samp, pre {
font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace);
font-feature-settings: var(--default-mono-font-feature-settings, normal);
font-variation-settings: var(--default-mono-font-variation-settings, normal);
font-size: 1em;
}
small {
font-size: 80%;
}
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
table {
text-indent: 0;
border-color: inherit;
border-collapse: collapse;
}
:-moz-focusring {
outline: auto;
}
progress {
vertical-align: baseline;
}
summary {
display: list-item;
}
ol, ul, menu {
list-style: none;
}
img, svg, video, canvas, audio, iframe, embed, object {
display: block;
vertical-align: middle;
}
img, video {
max-width: 100%;
height: auto;
}
button, input, select, optgroup, textarea, ::file-selector-button {
font: inherit;
font-feature-settings: inherit;
font-variation-settings: inherit;
letter-spacing: inherit;
color: inherit;
border-radius: 0;
background-color: transparent;
opacity: 1;
}
:where(select:is([multiple], [size])) optgroup {
font-weight: bolder;
}
:where(select:is([multiple], [size])) optgroup option {
padding-inline-start: 20px;
}
::file-selector-button {
margin-inline-end: 4px;
}
::placeholder {
opacity: 1;
}
@supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
::placeholder {
color: currentcolor;
@supports (color: color-mix(in lab, red, red)) {
color: color-mix(in oklab, currentcolor 50%, transparent);
}
}
}
textarea {
resize: vertical;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-date-and-time-value {
min-height: 1lh;
text-align: inherit;
}
::-webkit-datetime-edit {
display: inline-flex;
}
::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
padding-block: 0;
}
::-webkit-calendar-picker-indicator {
line-height: 1;
}
:-moz-ui-invalid {
box-shadow: none;
}
button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button {
appearance: button;
}
::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
height: auto;
}
[hidden]:where(:not([hidden='until-found'])) {
display: none !important;
}
}
@layer utilities {
.container {
width: 100%;
@media (width >= 40rem) {
max-width: 40rem;
}
@media (width >= 48rem) {
max-width: 48rem;
}
@media (width >= 64rem) {
max-width: 64rem;
}
@media (width >= 80rem) {
max-width: 80rem;
}
@media (width >= 96rem) {
max-width: 96rem;
}
}
.mx-auto {
margin-inline: auto;
}
.mt-2 {
margin-top: calc(var(--spacing) * 2);
}
.mb-1 {
margin-bottom: calc(var(--spacing) * 1);
}
.mb-2 {
margin-bottom: calc(var(--spacing) * 2);
}
.mb-3 {
margin-bottom: calc(var(--spacing) * 3);
}
.mb-4 {
margin-bottom: calc(var(--spacing) * 4);
}
.mb-6 {
margin-bottom: calc(var(--spacing) * 6);
}
.block {
display: block;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
.hidden {
display: none;
}
.max-h-\[300px\] {
max-height: 300px;
}
.max-h-\[400px\] {
max-height: 400px;
}
.min-h-\[100px\] {
min-height: 100px;
}
.min-h-\[150px\] {
min-height: 150px;
}
.min-h-\[200px\] {
min-height: 200px;
}
.min-h-\[250px\] {
min-height: 250px;
}
.min-h-screen {
min-height: 100vh;
}
.w-full {
width: 100%;
}
.max-w-6xl {
max-width: var(--container-6xl);
}
.min-w-\[150px\] {
min-width: 150px;
}
.min-w-\[200px\] {
min-width: 200px;
}
.flex-1 {
flex: 1;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-end {
align-items: flex-end;
}
.gap-2 {
gap: calc(var(--spacing) * 2);
}
.gap-4 {
gap: calc(var(--spacing) * 4);
}
.space-y-6 {
:where(& > :not(:last-child)) {
--tw-space-y-reverse: 0;
margin-block-start: calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));
margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)));
}
}
.overflow-auto {
overflow: auto;
}
.rounded-lg {
border-radius: var(--radius-lg);
}
.rounded-xl {
border-radius: var(--radius-xl);
}
.bg-gray-700 {
background-color: var(--color-gray-700);
}
.bg-gray-800 {
background-color: var(--color-gray-800);
}
.bg-gray-900 {
background-color: var(--color-gray-900);
}
.bg-green-600 {
background-color: var(--color-green-600);
}
.bg-purple-600 {
background-color: var(--color-purple-600);
}
.bg-gradient-to-r {
--tw-gradient-position: to right in oklab;
background-image: linear-gradient(var(--tw-gradient-stops));
}
.from-purple-400 {
--tw-gradient-from: var(--color-purple-400);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.to-pink-500 {
--tw-gradient-to: var(--color-pink-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.bg-clip-text {
background-clip: text;
}
.p-4 {
padding: calc(var(--spacing) * 4);
}
.p-6 {
padding: calc(var(--spacing) * 6);
}
.px-3 {
padding-inline: calc(var(--spacing) * 3);
}
.px-4 {
padding-inline: calc(var(--spacing) * 4);
}
.py-2 {
padding-block: calc(var(--spacing) * 2);
}
.py-8 {
padding-block: calc(var(--spacing) * 8);
}
.text-center {
text-align: center;
}
.text-2xl {
font-size: var(--text-2xl);
line-height: var(--tw-leading, var(--text-2xl--line-height));
}
.text-4xl {
font-size: var(--text-4xl);
line-height: var(--tw-leading, var(--text-4xl--line-height));
}
.text-sm {
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
}
.text-xl {
font-size: var(--text-xl);
line-height: var(--tw-leading, var(--text-xl--line-height));
}
.font-bold {
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
.font-semibold {
--tw-font-weight: var(--font-weight-semibold);
font-weight: var(--font-weight-semibold);
}
.text-gray-300 {
color: var(--color-gray-300);
}
.text-gray-400 {
color: var(--color-gray-400);
}
.text-green-400 {
color: var(--color-green-400);
}
.text-purple-400 {
color: var(--color-purple-400);
}
.text-red-400 {
color: var(--color-red-400);
}
.text-transparent {
color: transparent;
}
.text-white {
color: var(--color-white);
}
.outline-none {
--tw-outline-style: none;
outline-style: none;
}
.hover\:bg-green-700 {
&:hover {
@media (hover: hover) {
background-color: var(--color-green-700);
}
}
}
.hover\:bg-purple-700 {
&:hover {
@media (hover: hover) {
background-color: var(--color-purple-700);
}
}
}
.focus\:ring-2 {
&:focus {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
}
.focus\:ring-purple-500 {
&:focus {
--tw-ring-color: var(--color-purple-500);
}
}
.md\:grid-cols-2 {
@media (width >= 48rem) {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
}
@property --tw-space-y-reverse {
syntax: "*";
inherits: false;
initial-value: 0;
}
@property --tw-gradient-position {
syntax: "*";
inherits: false;
}
@property --tw-gradient-from {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-via {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-to {
syntax: "<color>";
inherits: false;
initial-value: #0000;
}
@property --tw-gradient-stops {
syntax: "*";
inherits: false;
}
@property --tw-gradient-via-stops {
syntax: "*";
inherits: false;
}
@property --tw-gradient-from-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 0%;
}
@property --tw-gradient-via-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 50%;
}
@property --tw-gradient-to-position {
syntax: "<length-percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-font-weight {
syntax: "*";
inherits: false;
}
@property --tw-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-inset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-ring-inset {
syntax: "*";
inherits: false;
}
@property --tw-ring-offset-width {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --tw-ring-offset-color {
syntax: "*";
inherits: false;
initial-value: #fff;
}
@property --tw-ring-offset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@layer properties {
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
*, ::before, ::after, ::backdrop {
--tw-space-y-reverse: 0;
--tw-gradient-position: initial;
--tw-gradient-from: #0000;
--tw-gradient-via: #0000;
--tw-gradient-to: #0000;
--tw-gradient-stops: initial;
--tw-gradient-via-stops: initial;
--tw-gradient-from-position: 0%;
--tw-gradient-via-position: 50%;
--tw-gradient-to-position: 100%;
--tw-font-weight: initial;
--tw-shadow: 0 0 #0000;
--tw-shadow-color: initial;
--tw-shadow-alpha: 100%;
--tw-inset-shadow: 0 0 #0000;
--tw-inset-shadow-color: initial;
--tw-inset-shadow-alpha: 100%;
--tw-ring-color: initial;
--tw-ring-shadow: 0 0 #0000;
--tw-inset-ring-color: initial;
--tw-inset-ring-shadow: 0 0 #0000;
--tw-ring-inset: initial;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
}
}
}
</style>
<style>
.loader {
border: 3px solid #f3f3f3;
border-top: 3px solid #8b5cf6;
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: inline-block;
}
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
pre { white-space: pre-wrap; word-break: break-word; }
.tab-active { background: #8b5cf6; color: white; }
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-6xl">
<h1 class="text-4xl font-bold text-center mb-2 bg-gradient-to-r from-purple-400 to-pink-500 bg-clip-text text-transparent">
🦙 Casi d'Uso Ollama
</h1>
<p class="text-center text-gray-400 mb-4">Esempi pratici con llama3.2:3b</p>
<!-- Config -->
<div class="bg-gray-800 rounded-xl p-4 mb-6">
<div class="flex flex-wrap gap-4 items-end">
<div class="flex-1 min-w-[200px]">
<label class="block text-sm text-gray-400 mb-1">API URL</label>
<input type="text" id="apiUrl" value="http://localhost:3001/api2" class="w-full bg-gray-700 rounded-lg px-3 py-2 text-white focus:ring-2 focus:ring-purple-500 outline-none">
</div>
<div class="min-w-[150px]">
<label class="block text-sm text-gray-400 mb-1">Modello</label>
<input type="text" id="model" value="llama3.2:3b" class="w-full bg-gray-700 rounded-lg px-3 py-2 text-white focus:ring-2 focus:ring-purple-500 outline-none">
</div>
<button onclick="testConnection()" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg">
🔌 Test Connessione
</button>
</div>
<div id="connectionStatus" class="mt-2 text-sm"><span class="text-green-400">✅ Connesso! Ollama funzionante.</span></div>
</div>
<!-- Tabs -->
<div class="flex flex-wrap gap-2 mb-6">
<button onclick="showTab(&#39;ecommerce&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700" data-tab="ecommerce">🛒 E-Commerce</button>
<button onclick="showTab(&#39;content&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700" data-tab="content">✍️ Content</button>
<button onclick="showTab(&#39;support&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700" data-tab="support">🎧 Supporto</button>
<button onclick="showTab(&#39;data&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700" data-tab="data">📊 Dati</button>
<button onclick="showTab(&#39;forms&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700 tab-active" data-tab="forms">📝 Forms</button>
<button onclick="showTab(&#39;social&#39;)" class="tab-btn px-4 py-2 rounded-lg bg-gray-700" data-tab="social">📱 Social</button>
</div>
<!-- ==================== E-COMMERCE ==================== -->
<div id="tab-ecommerce" class="tab-content space-y-6 hidden">
<h2 class="text-2xl font-bold text-purple-400">🛒 E-Commerce</h2>
<!-- Descrizione Prodotto -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📦 Generatore Descrizioni Prodotto</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Nome Prodotto</label>
<input type="text" id="productName" value="Zaino Impermeabile 30L" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<label class="block text-sm text-gray-400 mb-2">Caratteristiche (opzionale)</label>
<textarea id="productFeatures" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3" placeholder="es: impermeabile, 30 litri, tasche laterali...">impermeabile, 30 litri, tasche laterali per borraccia, scomparto laptop 15", nero opaco</textarea>
<label class="block text-sm text-gray-400 mb-2">Stile</label>
<select id="productStyle" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="professionale">Professionale</option>
<option value="accattivante">Accattivante/Marketing</option>
<option value="tecnico">Tecnico/Dettagliato</option>
<option value="minimalista">Minimalista</option>
</select>
<button onclick="generateProductDesc()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
✨ Genera Descrizione
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risultato</label>
<div id="productResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">Il nostro zaino Impermeabile 30L è progettato per fornire comfort e protezione durante le tue avventure esterne. Costruito con materiali di alta qualità, questo zaino offre un'immunità all'acqua grazie alla sua impermeabilità, garantendo che i tuoi oggetti rimangano asciutti anche in condizioni meteo avverse.<br><br>Il zaino dispone di spazioso contenuto con una capacità totale di 30 litri, perfetto per trasportare tutti i tuoi necessari. Le tasche laterali, dotate di porte a valvola per le borraccie, ti consentono di accedere facilmente al tuo acquisto senza distoglierti dal cammino.<br><br>Il zaino include anche un scomparto dedicato per il laptop da 15", garantendo che la tua schermata rimanga protetta e sicura. Il tutto è coperto dalla nostra garanzia, rendendo questo zaino una scelta ottimale per chi cerca un accessorio funzionale e duraturo.<br><br>Il nostro zaino Impermeabile 30L è disponibile in una versione nero opaco, che si abbina perfettamente ai tuoi stili e colori preferiti.</div>
</div>
</div>
</div>
<!-- Analisi Recensioni -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">⭐ Analisi Recensioni Clienti</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Recensione</label>
<textarea id="reviewText" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Prodotto arrivato in ritardo di 3 giorni, però la qualità è eccellente! Il materiale è resistente e le cuciture sono perfette. Peccato per la spedizione, altrimenti 5 stelle.</textarea>
<button onclick="analyzeReview()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
🔍 Analizza Recensione
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Analisi</label>
<div id="reviewResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Analizza Recensione" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Risposte Automatiche Recensioni -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">💬 Genera Risposta a Recensione</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Recensione del cliente</label>
<textarea id="reviewForReply" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Pessima esperienza. Pacco arrivato danneggiato e assistenza clienti inesistente. Non comprerò mai più.</textarea>
<label class="block text-sm text-gray-400 mb-2">Nome azienda</label>
<input type="text" id="companyName" value="TechStore Italia" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="generateReviewReply()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
✍️ Genera Risposta Professionale
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risposta suggerita</label>
<div id="replyResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Genera Risposta" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Categorizzazione Prodotti -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">🏷️ Categorizzazione Automatica Prodotti</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Descrizione Prodotto</label>
<textarea id="productToCategory" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Smartphone Samsung Galaxy S24 Ultra, display 6.8" AMOLED, 12GB RAM, 256GB storage, fotocamera 200MP, 5G</textarea>
<label class="block text-sm text-gray-400 mb-2">Categorie disponibili</label>
<input type="text" id="categories" value="Elettronica, Abbigliamento, Casa e Giardino, Sport, Libri, Giocattoli, Alimentari" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="categorizeProduct()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
🏷️ Categorizza
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risultato</label>
<div id="categoryResult" class="bg-gray-900 rounded-lg p-4 min-h-[100px] text-gray-300">
Clicca "Categorizza" per vedere il risultato...
</div>
</div>
</div>
</div>
</div>
<!-- ==================== CONTENT ==================== -->
<div id="tab-content" class="tab-content space-y-6 hidden">
<h2 class="text-2xl font-bold text-purple-400">✍️ Content Creation</h2>
<!-- Blog Post Ideas -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">💡 Generatore Idee Blog</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Argomento/Nicchia</label>
<input type="text" id="blogTopic" value="cucina vegana" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<label class="block text-sm text-gray-400 mb-2">Numero di idee</label>
<input type="number" id="blogIdeasCount" value="5" min="1" max="10" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="generateBlogIdeas()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
💡 Genera Idee
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Idee per articoli</label>
<div id="blogIdeasResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">Certo, ecco 5 idee per articoli di blog sulla cucina vegana:<br><br>1. **"La scoperta segreta della cucina indiana: come fare risotto senza latte né uova"<br>Descrivere la ricetta classica del risotto vegano indiano e fornire una versione moderna e innovativa.<br><br>2. **"5 snack vegan per una vita più sana e felice"<br>Proporre 5 snack salutari e gustosi che possono essere preparati facilmente a casa senza l'uso di prodotti animali.<br><br>3. **"La cucina mediterranea vegana: come fare paella senza pollo né pesce"<br>Presentare una ricetta di paella vegana tipica della cucina mediterranea e fornire consigli per variare la ricetta in base alle preferenze personali.<br><br>4. **"Come creare un menù vegano equilibrato per una vita più sana"<br>Offrire consigli e suggerimenti per creare un menù vegano completo e bilanciato, incluso consigli su come scegliere le fonti di proteine vegetali.<br><br>5. **"La cucina cinese vegana: come fare dumplings senza carne né latte"<br>Presentare una ricetta di dumplings vegani tipici della cucina cinese e fornire consigli per variare la ricetta in base alle preferenze personali.</div>
</div>
</div>
</div>
<!-- Email Writer -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📧 Scrittore Email Professionale</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Tipo Email</label>
<select id="emailType" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="followup">Follow-up cliente</option>
<option value="proposta">Proposta commerciale</option>
<option value="ringraziamento">Ringraziamento</option>
<option value="sollecito">Sollecito pagamento</option>
<option value="scuse">Scuse per disservizio</option>
</select>
<label class="block text-sm text-gray-400 mb-2">Contesto/Dettagli</label>
<textarea id="emailContext" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Cliente che ha richiesto preventivo per sito web 3 giorni fa, non ha ancora risposto</textarea>
<label class="block text-sm text-gray-400 mb-2">Tono</label>
<select id="emailTone" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="professionale">Professionale</option>
<option value="amichevole">Amichevole</option>
<option value="formale">Molto formale</option>
</select>
<button onclick="generateEmail()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
📧 Genera Email
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Email generata</label>
<div id="emailResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">
Clicca "Genera Email" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Riscrittura Testi -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">🔄 Riscrittura/Miglioramento Testi</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Testo originale</label>
<textarea id="textToRewrite" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Ciao, volevo dire che il nostro prodotto è molto buono e costa poco. Se vuoi comprarlo vai sul sito. Grazie.</textarea>
<label class="block text-sm text-gray-400 mb-2">Obiettivo</label>
<select id="rewriteGoal" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="professionale">Rendi più professionale</option>
<option value="persuasivo">Rendi più persuasivo</option>
<option value="semplice">Semplifica</option>
<option value="formale">Rendi più formale</option>
<option value="coinvolgente">Rendi più coinvolgente</option>
</select>
<button onclick="rewriteText()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
🔄 Riscrivi
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Testo riscritto</label>
<div id="rewriteResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Riscrivi" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- SEO Meta -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">🔍 Generatore Meta Tags SEO</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Contenuto pagina</label>
<textarea id="pageContent" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Vendiamo scarpe da running Nike, Adidas e Asics. Spedizione gratuita sopra 50€. Ampia selezione di taglie e colori.</textarea>
<label class="block text-sm text-gray-400 mb-2">Keyword principale</label>
<input type="text" id="mainKeyword" value="scarpe da running" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="generateSEO()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
🔍 Genera Meta Tags
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Meta Tags</label>
<div id="seoResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Genera Meta Tags" per vedere il risultato...
</div>
</div>
</div>
</div>
</div>
<!-- ==================== SUPPORTO ==================== -->
<div id="tab-support" class="tab-content space-y-6 hidden">
<h2 class="text-2xl font-bold text-purple-400">🎧 Supporto Clienti</h2>
<!-- FAQ Generator -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">❓ Generatore FAQ</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Descrizione servizio/prodotto</label>
<textarea id="faqContext" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">E-commerce di abbigliamento con spedizione in 24/48h, reso gratuito entro 30 giorni, pagamento con carta o PayPal, taglie dalla XS alla XXL</textarea>
<label class="block text-sm text-gray-400 mb-2">Numero FAQ</label>
<input type="number" id="faqCount" value="5" min="3" max="10" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="generateFAQ()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
❓ Genera FAQ
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">FAQ Generate</label>
<div id="faqResult" class="bg-gray-900 rounded-lg p-4 min-h-[250px] text-gray-300 overflow-auto max-h-[400px]">Ecco 5 FAQ per il servizio di e-commerce di abbigliamento:<br><br>**Q: Come posso sapere la misura della mia giacca?**<br>R: Possiamo fornirti una tabella delle misure con le relative corrispondenze, in modo da poterti scegliere la giacca più adatta.<br><br>**Q: Posso restituire un'ordine se non mi piace il prodotto?**<br>R: Sì, abbiamo un periodo di 30 giorni per richiedere il restituzione del prodotto. Il costo della spedizione è a carico di noi.<br><br>**Q: Come posso pagare il mio ordine?**<br>R: Possiamo accettare pagamento con carta o PayPal. I pagamenti sono sicuri e protetti da un sistema di pagamento crittografato.<br><br>**Q: Qual è la spedizione più rapida che puoi offrire?**<br>R: Offriamo una spedizione in 24/48h su tutta l'Italia, assicurandoti di ricevere il tuo ordine entro un tempo record.<br><br>**Q: Posso modificare o annullare un ordine già inviato?**<br>R: Sì, puoi contattarci entro 2 ore dalla conferma dell'ordine per richiedere una modifica o l'annullamento. In tal caso, il costo della spedizione non sarà applicato.</div>
</div>
</div>
</div>
<!-- Ticket Classifier -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">🎫 Classificatore Ticket Supporto</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Messaggio cliente</label>
<textarea id="ticketMessage" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Salve, ho ordinato 3 giorni fa ma non ho ancora ricevuto nulla. Il tracking non si aggiorna. Ho bisogno del pacco entro venerdì per un regalo!</textarea>
<button onclick="classifyTicket()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
🎫 Classifica e Analizza
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Analisi Ticket</label>
<div id="ticketResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">
Clicca "Classifica e Analizza" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Response Suggester -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">💬 Suggeritore Risposte Supporto</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Domanda cliente</label>
<textarea id="supportQuestion" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Come posso cambiare l'indirizzo di spedizione del mio ordine?</textarea>
<label class="block text-sm text-gray-400 mb-2">Policy/Info azienda (opzionale)</label>
<textarea id="companyPolicy" rows="2" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">L'indirizzo può essere modificato solo se l'ordine non è ancora stato spedito. Contattare supporto@azienda.it</textarea>
<button onclick="suggestResponse()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
💬 Suggerisci Risposta
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risposta suggerita</label>
<div id="supportResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Suggerisci Risposta" per vedere il risultato...
</div>
</div>
</div>
</div>
</div>
<!-- ==================== DATA ==================== -->
<div id="tab-data" class="tab-content space-y-6 hidden">
<h2 class="text-2xl font-bold text-purple-400">📊 Estrazione e Analisi Dati</h2>
<!-- Estrazione Dati -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📋 Estrazione Dati Strutturati</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Testo da analizzare</label>
<textarea id="extractText" rows="4" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Gentile Sig. Marco Bianchi, la informiamo che la sua prenotazione n. 12345 presso Hotel Bellavista di Roma è confermata per il 15/03/2024 per 3 notti in camera doppia. Totale: €450. Contatto: info@hotelbellavista.it</textarea>
<label class="block text-sm text-gray-400 mb-2">Campi da estrarre (JSON schema)</label>
<textarea id="extractSchema" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">{"nome": "", "numero_prenotazione": "", "hotel": "", "città": "", "data_checkin": "", "notti": 0, "tipo_camera": "", "totale": "", "email": ""}</textarea>
<button onclick="extractData()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
📋 Estrai Dati
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Dati estratti (JSON)</label>
<div id="extractResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300"><pre>{
"nome": "Marco Bianchi",
"numero_prenotazione": "12345",
"hotel": "Hotel Bellavista",
"città": "Roma",
"data_checkin": "15/03/2024",
"notti": 3,
"tipo_camera": "camera doppia",
"totale": "€450",
"email": "info@hotelbellavista.it"
}</pre></div>
</div>
</div>
</div>
<!-- Sentiment Batch -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">😊 Analisi Sentiment Multipla</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Testi da analizzare (uno per riga)</label>
<textarea id="sentimentTexts" rows="6" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Servizio eccellente, tornerò sicuramente!
Pessima esperienza, mai più.
Il prodotto è nella media, niente di speciale.
Fantastico! Superato ogni aspettativa!
Deluso dalla qualità, non vale il prezzo.</textarea>
<button onclick="batchSentiment()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
😊 Analizza Tutti
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risultati</label>
<div id="sentimentResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300 overflow-auto max-h-[300px]">
Clicca "Analizza Tutti" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Riassunto Documenti -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📄 Riassunto Documenti</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Documento/Testo lungo</label>
<textarea id="documentText" rows="6" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">L'intelligenza artificiale (IA) è un campo dell'informatica dedicato alla creazione di sistemi capaci di svolgere compiti che normalmente richiedono intelligenza umana. Questi compiti includono l'apprendimento, il ragionamento, la risoluzione di problemi, la percezione e la comprensione del linguaggio naturale. L'IA può essere classificata in due categorie principali: IA debole (o ristretta), progettata per svolgere un compito specifico, e IA forte (o generale), che possiede capacità cognitive generalizzate simili a quelle umane. Attualmente, la maggior parte delle applicazioni di IA sono di tipo debole. Le tecniche di machine learning, in particolare il deep learning, hanno portato a progressi significativi in campi come il riconoscimento vocale, la visione artificiale e l'elaborazione del linguaggio naturale.</textarea>
<label class="block text-sm text-gray-400 mb-2">Formato</label>
<select id="summaryFormat" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="conciso">Conciso (2-3 frasi)</option>
<option value="bullet">Punti chiave</option>
<option value="dettagliato">Dettagliato</option>
</select>
<button onclick="summarizeDocument()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
📄 Riassumi
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Riassunto</label>
<div id="summaryResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">
Clicca "Riassumi" per vedere il risultato...
</div>
</div>
</div>
</div>
</div>
<!-- ==================== FORMS ==================== -->
<div id="tab-forms" class="tab-content space-y-6">
<h2 class="text-2xl font-bold text-purple-400">📝 Forms Intelligenti</h2>
<!-- Auto-complete -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">✨ Auto-completamento Intelligente</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Inizio frase/testo</label>
<textarea id="autocompleteText" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">La nostra azienda si impegna a fornire</textarea>
<label class="block text-sm text-gray-400 mb-2">Contesto (opzionale)</label>
<input type="text" id="autocompleteContext" value="sito web aziendale, sezione chi siamo" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="autocomplete()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
✨ Completa
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Suggerimenti</label>
<div id="autocompleteResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">Certo, ecco tre possibili completamenti diversi:<br><br>1. "La nostra azienda si impegna a fornire soluzioni innovative e di alta qualità ai nostri clienti, sempre con un focus sulla soddisfazione e sul successo."<br><br>2. "La nostra azienda si impegna a fornire servizi personalizzati e professionisti che soddisfano le esigenze specifiche dei propri clienti, garantendo una esperienza di qualità senza compromessi."<br><br>3. "La nostra azienda si impegna a fornire soluzioni complete e integrate che rispondono alle esigenze uniche del proprio settore, con un impegno costante nella ricerca innovativa e nella migliorizzazione delle nostre offerte."</div>
</div>
</div>
</div>
<!-- Validazione Indirizzi -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📍 Parsing Indirizzo</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Indirizzo completo (testo libero)</label>
<textarea id="addressText" rows="2" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Via Roma 123, interno 4B, 20100 Milano MI, Italia</textarea>
<button onclick="parseAddress()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
📍 Estrai Componenti
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Indirizzo strutturato</label>
<div id="addressResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300"><pre>{
"via": "Via Roma",
"numero_civico": "123",
"interno": "4B",
"cap": "20100",
"citta": "Milano",
"provincia": "MI",
"nazione": "Italia"
}</pre></div>
</div>
</div>
</div>
<!-- Form Validation Suggestions -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">✅ Suggerimenti Correzione Form</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Nome</label>
<input type="text" id="formName" value="mario rossi" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<label class="block text-sm text-gray-400 mb-2">Email</label>
<input type="text" id="formEmail" value="mario.rossi@gmial.com" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<label class="block text-sm text-gray-400 mb-2">Telefono</label>
<input type="text" id="formPhone" value="3331234567" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="validateForm()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
✅ Analizza e Suggerisci
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Suggerimenti</label>
<div id="formResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300"><pre>{
"nome": {
"valore_corretto": "Mario Rossi",
"suggerimento": "Scritto con la maiuscola al primo carattere"
},
"email": {
"valore_corretto": "mario.rossi@gmail.com",
"suggerimento": "Completa il dominio e assicurati che sia corretto"
},
"telefono": {
"valore_corretto": "",
"suggerimento": "Controlla la lunghezza del numero di telefono"
},
"errori_trovati": [
"Nome non scritto con la maiuscola al primo carattere",
"Indirizzo email incompleto"
]
}</pre></div>
</div>
</div>
</div>
</div>
<!-- ==================== SOCIAL ==================== -->
<div id="tab-social" class="tab-content space-y-6 hidden">
<h2 class="text-2xl font-bold text-purple-400">📱 Social Media</h2>
<!-- Post Generator -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">📸 Generatore Post Social</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Argomento/Prodotto</label>
<input type="text" id="socialTopic" value="Lancio nuova collezione primavera" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<label class="block text-sm text-gray-400 mb-2">Piattaforma</label>
<select id="socialPlatform" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="instagram">Instagram</option>
<option value="facebook">Facebook</option>
<option value="linkedin">LinkedIn</option>
<option value="twitter">Twitter/X</option>
<option value="tiktok">TikTok</option>
</select>
<label class="block text-sm text-gray-400 mb-2">Tono</label>
<select id="socialTone" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<option value="entusiasta">Entusiasta</option>
<option value="professionale">Professionale</option>
<option value="casual">Casual/Amichevole</option>
<option value="urgente">Urgente/FOMO</option>
</select>
<button onclick="generateSocialPost()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
📸 Genera Post
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Post generato</label>
<div id="socialResult" class="bg-gray-900 rounded-lg p-4 min-h-[200px] text-gray-300">
Clicca "Genera Post" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Hashtag Generator -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">#️⃣ Generatore Hashtag</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Descrizione contenuto</label>
<textarea id="hashtagContent" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Foto di tramonto sulla spiaggia in Sardegna, vacanze estive, relax</textarea>
<label class="block text-sm text-gray-400 mb-2">Numero hashtag</label>
<input type="number" id="hashtagCount" value="15" min="5" max="30" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="generateHashtags()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
#️⃣ Genera Hashtag
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Hashtag suggeriti</label>
<div id="hashtagResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Genera Hashtag" per vedere il risultato...
</div>
</div>
</div>
</div>
<!-- Comment Responder -->
<div class="bg-gray-800 rounded-xl p-6">
<h3 class="text-xl font-semibold mb-4">💬 Rispondi ai Commenti</h3>
<div class="grid md:grid-cols-2 gap-4">
<div>
<label class="block text-sm text-gray-400 mb-2">Commento ricevuto</label>
<textarea id="commentText" rows="3" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">Bellissimo prodotto! Quanto costa la spedizione in Sicilia? E i tempi di consegna?</textarea>
<label class="block text-sm text-gray-400 mb-2">Info da includere (opzionale)</label>
<input type="text" id="commentInfo" value="Spedizione gratuita sopra 50€, consegna 3-5 giorni" class="w-full bg-gray-700 rounded-lg px-3 py-2 mb-3">
<button onclick="respondComment()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg w-full">
💬 Genera Risposta
</button>
</div>
<div>
<label class="block text-sm text-gray-400 mb-2">Risposta suggerita</label>
<div id="commentResult" class="bg-gray-900 rounded-lg p-4 min-h-[150px] text-gray-300">
Clicca "Genera Risposta" per vedere il risultato...
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// ============================================
// UTILITY FUNCTIONS
// ============================================
function getApiUrl() {
return document.getElementById('apiUrl').value;
}
function getModel() {
return document.getElementById('model').value;
}
function showLoading(elementId) {
document.getElementById(elementId).innerHTML = '<div class="loader"></div> Elaborazione in corso...';
}
function showResult(elementId, content, isJson = false) {
if (isJson) {
document.getElementById(elementId).innerHTML = `<pre>${JSON.stringify(content, null, 2)}</pre>`;
} else {
document.getElementById(elementId).innerHTML = content.replace(/\n/g, '<br>');
}
}
function showError(elementId, error) {
document.getElementById(elementId).innerHTML = `<span class="text-red-400">❌ Errore: ${error}</span>`;
}
async function apiCall(endpoint, body) {
const response = await fetch(`${getApiUrl()}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model: getModel(), ...body })
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
// ============================================
// TAB MANAGEMENT
// ============================================
function showTab(tabName) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('tab-active'));
document.getElementById(`tab-${tabName}`).classList.remove('hidden');
document.querySelector(`[data-tab="${tabName}"]`).classList.add('tab-active');
}
// ============================================
// CONNECTION TEST
// ============================================
async function testConnection() {
const status = document.getElementById('connectionStatus');
status.innerHTML = '<div class="loader"></div> Test in corso...';
try {
const response = await fetch(`${getApiUrl()}/health`);
const data = await response.json();
if (data.status === 'ok') {
status.innerHTML = '<span class="text-green-400">✅ Connesso! Ollama funzionante.</span>';
} else {
status.innerHTML = '<span class="text-yellow-400">⚠️ API raggiungibile ma Ollama non connesso</span>';
}
} catch (error) {
status.innerHTML = `<span class="text-red-400">❌ Errore connessione: ${error.message}</span>`;
}
}
// ============================================
// E-COMMERCE FUNCTIONS
// ============================================
async function generateProductDesc() {
showLoading('productResult');
try {
const name = document.getElementById('productName').value;
const features = document.getElementById('productFeatures').value;
const style = document.getElementById('productStyle').value;
const data = await apiCall('/generate', {
prompt: `Scrivi una descrizione ${style} per questo prodotto:
Nome: ${name}
Caratteristiche: ${features}
Scrivi SOLO la descrizione, senza titoli o introduzioni.`,
temperature: 0.7
});
showResult('productResult', data.response);
} catch (error) {
showError('productResult', error.message);
}
}
async function analyzeReview() {
showLoading('reviewResult');
try {
const review = document.getElementById('reviewText').value;
const data = await apiCall('/generate', {
prompt: `Analizza questa recensione e rispondi in JSON:
"${review}"
Formato risposta:
{
"sentiment": "positivo/negativo/misto",
"voto_stimato": "1-5",
"punti_positivi": ["..."],
"punti_negativi": ["..."],
"suggerimento_azione": "..."
}`,
temperature: 0.2
});
try {
const json = JSON.parse(data.response.match(/\{[\s\S]*\}/)[0]);
showResult('reviewResult', json, true);
} catch {
showResult('reviewResult', data.response);
}
} catch (error) {
showError('reviewResult', error.message);
}
}
async function generateReviewReply() {
showLoading('replyResult');
try {
const review = document.getElementById('reviewForReply').value;
const company = document.getElementById('companyName').value;
const data = await apiCall('/generate', {
prompt: `Sei il customer service di "${company}". Scrivi una risposta professionale e empatica a questa recensione negativa:
"${review}"
La risposta deve:
- Ringraziare per il feedback
- Scusarsi per l'inconveniente
- Proporre una soluzione
- Essere breve ma completa`,
temperature: 0.6
});
showResult('replyResult', data.response);
} catch (error) {
showError('replyResult', error.message);
}
}
async function categorizeProduct() {
showLoading('categoryResult');
try {
const product = document.getElementById('productToCategory').value;
const categories = document.getElementById('categories').value;
const data = await apiCall('/classify', {
text: product,
categories: categories.split(',').map(c => c.trim())
});
showResult('categoryResult', data, true);
} catch (error) {
showError('categoryResult', error.message);
}
}
// ============================================
// CONTENT FUNCTIONS
// ============================================
async function generateBlogIdeas() {
showLoading('blogIdeasResult');
try {
const topic = document.getElementById('blogTopic').value;
const count = document.getElementById('blogIdeasCount').value;
const data = await apiCall('/generate', {
prompt: `Genera ${count} idee per articoli di blog sul tema "${topic}".
Per ogni idea includi:
- Titolo accattivante
- Breve descrizione (1 riga)
Formato lista numerata.`,
temperature: 0.8
});
showResult('blogIdeasResult', data.response);
} catch (error) {
showError('blogIdeasResult', error.message);
}
}
async function generateEmail() {
showLoading('emailResult');
try {
const type = document.getElementById('emailType').value;
const context = document.getElementById('emailContext').value;
const tone = document.getElementById('emailTone').value;
const typeMap = {
followup: 'follow-up',
proposta: 'proposta commerciale',
ringraziamento: 'ringraziamento',
sollecito: 'sollecito pagamento',
scuse: 'scuse per disservizio'
};
const data = await apiCall('/generate', {
prompt: `Scrivi un'email di ${typeMap[type]} con tono ${tone}.
Contesto: ${context}
Includi oggetto e corpo email. Firma come "Il Team"`,
temperature: 0.6
});
showResult('emailResult', data.response);
} catch (error) {
showError('emailResult', error.message);
}
}
async function rewriteText() {
showLoading('rewriteResult');
try {
const text = document.getElementById('textToRewrite').value;
const goal = document.getElementById('rewriteGoal').value;
const goalMap = {
professionale: 'più professionale e curato',
persuasivo: 'più persuasivo e convincente',
semplice: 'più semplice e chiaro',
formale: 'più formale e istituzionale',
coinvolgente: 'più coinvolgente ed emozionale'
};
const data = await apiCall('/generate', {
prompt: `Riscrivi questo testo rendendolo ${goalMap[goal]}:
"${text}"
Rispondi solo con il testo riscritto.`,
temperature: 0.6
});
showResult('rewriteResult', data.response);
} catch (error) {
showError('rewriteResult', error.message);
}
}
async function generateSEO() {
showLoading('seoResult');
try {
const content = document.getElementById('pageContent').value;
const keyword = document.getElementById('mainKeyword').value;
const data = await apiCall('/generate', {
prompt: `Genera meta tags SEO per questa pagina:
Contenuto: ${content}
Keyword principale: ${keyword}
Rispondi in JSON:
{
"title": "max 60 caratteri, include keyword",
"description": "max 160 caratteri, persuasiva",
"keywords": ["keyword1", "keyword2", ...]
}`,
temperature: 0.4
});
try {
const json = JSON.parse(data.response.match(/\{[\s\S]*\}/)[0]);
showResult('seoResult', json, true);
} catch {
showResult('seoResult', data.response);
}
} catch (error) {
showError('seoResult', error.message);
}
}
// ============================================
// SUPPORT FUNCTIONS
// ============================================
async function generateFAQ() {
showLoading('faqResult');
try {
const context = document.getElementById('faqContext').value;
const count = document.getElementById('faqCount').value;
const data = await apiCall('/generate', {
prompt: `Genera ${count} FAQ per questo servizio/prodotto:
${context}
Formato:
**D: [domanda]**
R: [risposta concisa]
---`,
temperature: 0.6
});
showResult('faqResult', data.response);
} catch (error) {
showError('faqResult', error.message);
}
}
async function classifyTicket() {
showLoading('ticketResult');
try {
const message = document.getElementById('ticketMessage').value;
const data = await apiCall('/generate', {
prompt: `Analizza questo ticket di supporto:
"${message}"
Rispondi in JSON:
{
"categoria": "spedizione/prodotto/pagamento/account/altro",
"urgenza": "alta/media/bassa",
"sentiment_cliente": "arrabbiato/frustrato/neutro/paziente",
"richiesta_principale": "breve descrizione",
"azioni_suggerite": ["azione1", "azione2"],
"risposta_template": "suggerimento risposta breve"
}`,
temperature: 0.2
});
try {
const json = JSON.parse(data.response.match(/\{[\s\S]*\}/)[0]);
showResult('ticketResult', json, true);
} catch {
showResult('ticketResult', data.response);
}
} catch (error) {
showError('ticketResult', error.message);
}
}
async function suggestResponse() {
showLoading('supportResult');
try {
const question = document.getElementById('supportQuestion').value;
const policy = document.getElementById('companyPolicy').value;
const data = await apiCall('/generate', {
prompt: `Sei un operatore supporto clienti. Rispondi a questa domanda:
"${question}"
${policy ? `Informazioni utili: ${policy}` : ''}
Scrivi una risposta cortese, chiara e professionale.`,
temperature: 0.5
});
showResult('supportResult', data.response);
} catch (error) {
showError('supportResult', error.message);
}
}
// ============================================
// DATA FUNCTIONS
// ============================================
async function extractData() {
showLoading('extractResult');
try {
const text = document.getElementById('extractText').value;
const schema = document.getElementById('extractSchema').value;
const data = await apiCall('/extract', {
text: text,
schema: JSON.parse(schema)
});
showResult('extractResult', data, true);
} catch (error) {
showError('extractResult', error.message);
}
}
async function batchSentiment() {
showLoading('sentimentResult');
try {
const texts = document.getElementById('sentimentTexts').value.split('\n').filter(t => t.trim());
const results = [];
for (const text of texts) {
const data = await apiCall('/sentiment', { text });
results.push({ testo: text.substring(0, 50) + '...', ...data });
}
// Calcola statistiche
const stats = {
totale: results.length,
positivi: results.filter(r => r.sentiment === 'positive').length,
negativi: results.filter(r => r.sentiment === 'negative').length,
neutri: results.filter(r => r.sentiment === 'neutral').length
};
showResult('sentimentResult', { statistiche: stats, dettagli: results }, true);
} catch (error) {
showError('sentimentResult', error.message);
}
}
async function summarizeDocument() {
showLoading('summaryResult');
try {
const text = document.getElementById('documentText').value;
const format = document.getElementById('summaryFormat').value;
const data = await apiCall('/summarize', {
text: text,
style: format
});
showResult('summaryResult', data.summary);
} catch (error) {
showError('summaryResult', error.message);
}
}
// ============================================
// FORMS FUNCTIONS
// ============================================
async function autocomplete() {
showLoading('autocompleteResult');
try {
const text = document.getElementById('autocompleteText').value;
const context = document.getElementById('autocompleteContext').value;
const data = await apiCall('/generate', {
prompt: `Completa questa frase in modo naturale e professionale:
"${text}"
${context ? `Contesto: ${context}` : ''}
Fornisci 3 possibili completamenti diversi, uno per riga.`,
temperature: 0.7
});
showResult('autocompleteResult', data.response);
} catch (error) {
showError('autocompleteResult', error.message);
}
}
async function parseAddress() {
showLoading('addressResult');
try {
const address = document.getElementById('addressText').value;
const data = await apiCall('/extract', {
text: address,
schema: {
via: "",
numero_civico: "",
interno: "",
cap: "",
citta: "",
provincia: "",
nazione: ""
}
});
showResult('addressResult', data, true);
} catch (error) {
showError('addressResult', error.message);
}
}
async function validateForm() {
showLoading('formResult');
try {
const name = document.getElementById('formName').value;
const email = document.getElementById('formEmail').value;
const phone = document.getElementById('formPhone').value;
const data = await apiCall('/generate', {
prompt: `Analizza questi dati form e suggerisci correzioni:
Nome: ${name}
Email: ${email}
Telefono: ${phone}
Rispondi in JSON:
{
"nome": { "valore_corretto": "", "suggerimento": "" },
"email": { "valore_corretto": "", "suggerimento": "" },
"telefono": { "valore_corretto": "", "suggerimento": "" },
"errori_trovati": ["..."]
}`,
temperature: 0.2
});
try {
const json = JSON.parse(data.response.match(/\{[\s\S]*\}/)[0]);
showResult('formResult', json, true);
} catch {
showResult('formResult', data.response);
}
} catch (error) {
showError('formResult', error.message);
}
}
// ============================================
// SOCIAL FUNCTIONS
// ============================================
async function generateSocialPost() {
showLoading('socialResult');
try {
const topic = document.getElementById('socialTopic').value;
const platform = document.getElementById('socialPlatform').value;
const tone = document.getElementById('socialTone').value;
const platformLimits = {
instagram: 'max 2200 caratteri, usa emoji, includi CTA',
facebook: 'può essere più lungo, coinvolgente',
linkedin: 'professionale, max 3000 caratteri',
twitter: 'max 280 caratteri, conciso',
tiktok: 'breve, trendy, usa emoji'
};
const data = await apiCall('/generate', {
prompt: `Scrivi un post ${platform} su: ${topic}
Tono: ${tone}
Linee guida: ${platformLimits[platform]}
Includi emoji appropriate e una call-to-action.`,
temperature: 0.8
});
showResult('socialResult', data.response);
} catch (error) {
showError('socialResult', error.message);
}
}
async function generateHashtags() {
showLoading('hashtagResult');
try {
const content = document.getElementById('hashtagContent').value;
const count = document.getElementById('hashtagCount').value;
const data = await apiCall('/generate', {
prompt: `Genera ${count} hashtag Instagram per questo contenuto:
"${content}"
Includi un mix di:
- Hashtag popolari (milioni di post)
- Hashtag medi (centinaia di migliaia)
- Hashtag di nicchia (decine di migliaia)
Scrivi solo gli hashtag, uno per riga, senza numeri o spiegazioni.`,
temperature: 0.7
});
// Formatta come hashtag cliccabili
const hashtags = data.response.split('\n')
.filter(h => h.trim())
.map(h => h.startsWith('#') ? h : '#' + h.trim().replace(/\s+/g, ''))
.join(' ');
showResult('hashtagResult', hashtags);
} catch (error) {
showError('hashtagResult', error.message);
}
}
async function respondComment() {
showLoading('commentResult');
try {
const comment = document.getElementById('commentText').value;
const info = document.getElementById('commentInfo').value;
const data = await apiCall('/generate', {
prompt: `Rispondi a questo commento social in modo amichevole e utile:
Commento: "${comment}"
${info ? `Info da includere: ${info}` : ''}
La risposta deve essere breve, cordiale e includere emoji. Massimo 2-3 frasi.`,
temperature: 0.7
});
showResult('commentResult', data.response);
} catch (error) {
showError('commentResult', error.message);
}
}
// Test connection on load
window.addEventListener('load', () => {
setTimeout(testConnection, 500);
});
</script>
</body></html>