From 1d427cf24b67a1653013928cf7fa4d88b1dd833d Mon Sep 17 00:00:00 2001 From: Divya-Sharma-CSE Date: Tue, 26 May 2026 00:26:30 +0530 Subject: [PATCH] enhancement:skeleton screen to saved timetables --- .env.example | 10 -- src/app/saved/saved-mobile.tsx | 45 +++++---- src/app/saved/saved.tsx | 114 ++++++++++++---------- src/components/ui/SavedMobileSkeleton.tsx | 54 ++++++++++ src/components/ui/SavedSkeleton.tsx | 103 +++++++++++++++++++ 5 files changed, 241 insertions(+), 85 deletions(-) delete mode 100644 .env.example create mode 100644 src/components/ui/SavedMobileSkeleton.tsx create mode 100644 src/components/ui/SavedSkeleton.tsx diff --git a/.env.example b/.env.example deleted file mode 100644 index 8380781..0000000 --- a/.env.example +++ /dev/null @@ -1,10 +0,0 @@ -BASE_URL = http://localhost:3000 - -GOOGLE_CLIENT_ID = -GOOGLE_CLIENT_SECRET = -GOOGLE_CLIENT_EMAIL = -GOOGLE_PRIVATE_KEY = -SHEET_ID = - -MONGODB_URI = (mongodb+srv://:/ffcs-user) -// keep ffcs-user as the database name diff --git a/src/app/saved/saved-mobile.tsx b/src/app/saved/saved-mobile.tsx index c7e40d2..1969da8 100644 --- a/src/app/saved/saved-mobile.tsx +++ b/src/app/saved/saved-mobile.tsx @@ -7,7 +7,7 @@ import Footer from '@/components/ui/Footer'; import Image from 'next/image'; import axios from 'axios'; import { PopupViewTT } from '@/components/ui/PopupMobile'; -import Loader from '@/components/ui/Loader'; +import SavedMobileSkeleton from '@/components/ui/SavedMobileSkeleton'; async function fetchTimetablesByOwner(owner: string) { const res = await axios.get(`/api/timetables?owner=${encodeURIComponent(owner)}`); @@ -115,32 +115,35 @@ export default function SavedMobile() {
Saved Timetables
-
    - {timetables.map((tt, index) => ( -
  • handleView(tt)} - > - {index + 1}. - {tt.title} -
  • - ))} -
+ {loading ? ( + + ) : ( +
    + {timetables.map((tt, index) => ( +
  • handleView(tt)} + > + {index + 1}. + {tt.title} +
  • + ))} +
+ )}
- {loading ? null : timetables.length === 0 ? ( - Nothing To Show Here - ) : ( - End of List - )} + {!loading && + (timetables.length === 0 ? ( + Nothing To Show Here + ) : ( + End of List + ))}
- {loading ? ( - - ) : timetables.length === 0 ? ( + {!loading && timetables.length === 0 ? (
No saved timetables found.
diff --git a/src/app/saved/saved.tsx b/src/app/saved/saved.tsx index c7f25e0..185c94f 100644 --- a/src/app/saved/saved.tsx +++ b/src/app/saved/saved.tsx @@ -11,6 +11,7 @@ import Image from 'next/image'; import AlertModal from '@/components/ui/AlertModal'; import axios from 'axios'; import Loader from '@/components/ui/Loader'; +import SavedSkeleton from '@/components/ui/SavedSkeleton'; async function fetchTimetablesByOwner(owner: string) { const res = await axios.get(`/api/timetables?owner=${encodeURIComponent(owner)}`); @@ -157,63 +158,68 @@ export default function Saved() {

Saved Timetables

-

All Timetables

- {loading ? ( - + /* ── skeleton replaces both the heading and the list while fetching ── */ + ) : timetables.length === 0 ? ( -
-

(No Timetables Found)

- router.push('/')} - type="large" - text="Home" - color="purple" - image="/icons/home.svg" - /> -
+ <> +

All Timetables

+
+

(No Timetables Found)

+ router.push('/')} + type="large" + text="Home" + color="purple" + image="/icons/home.svg" + /> +
+ ) : ( -
    - {timetables.map((tt, i) => ( -
  • - - {i + 1}. {tt.title} - -
    - openView(tt)} - /> - { - setSelectedTT(tt); - setRenameValue(tt.title); - setPopupType('rename_tt'); - setShowPopup(true); - }} - /> - { - setSelectedTT(tt); - setPopupType('delete_tt'); - setShowPopup(true); - }} - /> -
    -
  • - ))} -
+ <> +

All Timetables

+
    + {timetables.map((tt, i) => ( +
  • + + {i + 1}. {tt.title} + +
    + openView(tt)} + /> + { + setSelectedTT(tt); + setRenameValue(tt.title); + setPopupType('rename_tt'); + setShowPopup(true); + }} + /> + { + setSelectedTT(tt); + setPopupType('delete_tt'); + setShowPopup(true); + }} + /> +
    +
  • + ))} +
+ )}
diff --git a/src/components/ui/SavedMobileSkeleton.tsx b/src/components/ui/SavedMobileSkeleton.tsx new file mode 100644 index 0000000..0d8d82f --- /dev/null +++ b/src/components/ui/SavedMobileSkeleton.tsx @@ -0,0 +1,54 @@ +/** + * SavedMobileSkeleton.tsx + * Drop into: src/components/ui/SavedMobileSkeleton.tsx + * + * Usage in saved-mobile.tsx: + * Replace the entire
    + loading branches with: + * {loading ? :
      ...
    } + */ + +import React from 'react'; + +const SHIMMER_CSS = ` +@keyframes boneShimmer { + 0% { background-position: -200% 0; } + 100% { background-position: 200% 0; } +} +.bone-mobile { + background: linear-gradient( + 90deg, + #b8d9db 25%, + #d6ecee 50%, + #b8d9db 75% + ); + background-size: 200% 100%; + animation: boneShimmer 1.6s ease-in-out infinite; +} +`; + +function BoneRow({ delay }: { delay: string }) { + return ( +