Skip to content

Commit 7c362d4

Browse files
committed
Fixing most features
1 parent 0d2d896 commit 7c362d4

6 files changed

Lines changed: 44 additions & 29 deletions

File tree

model/design.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ def get_design_by_id(self, design_id: int):
2323

2424
def get_designs_by_id(self, user_id: int, page: int, page_size: int):
2525
cursor = self.conn.cursor()
26-
query = (
27-
"SELECT d.*, "
28-
"CASE WHEN q.scheduled THEN 1 ELSE 0 END AS is_scheduled, "
29-
"CASE WHEN q.queue_id IS NOT NULL THEN 1 ELSE 0 END AS is_in_queue "
30-
"FROM design d "
31-
"LEFT JOIN queue_item q ON d.design_id = q.design_id "
32-
"WHERE d.user_id = ? "
33-
"ORDER BY d.updated_at DESC "
34-
"LIMIT ? OFFSET ?;"
35-
)
26+
query = """
27+
SELECT d.*,
28+
CASE WHEN rq.design_id IS NOT NULL THEN 1 ELSE 0 END AS is_in_queue,
29+
CASE WHEN si.design_id IS NOT NULL THEN 1 ELSE 0 END AS is_scheduled
30+
FROM design d
31+
LEFT JOIN rotation_queue rq ON d.design_id = rq.design_id
32+
LEFT JOIN scheduled_items si ON d.design_id = si.design_id
33+
WHERE d.user_id = ?
34+
GROUP BY d.design_id
35+
ORDER BY d.updated_at DESC
36+
LIMIT ? OFFSET ?;
37+
"""
3638

3739
try:
3840
cursor.execute(query, (user_id, page_size, (page - 1) * page_size))

model/rotation_system.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def _get_connection(self):
1818
conn = sqlite3.connect(self.db_path)
1919
conn.row_factory = sqlite3.Row # Enable row factory for dict-like access
2020
conn.execute("PRAGMA foreign_keys = ON")
21+
conn.execute("PRAGMA busy_timeout = 5000;")
2122
return conn
2223

2324
def get_active_image(self) -> Optional[Dict]:
@@ -71,7 +72,7 @@ def add_unscheduled_image(self, design_id: int) -> int:
7172

7273
# Calculate expiry time (1 day from now)
7374
expiry_time = datetime.now() + timedelta(days=1)
74-
75+
7576
# Insert the new item
7677
cur.execute("""
7778
INSERT INTO rotation_queue
@@ -85,6 +86,11 @@ def add_unscheduled_image(self, design_id: int) -> int:
8586
# If this is the first item, make it active
8687
self._ensure_active_item(conn)
8788

89+
cur.execute(
90+
"INSERT INTO upload_history (design_id, attempt_time, status) VALUES (?, ?, ?);",
91+
(design_id, datetime.utcnow().isoformat(), 'successful')
92+
)
93+
8894
return item_id
8995

9096
finally:
@@ -178,7 +184,7 @@ def process_scheduled_images(self) -> bool:
178184
""", (active_item_id,))
179185
result = cur.fetchone()
180186
current_order = result['display_order'] if result else 0
181-
187+
182188
# Shift all items with display_order > current_order up by 1
183189
cur.execute("""
184190
UPDATE rotation_queue
@@ -205,6 +211,11 @@ def process_scheduled_images(self) -> bool:
205211
VALUES (?, ?, ?, ?)
206212
""", (item['design_id'], item['duration'], display_order, expiry_time))
207213

214+
cur.execute(
215+
"INSERT INTO upload_history (design_id, attempt_time, status) VALUES (?, ?, ?);",
216+
(item['design_id'], datetime.utcnow().isoformat(), 'successful')
217+
)
218+
208219
item_id = cur.lastrowid
209220

210221
# If override_current is true, make this the active item

model/upload_history.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ def __init__(self):
77
try:
88
self.conn = sqlite3.connect(database_path)
99
self.conn.execute("PRAGMA foreign_keys = ON")
10+
self.conn.execute("PRAGMA busy_timeout = 5000;")
1011
except sqlite3.Error as e:
1112
print(f"Database connection error: {e}")
1213
raise

