AlessandroArgiolas02 commited on
Commit
d558678
·
verified ·
1 Parent(s): e140e61

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -34
app.py CHANGED
@@ -8,14 +8,162 @@ genai.configure(api_key=GEMINI_KEY)
8
  model = genai.GenerativeModel('gemini-pro')
9
 
10
  CSS = """
11
- body { background: #f5f7fa; font-family: 'Arial', sans-serif; }
12
- .chat-container { max-width: 800px; margin: 0 auto; }
13
- .msg-user { background: #e3f2fd; padding: 15px; border-radius: 15px; margin: 10px; max-width: 70%; float: right; }
14
- .msg-bot { background: white; padding: 15px; border-radius: 15px; margin: 10px; max-width: 70%; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
15
- .card { border-left: 4px solid #2196F3; padding: 10px; margin: 10px 0; }
16
- .price { color: #2e7d32; font-weight: bold; }
17
- .link { color: #1565C0; text-decoration: underline; }
18
- .reset-btn { margin-top: 20px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  """
20
 
21
  class ChatManager:
@@ -49,10 +197,12 @@ class ChatManager:
49
  for item in structured:
50
  html += f"""
51
  <div class='card'>
52
- <h3>{item.get('nome', '')}</h3>
53
- <p>{item.get('descrizione', '')}</p>
54
- <p class='price'>{item.get('prezzo', '')}</p>
55
- {f"<a href='{item['link']}' class='link' target='_blank'>Maggiori informazioni</a>" if 'link' in item else ''}
 
 
56
  </div>
57
  """
58
  return html if html else response
@@ -67,19 +217,19 @@ def respond(message, chat_history):
67
  chat_manager.context["city"] = city
68
 
69
  if not chat_manager.context["city"]:
70
- bot_response = "Per favore dimmi prima di quale città vuoi informazioni! 🌍"
71
  chat_history[-1] = (message, bot_response)
72
  return "", chat_history
73
 
74
  prompt = f"""
75
- Sei un esperto guida turistica per {chat_manager.context["city"]}.
76
- Rispondi in italiano strutturando ogni suggerimento con:
77
- - **Nome**: [nome luogo]
78
- - **Descrizione**: [breve descrizione 20-30 parole]
79
- - **Prezzo**: [se applicabile]
80
- - **Link**: [sito ufficiale se disponibile]
81
 
82
- Richiesta utente: {message}
83
  """
84
 
85
  try:
@@ -93,23 +243,45 @@ def respond(message, chat_history):
93
 
94
  def reset_context(chat_history):
95
  chat_manager.context = {"city": None}
96
- new_history = chat_history + [[None, "Contesto resettato. Di quale città vuoi parlare ora? 🌆"]]
97
  return new_history
98
 
99
  with gr.Blocks(css=CSS) as app:
100
- gr.Markdown("# 🗺️ Assistente Turistico Chat")
101
-
102
- chatbot = gr.Chatbot(
103
- label="Chat",
104
- elem_classes="chat-container",
105
- value=[[None, "Ciao! Dimmi di quale città vuoi informazioni 🌍"]]
106
- )
107
- msg = gr.Textbox(label="Scrivi il tuo messaggio...")
108
-
109
- with gr.Row():
110
- send_btn = gr.Button("Invia")
111
- reset_btn = gr.Button("Cambia Città", variant="secondary")
112
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  send_btn.click(
114
  respond,
115
  [msg, chatbot],
 
8
  model = genai.GenerativeModel('gemini-pro')
9
 
10
  CSS = """
11
+ :root {
12
+ --primary: #2A5C82;
13
+ --secondary: #5BA4E6;
14
+ --accent: #FF7F50;
15
+ --background: #F8F9FA;
16
+ --text: #2C3E50;
17
+ }
18
+
19
+ body {
20
+ background: var(--background);
21
+ font-family: 'Segoe UI', system-ui, sans-serif;
22
+ min-height: 100vh;
23
+ margin: 0;
24
+ padding: 20px;
25
+ }
26
+
27
+ .gradio-container {
28
+ max-width: 800px;
29
+ margin: 0 auto;
30
+ background: white;
31
+ border-radius: 20px;
32
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
33
+ overflow: hidden;
34
+ }
35
+
36
+ .header {
37
+ background: var(--primary);
38
+ padding: 40px 20px;
39
+ text-align: center;
40
+ color: white;
41
+ }
42
+
43
+ .header h1 {
44
+ margin: 0;
45
+ font-size: 2.2em;
46
+ font-weight: 700;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ gap: 10px;
51
+ }
52
+
53
+ .chat-container {
54
+ padding: 20px;
55
+ height: 60vh;
56
+ overflow-y: auto;
57
+ }
58
+
59
+ .msg-user {
60
+ background: var(--secondary);
61
+ color: white;
62
+ padding: 15px 20px;
63
+ border-radius: 15px 15px 0 15px;
64
+ margin: 10px 0 10px 30%;
65
+ position: relative;
66
+ animation: slideIn 0.3s ease;
67
+ }
68
+
69
+ .msg-bot {
70
+ background: white;
71
+ padding: 20px;
72
+ border-radius: 15px 15px 15px 0;
73
+ margin: 10px 30% 10px 0;
74
+ border: 1px solid #E0E0E0;
75
+ position: relative;
76
+ animation: fadeIn 0.5s ease;
77
+ }
78
+
79
+ .msg-bot::before {
80
+ content: "✈️";
81
+ position: absolute;
82
+ left: -35px;
83
+ top: 15px;
84
+ font-size: 1.5em;
85
+ }
86
+
87
+ .card {
88
+ background: white;
89
+ padding: 20px;
90
+ border-radius: 12px;
91
+ margin: 15px 0;
92
+ border-left: 4px solid var(--accent);
93
+ box-shadow: 0 3px 10px rgba(0,0,0,0.05);
94
+ transition: transform 0.2s;
95
+ }
96
+
97
+ .card:hover {
98
+ transform: translateY(-3px);
99
+ }
100
+
101
+ .price {
102
+ color: var(--primary);
103
+ font-weight: 600;
104
+ margin: 8px 0;
105
+ }
106
+
107
+ .link {
108
+ color: var(--secondary) !important;
109
+ text-decoration: none;
110
+ font-weight: 500;
111
+ display: inline-flex;
112
+ align-items: center;
113
+ gap: 5px;
114
+ }
115
+
116
+ .link:hover {
117
+ text-decoration: underline;
118
+ }
119
+
120
+ .controls {
121
+ padding: 20px;
122
+ background: #F8FAFD;
123
+ border-top: 1px solid #E0E0E0;
124
+ }
125
+
126
+ input[type="text"] {
127
+ border: 2px solid var(--secondary) !important;
128
+ border-radius: 12px !important;
129
+ padding: 15px !important;
130
+ font-size: 1em;
131
+ }
132
+
133
+ button {
134
+ background: var(--primary) !important;
135
+ color: white !important;
136
+ border: none !important;
137
+ padding: 12px 25px !important;
138
+ border-radius: 10px !important;
139
+ transition: all 0.2s !important;
140
+ }
141
+
142
+ button:hover {
143
+ transform: translateY(-2px);
144
+ box-shadow: 0 5px 15px rgba(42,92,130,0.2) !important;
145
+ }
146
+
147
+ @keyframes slideIn {
148
+ from { transform: translateX(20px); opacity: 0; }
149
+ to { transform: translateX(0); opacity: 1; }
150
+ }
151
+
152
+ @keyframes fadeIn {
153
+ from { opacity: 0; transform: translateY(10px); }
154
+ to { opacity: 1; transform: translateY(0); }
155
+ }
156
+
157
+ @media (max-width: 600px) {
158
+ .gradio-container {
159
+ border-radius: 0;
160
+ }
161
+
162
+ .msg-user, .msg-bot {
163
+ margin-left: 10%;
164
+ margin-right: 10%;
165
+ }
166
+ }
167
  """
168
 
169
  class ChatManager:
 
197
  for item in structured:
198
  html += f"""
199
  <div class='card'>
200
+ <h3 style="margin:0;color:var(--primary)">📍 {item.get('nome', '')}</h3>
201
+ <p style="margin:10px 0;color:var(--text)">{item.get('descrizione', '')}</p>
202
+ <div style="display:flex;gap:15px;align-items:center">
203
+ {f"<div class='price'>💰 {item.get('prezzo', '')}</div>" if item.get('prezzo') else ''}
204
+ {f"<a href='{item['link']}' class='link' target='_blank'><svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-external-link'><path d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'></path><polyline points='15 3 21 3 21 9'></polyline><line x1='10' y1='14' x2='21' y2='3'></line></svg> Maggiori info</a>" if 'link' in item else ''}
205
+ </div>
206
  </div>
207
  """
208
  return html if html else response
 
217
  chat_manager.context["city"] = city
218
 
219
  if not chat_manager.context["city"]:
220
+ bot_response = "🌍 Per favore dimmi prima di quale città vuoi informazioni!"
221
  chat_history[-1] = (message, bot_response)
222
  return "", chat_history
223
 
224
  prompt = f"""
225
+ Sei un assistente turistico esperto di {chat_manager.context["city"]}.
226
+ Fornisci informazioni strutturate in italiano con:
227
+ - Nome luogo
228
+ - Breve descrizione (max 30 parole)
229
+ - Prezzo (se applicabile)
230
+ - Link ufficiale (se disponibile)
231
 
232
+ Richiesta: {message}
233
  """
234
 
235
  try:
 
243
 
244
  def reset_context(chat_history):
245
  chat_manager.context = {"city": None}
246
+ new_history = chat_history + [[None, "🔄 Contesto resettato! Di quale città vuoi parlare ora?"]]
247
  return new_history
248
 
249
  with gr.Blocks(css=CSS) as app:
250
+ with gr.Column():
251
+ gr.HTML("""
252
+ <div class="header">
253
+ <h1>
254
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
255
+ <path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/>
256
+ <circle cx="12" cy="10" r="3"/>
257
+ </svg>
258
+ Travel Assistant AI
259
+ </h1>
260
+ <p>La tua guida personale per scoprire il mondo</p>
261
+ </div>
262
+ """)
263
+
264
+ chatbot = gr.Chatbot(
265
+ label="Chat",
266
+ elem_classes="chat-container",
267
+ show_label=False,
268
+ avatar_images=(
269
+ None,
270
+ "https://i.ibb.co/8XJp0dN/bot-avatar.png"
271
+ )
272
+ )
273
+
274
+ with gr.Row(elem_classes="controls"):
275
+ msg = gr.Textbox(
276
+ label="",
277
+ placeholder="Scrivi qui la tua richiesta...",
278
+ show_label=False,
279
+ container=False
280
+ )
281
+ with gr.Column(min_width=100):
282
+ send_btn = gr.Button("Invia ➔", variant="primary")
283
+ reset_btn = gr.Button("Nuova Ricerca", variant="secondary")
284
+
285
  send_btn.click(
286
  respond,
287
  [msg, chatbot],