diff --git a/src/app/saved/saved-mobile.tsx b/src/app/saved/saved-mobile.tsx index c7e40d2..d3ec096 100644 --- a/src/app/saved/saved-mobile.tsx +++ b/src/app/saved/saved-mobile.tsx @@ -8,6 +8,8 @@ import Image from 'next/image'; import axios from 'axios'; import { PopupViewTT } from '@/components/ui/PopupMobile'; import Loader from '@/components/ui/Loader'; +import Popup from '@/components/ui/Popup'; +import { ZButton } from '@/components/ui/Buttons'; async function fetchTimetablesByOwner(owner: string) { const res = await axios.get(`/api/timetables?owner=${encodeURIComponent(owner)}`); @@ -45,6 +47,9 @@ export default function SavedMobile() { const [popupTitle, setPopupTitle] = useState(''); const [selectedTT, setSelectedTT] = useState(null); const [publicToggle, setPublicToggle] = useState(true); + + // NEW: for rename support + const [renameValue, setRenameValue] = useState(''); useEffect(() => { if (!userEmail) return; @@ -72,11 +77,29 @@ export default function SavedMobile() { setShowPopup(true); } + // NEW: delete handler (mirrors saved.tsx) + async function handleDelete() { + if (!selectedTT) return; + await axios.delete(`/api/timetables/${selectedTT._id}`); + setTimetables(prev => prev.filter(t => t._id !== selectedTT._id)); + setShowPopup(false); + setSelectedTT(null); + } + + // NEW: rename handler (mirrors saved.tsx) + async function handleRename() { + if (!selectedTT) return; + await axios.patch(`/api/timetables/${selectedTT._id}`, { title: renameValue }); + setTimetables(prev => + prev.map(t => (t._id === selectedTT._id ? { ...t, title: renameValue } : t)) + ); + setShowPopup(false); + setSelectedTT(null); + } + async function handleCopyLink(tt: TimetableEntry) { try { - await axios.patch(`/api/timetables/${tt._id}`, { - isPublic: publicToggle, - }); + await axios.patch(`/api/timetables/${tt._id}`, { isPublic: publicToggle }); const res = await axios.get(`/api/timetables/${tt._id}`); const updated = res.data; if (!updated.shareId) throw new Error('No shareId found'); @@ -88,9 +111,7 @@ export default function SavedMobile() { async function handleTogglePublic(state: 'on' | 'off') { if (!selectedTT) return; setPublicToggle(state === 'on'); - await axios.patch(`/api/timetables/${selectedTT._id}`, { - isPublic: state === 'on', - }); + await axios.patch(`/api/timetables/${selectedTT._id}`, { isPublic: state === 'on' }); setTimetables(prev => prev.map(tt => (tt._id === selectedTT._id ? { ...tt, isPublic: state === 'on' } : tt)) ); @@ -98,6 +119,7 @@ export default function SavedMobile() { return (
+ {/* Background */}
-
Saved Timetables
- -
    - {timetables.map((tt, index) => ( -
  • handleView(tt)} - > - {index + 1}. - {tt.title} -
  • - ))} -
- -
-
- {loading ? null : timetables.length === 0 ? ( - Nothing To Show Here - ) : ( - End of List - )} -
-
+ {/* FIX: reduced mt-28 → mt-20 so title isn't pushed too far down on short phones */} +
Saved Timetables
+ {/* FIX: unified loading/empty/list rendering — no orphaned divider during load */} {loading ? ( - +
+ +
) : timetables.length === 0 ? ( -
- No saved timetables found. -
- Create and save from the desktop website. +
+

+ No saved timetables found. +
+ Create and save from the desktop website. +

- ) : null} + ) : ( + <> +
    + {timetables.map((tt, index) => ( +
  • + {/* Tapping the number or title opens the view popup */} + handleView(tt)} + > + {index + 1}. + + handleView(tt)} + > + {tt.title} + + + {/* NEW: action buttons for rename and delete on mobile */} +
    e.stopPropagation()}> + { + setSelectedTT(tt); + setRenameValue(tt.title); + setPopupType('rename_tt'); + setShowPopup(true); + }} + /> + { + setSelectedTT(tt); + setPopupType('delete_tt'); + setShowPopup(true); + }} + /> +
    +
  • + ))} +
+ + {/* Divider only shown when list is visible */} +
+
+ End of List +
+
+ + )}
+ {/* View popup — unchanged */} {showPopup && popupType === 'view_tt' && selectedTT && ( )} -
+ + {showPopup && popupType === 'delete_tt' && selectedTT && ( + setShowPopup(false)} + action={handleDelete} + /> + )} + + {showPopup && popupType === 'rename_tt' && selectedTT && ( + setShowPopup(false)} + action={handleRename} + onInputChange={setRenameValue} + /> + )} +
); } diff --git a/src/app/slots/slots.tsx b/src/app/slots/slots.tsx index 45c2196..7f58890 100644 --- a/src/app/slots/slots.tsx +++ b/src/app/slots/slots.tsx @@ -180,12 +180,7 @@ export default function View() {
- ({ - slotName: buttonTexts[i], - showName: true, - }))} - /> +