view/src/components/Carousel.jsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,7 @@ const Carousel = ({ userRole }) => {
152152
src={item.imageUrl}
153153
alt={item.title || `Design ${item.design_id}`}
154154
className="placeholder-image"
155-
/>
156-
157-
{/* Conditional overlay for admin edit or regular view */}
158-
{isAdmin ? (
159-
<div className={`edit-overlay ${hoveredItem === item.id ? 'visible' : ''}`}>
160-
<span>Edit</span>
161-
</div>
162-
) : (
163-
<div className={`view-overlay ${hoveredItem === item.id ? 'visible' : ''}`} />
164-
)}
155+
/>
165156

166157
{/* Display duration information on hover */}
167158
<div className={`schedule-overlay ${hoveredItem === item.id ? 'visible' : ''}`}>

view/src/components/UserImages.jsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import './styles/UserImages.css';
44
import '../assets/fonts/PixelifySans/PixelifySans-VariableFont_wght.ttf';
55
import axios from '../api/axios';
66
import {renderPixelDataToImage} from '../utils/pixelRenderer';
7+
import { Navigate } from 'react-router-dom';
78

89
// modal component
910
import Modal from "../components/Modal";
@@ -38,6 +39,7 @@ async function deleteDesign(design_id) {
3839
function UserImages() {
3940
const [designs, setDesigns] = useState([]);
4041
const [selectedDesign, setSelectedDesign] = useState(null);
42+
const [redirectToEdit, setRedirectToEdit] = useState(null);
4143
const [showDeleteModal, setShowDeleteModal] = useState(false);
4244
const [showAlertModal, setShowAlertModal] = useState(false);
4345
const [AlertMessage, setAlertMessage] = useState(null);
@@ -75,11 +77,20 @@ function UserImages() {
7577
const handleEdit = () => {
7678
if (selectedDesign) {
7779
console.log("Edit design", selectedDesign.design_id);
78-
// TODO: Irsa: Go to edit view
79-
// Not putting anything here so you can mount the component your way
80+
setRedirectToEdit({
81+
design: {
82+
design_id: selectedDesign.design_id,
83+
title: selectedDesign.title,
84+
pixel_data: selectedDesign.pixel_data
85+
}
86+
});
8087
}
8188
};
8289

90+
if (redirectToEdit) {
91+
return <Navigate to="/edit" state={redirectToEdit} replace />;
92+
}
93+
8394
const handleDeleteClick = () => {
8495
if (selectedDesign) {
8596
setShowDeleteModal(true);
@@ -230,7 +241,7 @@ function UserImages() {
230241
>
231242
{selectedDesign.is_approved ? (
232243
<>
233-
{!selectedDesign.is_scheduled && (
244+
{(!selectedDesign.is_scheduled && !selectedDesign.is_in_queue) && (
234245
<button
235246
onClick={handleQueue}
236247
className="cursor-pointer w-full border font-bold text-black border-gray-300 bg-yellow-400 py-2 rounded-md text-md font-pixelify hover:bg-black hover:text-yellow-400 hover:shadow-md transition-all duration-200 ease-in-out"
@@ -240,7 +251,7 @@ function UserImages() {
240251
)}
241252

242253
<div className="flex flex-col sm:flex-row gap-4">
243-
<button
254+
{!selectedDesign.is_in_queue && (<button
244255
onClick={selectedDesign.is_scheduled ? handleQueue : handleEdit}
245256
className={`cursor-pointer flex-1 border font-bold text-black border-gray-300 py-2 rounded-md text-md font-pixelify hover:bg-black hover:shadow-md transition-all duration-200 ease-in-out ${
246257
selectedDesign.is_scheduled
@@ -249,7 +260,7 @@ function UserImages() {
249260
}`}
250261
>
251262
{selectedDesign.is_scheduled ? 'Edit Schedule' : 'Edit'}
252-
</button>
263+
</button>)}
253264

254265
<button
255266
onClick={handleDeleteClick}

view/src/pages/UserHome.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ function UserHome() {
6767
/>
6868
</div>
6969
</div>
70-
7170
{/* Show the upcoming images carousel */}
71+
</div>
7272
<Carousel userRole="user" />
7373
</div>
74-
</div>
7574
);
7675
} else {
7776
return (

0 commit comments

Comments
 (0)