Skip to content

Commit 3873b74

Browse files
committed
fix(ui): revert layout to stable version
1 parent b3b6a27 commit 3873b74

File tree

2 files changed

+185
-138
lines changed

2 files changed

+185
-138
lines changed

README.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,16 @@
88
<p align="center">
99
<img src="docs/demo.png" alt="Demo screenshot" width="300">
1010
</p>
11-
1211
---
1312

1413
## ✨ Features
1514

1615
- **Local expertise** — tailored to Jyväskylä’s official sorting rules.
17-
- **Text _or_ photo** — type a question *or* upload an image of the item.
16+
- **Text *****or***** photo** — type a question *or* upload an image of the item.
1817
- **Bilingual UI** — instantly switch between **English** and **Finnish**.
1918
- **Smart image compression** — 500 × 500 JPEG (quality 75) → fewer OpenAI tokens & lower cost.
2019
- **GPT‑4o‑mini vision + chat** — one model for language *and* image reasoning.
2120
- **Serverless host** — runs on Google Cloud Run; scales to zero when idle.
22-
- **Responsive template** — single HTML/CSS file adapts fluidly from mobile to desktop.
23-
- **Automatic dark / light mode** — respects the user’s OS theme via `prefers‑color‑scheme`.
24-
- **Accessible UI controls** — keyboard‑friendly, logical focus order, proper contrast.
25-
- **Drag‑and‑drop & camera capture** — quick image selection on desktop and mobile.
2621

2722
---
2823

@@ -77,17 +72,6 @@ Open the URL, ask “Where do I throw plastic bags?” or upload a picture, and
7772

7873
---
7974

80-
## 🖼️ Front‑end template highlights
81-
82-
| Feature | Details |
83-
| ------- | ------- |
84-
| **Single‑page HTML** | No build step; pure HTML + Vanilla JS. |
85-
| **CSS Custom Properties** | Central palette makes theming easy. |
86-
| **Mobile‑first layout** | Flexible flexbox chat column with sticky input bar. |
87-
| **Styled scrollbars** | Subtle track / thumb colours match theme. |
88-
| **Markdown rendering** | Uses `marked.js` for rich responses. |
89-
| **Image preview & remove** | Thumbnail with one‑click _×_ delete before upload. |
90-
9175
## 🗂️ Code overview
9276

9377
- `` — Flask routes (`/``/ask``/reset`) + OpenAI calls.

templates/index.html

Lines changed: 184 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -6,138 +6,199 @@
66
<title>Waste Management Assistant</title>
77
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
88
<style>
9-
/* ─────────────────────── CSS variables ─────────────────────── */
10-
11-
:root {
12-
/* neutrals (light mode) */
13-
--bg-body: #f5f5f5;
14-
--bg-card: #ffffff;
15-
--bg-chat: #e0e0e0;
16-
--bg-user: #aae3c2;
17-
--bg-assistant: #F6F6F9;
18-
--bg-input: #ffffff;
19-
--border: #dddddd;
20-
--scroll-track: #f1f1f1;
21-
--scroll-thumb: #cccccc;
22-
23-
/* text / accent */
24-
--text-default: #202124;
25-
--text-inverse: #ffffff;
26-
--accent-pink: #EE125B;
27-
}
9+
html, body {
10+
height: 100%;
11+
margin: 0;
12+
font-family: Arial, sans-serif;
13+
background-color: #f5f5f5;
14+
overflow: hidden; /* Prevent overflow issues */
15+
}
2816

29-
/* ─────────────── automatic dark-mode palette ─────────────── */
30-
@media (prefers-color-scheme: dark) {
31-
:root {
32-
--bg-body: #18191b;
33-
--bg-card: #202124;
34-
--bg-chat: #26272a;
35-
--bg-user: #2d4b3a;
36-
--bg-assistant: #323438;
37-
--bg-input: #2b2c2f;
38-
--border: #3b3c3f;
39-
--scroll-track: #1e1f21;
40-
--scroll-thumb: #575a5d;
41-
42-
--text-default: #e8e8e8;
43-
--text-inverse: #e8e8e8;
44-
--accent-pink: #ff2e7a;
17+
.container {
18+
display: flex;
19+
flex-direction: column;
20+
height: 100vh; /* Full viewport height */
21+
width: 100%;
22+
max-width: 100vw;
23+
margin: 0;
24+
box-sizing: border-box;
25+
background-color: #ffffff;
26+
border-radius: 10px;
4527
}
46-
}
4728

48-
/* ───────────────── base / mobile styles ───────────────── */
29+
.chat-container {
30+
flex-grow: 1;
31+
overflow-y: auto;
32+
background-color: #e0e0e0;
33+
padding: 10px;
34+
box-sizing: border-box;
35+
margin-bottom: 70px; /* Add margin to account for input container height */
36+
}
4937

50-
html,body{
51-
height:100%;margin:0;
52-
font-family:Arial,sans-serif;color:var(--text-default);
53-
background:var(--bg-body);overflow:hidden;
54-
}
38+
.message {
39+
margin-bottom: 10px;
40+
padding: 10px 15px;
41+
background-color: white;
42+
border-radius: 10px;
43+
word-wrap: break-word;
44+
max-width: 80%;
45+
box-sizing: border-box;
46+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
47+
}
5548

56-
.container{
57-
display:flex;flex-direction:column;height:100vh;width:100%;
58-
max-width:100vw;margin:0;box-sizing:border-box;
59-
background:var(--bg-card);border-radius:10px;
60-
}
49+
.user-message {
50+
background-color: #aae3c2;
51+
align-self: flex-end;
52+
margin-left: auto;
53+
}
6154

62-
.chat-container{
63-
flex-grow:1;overflow-y:auto;background:var(--bg-chat);
64-
padding:10px;box-sizing:border-box;margin-bottom:70px;
65-
}
55+
.user-image {
56+
align-self: flex-end; /* Align the image to the right */
57+
margin-left: auto;
58+
max-width: 200px;
59+
border: 1px solid #ddd;
60+
border-radius: 10px;
61+
display: block;
62+
margin-top: 10px;
63+
margin-bottom: 10px;
64+
padding: 0; /* No padding */
65+
background-color: transparent; /* No background color */
66+
box-shadow: none; /* Remove any shadow */
67+
}
6668

67-
.message{
68-
margin-bottom:10px;padding:10px 15px;border-radius:10px;
69-
word-wrap:break-word;max-width:80%;box-sizing:border-box;
70-
box-shadow:0 1px 3px rgba(0,0,0,.1);color:var(--text-default);
71-
}
72-
.user-message {background:var(--bg-user); align-self:flex-end;margin-left:auto;}
73-
.assistant-message{background:var(--bg-assistant); align-self:flex-start;margin-right:auto;}
69+
.assistant-message {
70+
background-color: #F6F6F9;
71+
align-self: flex-start;
72+
margin-right: auto;
73+
}
7474

75-
.user-image{
76-
align-self:flex-end;margin-left:auto;max-width:200px;
77-
border:1px solid var(--border);border-radius:10px;display:block;
78-
margin:10px 0;background:transparent;box-shadow:none;
79-
}
75+
.input-container {
76+
display: flex;
77+
align-items: flex-end;
78+
padding: 10px;
79+
background-color: #f5f5f5;
80+
border-top: 1px solid #ddd;
81+
box-sizing: border-box;
82+
position: sticky; /* Change from fixed to sticky */
83+
bottom: 0;
84+
left: 0;
85+
right: 0;
86+
width: 100%; /* Full width */
87+
}
8088

81-
.input-container{
82-
display:flex;align-items:flex-end;padding:10px;
83-
background:var(--bg-input);border-top:1px solid var(--border);
84-
box-sizing:border-box;position:sticky;bottom:0;left:0;right:0;width:100%;
85-
}
89+
.textarea-container {
90+
flex-grow: 1;
91+
margin-left: 10px;
92+
display: flex;
93+
flex-direction: column;
94+
}
8695

87-
.textarea-container{flex-grow:1;margin-left:10px;display:flex;flex-direction:column;}
96+
textarea {
97+
width: 100%;
98+
padding: 10px 10px;
99+
font-size: 16px;
100+
line-height: 17px;
101+
border-radius: 15px;
102+
border: 1px solid #ddd;
103+
background-color: #fff;
104+
resize: none;
105+
height: 40px; /* Set initial height */
106+
max-height: 150px;
107+
overflow-y: auto;
108+
box-sizing: border-box;
109+
overflow: hidden; /* Prevent scrolling until necessary */
110+
}
88111

89-
textarea{
90-
width:100%;padding:10px;font-size:16px;line-height:17px;
91-
border-radius:15px;border:1px solid var(--border);
92-
background:var(--bg-card);color:var(--text-default);
93-
resize:none;height:40px;max-height:150px;overflow-y:auto;box-sizing:border-box;
94-
}
112+
#imageInput {
113+
display: none;
114+
}
95115

96-
#imageInput{display:none;}
116+
.icon-button, button#sendButton {
117+
margin-left: 10px;
118+
height: 40px;
119+
width: 40px;
120+
background-color: transparent;
121+
border: none;
122+
cursor: pointer;
123+
display: flex;
124+
justify-content: center;
125+
align-items: center;
126+
}
97127

98-
.icon-button,button#sendButton{
99-
margin-left:10px;height:40px;width:40px;background:transparent;border:none;
100-
cursor:pointer;display:flex;justify-content:center;align-items:center;
101-
}
102-
.icon-button i,button#sendButton i{font-size:30px;color:var(--accent-pink);}
103-
button#sendButton:disabled{cursor:not-allowed;}
128+
.icon-button i {
129+
font-size: 30px;
130+
color: #EE125B;
131+
}
104132

105-
.chat-container::-webkit-scrollbar {width:8px;}
106-
.chat-container::-webkit-scrollbar-thumb {background:var(--scroll-thumb);border-radius:5px;}
107-
.chat-container::-webkit-scrollbar-track {background:var(--scroll-track);}
133+
button#sendButton {
134+
/* margin-left: 5px; */
135+
height: 40px;
136+
width: 40px;
137+
background-color: transparent; /* Make the background transparent */
138+
color: white;
139+
border: none;
140+
cursor: pointer;
141+
display: flex;
142+
justify-content: center;
143+
align-items: center;
144+
}
108145

109-
.image-thumbnail{
110-
position:relative;width:50px;height:50px;border-radius:5px;overflow:visible;
111-
border:1px solid var(--border);flex-shrink:0;margin-right:10px;
112-
}
113-
.image-thumbnail img{width:100%;height:100%;object-fit:cover;}
114-
.remove-thumbnail{
115-
position:absolute;top:-10px;right:-10px;background:#272A2B;color:#fff;
116-
border-radius:50%;width:25px;height:25px;display:flex;justify-content:center;
117-
align-items:center;cursor:pointer;font-size:14px;
118-
}
146+
button#sendButton i {
147+
font-size: 30px; /* Adjust the size of the icon */
148+
color: #EE125B; /* Keep the same arrow color */
149+
}
119150

120-
/* ─────────────── desktop-only tweaks (≥ 768 px) ─────────────── */
121-
@media (min-width:768px){
122-
.container{
123-
max-width:900px;margin:0 auto;border:1px solid var(--border);
151+
button#sendButton:disabled {
152+
background-color: transparent; /* Ensure it's still transparent when disabled */
153+
cursor: not-allowed;
124154
}
125-
.chat-container{
126-
margin:20px;margin-bottom:90px;border-radius:12px;background:var(--bg-chat);
127-
box-shadow:0 2px 6px rgba(0,0,0,.06);
155+
156+
.chat-container::-webkit-scrollbar {
157+
width: 8px;
128158
}
129-
.message {max-width:60%;font-size:15px;}
130-
.user-image{max-width:250px;}
131159

132-
.input-container{
133-
position:static;width:auto;margin:0 20px 20px;
134-
border:1px solid var(--border);border-radius:12px;background:var(--bg-input);
160+
.chat-container::-webkit-scrollbar-thumb {
161+
background-color: #ccc;
162+
border-radius: 5px;
163+
}
164+
165+
.chat-container::-webkit-scrollbar-track {
166+
background-color: #f1f1f1;
167+
}
168+
169+
.image-thumbnail {
170+
position: relative;
171+
width: 50px;
172+
height: 50px;
173+
border-radius: 5px;
174+
overflow: visible;
175+
border: 1px solid #ddd;
176+
flex-shrink: 0;
177+
margin-right: 10px;
178+
}
179+
180+
.image-thumbnail img {
181+
width: 100%;
182+
height: 100%;
183+
object-fit: cover;
135184
}
136-
textarea{font-size:15px;padding:12px;}
137-
.icon-button i,#sendButton i{font-size:26px;}
138-
}
139-
</style>
140185

186+
.remove-thumbnail {
187+
position: absolute;
188+
top: -10px; /* Adjust the position higher */
189+
right: -10px; /* Adjust to the right */
190+
background-color: #272A2B;
191+
color: white;
192+
border-radius: 50%;
193+
width: 25px; /* Keep button size */
194+
height: 25px;
195+
display: flex;
196+
justify-content: center;
197+
align-items: center;
198+
cursor: pointer;
199+
font-size: 14px; /* Keep font size */
200+
}
201+
</style>
141202
</head>
142203
<body>
143204

@@ -322,25 +383,27 @@
322383

323384
function appendImage(imageSrc, isUser) {
324385
const chatDiv = document.getElementById('chat');
386+
const messageDiv = document.createElement('div');
325387

326-
// wrapper div gets the same alignment class as a text message
327-
const wrapper = document.createElement('div');
328-
wrapper.classList.add('message');
329-
wrapper.classList.add(isUser ? 'user-message' : 'assistant-message');
330-
331-
// actual <img>
332388
const img = document.createElement('img');
333389
img.src = imageSrc;
334390
img.style.maxWidth = '200px';
335391
img.style.borderRadius = '10px';
336392
img.style.display = 'block';
337393
img.style.marginTop = '10px';
394+
395+
if (isUser) {
396+
img.classList.add('user-image'); // Only apply the user-image class for user images
397+
} else {
398+
messageDiv.classList.add('assistant-message');
399+
}
338400

339-
wrapper.appendChild(img);
340-
chatDiv.appendChild(wrapper);
401+
img.onload = function() {
402+
scrollToMessage(messageDiv);
403+
};
341404

342-
// ensure the latest image scrolls into view
343-
scrollToMessage(wrapper);
405+
messageDiv.appendChild(img);
406+
chatDiv.appendChild(messageDiv);
344407
}
345408

346409
const translations = {

0 commit comments

Comments
 (0)