-
Notifications
You must be signed in to change notification settings - Fork 324
Fix/issue 44 external apps filter #1424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -234,6 +234,13 @@ const STATUS_ORDER: Record<string, number> = { | |
| REJECTED: 4, | ||
| WITHDRAWN: 5, | ||
| }; | ||
| const EXTERNAL_STATUS = "APPLIED"; | ||
| const EXTERNAL_VISIBLE_FILTERS = ["ALL", "APPLIED", "IN_PROGRESS"] as const; | ||
| type ExternalVisibleFilter = (typeof EXTERNAL_VISIBLE_FILTERS)[number]; | ||
|
|
||
| function isExternalVisibleFilter(filter: string): filter is ExternalVisibleFilter { | ||
| return (EXTERNAL_VISIBLE_FILTERS as readonly string[]).includes(filter); | ||
| } | ||
|
|
||
| function sortApplications( | ||
| apps: Application[], | ||
|
|
@@ -259,6 +266,7 @@ export default function MyApplicationsPage() { | |
| const [page, setPage] = useState(1); | ||
| const [pendingDelete, setPendingDelete] = useState<PendingDelete | null>(null); | ||
| const [sortOption, setSortOption] = useState<"newest" | "oldest" | "company" | "status">("newest"); | ||
| const [activeFilter, setActiveFilter] = useState("ALL"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Search for filter UI implementation that might set activeFilter
# Search for setActiveFilter calls
rg -n 'setActiveFilter' --type=tsx --type=ts
# Search for potential filter button/tab patterns
rg -n -C3 'IN_PROGRESS|APPLIED|ALL.*filter|filter.*button' client/src/module/student/applications/ --type=tsx --type=tsRepository: Sachinchaurasiya360/InternHack Length of output: 130 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="client/src/module/student/applications/MyApplicationsPage.tsx"
echo "== Existence checks =="
ls -l "$FILE"
echo
echo "== Find activeFilter usage =="
rg -n "activeFilter" "$FILE"
echo
echo "== Find setActiveFilter usage in repo (scoped) =="
rg -n "setActiveFilter" client/src --glob='*.ts' --glob='*.tsx' || true
echo
echo "== Find IN_PROGRESS/APPLIED mentions in that module dir =="
rg -n "IN_PROGRESS|APPLIED" client/src/module/student/applications --glob='*.ts' --glob='*.tsx' || true
echo
echo "== Show filter/search-related UI area around line ~430-560 =="
# show manageable window
sed -n '420,560p' "$FILE" | nl -ba | sed -n '1,200p'Repository: Sachinchaurasiya360/InternHack Length of output: 1493 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="client/src/module/student/applications/MyApplicationsPage.tsx"
echo "== Existence checks =="
ls -l "$FILE"
echo
echo "== Find activeFilter usage =="
rg -n "activeFilter" "$FILE" || true
echo
echo "== Find setActiveFilter usage in repo (scoped) =="
rg -n "setActiveFilter" client/src --glob='*.ts' --glob='*.tsx' || true
echo
echo "== Find IN_PROGRESS/APPLIED mentions in that module dir =="
rg -n "IN_PROGRESS|APPLIED" client/src/module/student/applications --glob='*.ts' --glob='*.tsx' || true
echo
echo "== Show filter/search-related UI area around line ~430-560 =="
sed -n '420,560p' "$FILE" | nl -ba | sed -n '1,250p'Repository: Sachinchaurasiya360/InternHack Length of output: 1493 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="client/src/module/student/applications/MyApplicationsPage.tsx"
echo "== setActiveFilter call sites (anywhere) =="
rg -n "setActiveFilter" "$FILE" --glob='*.tsx' --glob='*.ts' || true
echo
echo "== Where EXTERNAL_VISIBLE_FILTERS is used =="
rg -n "EXTERNAL_VISIBLE_FILTERS|isExternalVisibleFilter" "$FILE" || true
echo
echo "== Show surrounding code for those constants/helpers =="
# print around first occurrence(s)
for line in $(rg -n "EXTERNAL_VISIBLE_FILTERS|isExternalVisibleFilter" "$FILE" | cut -d: -f1 | head -n 10); do
echo "--- around line $line ---"
sed -n "$((line-40)),$((line+60))p" "$FILE" | cat
done
echo
echo "== Look for UI event handlers referencing activeFilter =="
rg -n "activeFilter|setActiveFilter|onClick|onChange|RadioGroup|Tabs|Select|Filter" "$FILE" --glob='*.tsx' | head -n 80 || true
echo
echo "== Print a likely UI region (420-620) without nl =="
sed -n '400,650p' "$FILE" | catRepository: Sachinchaurasiya360/InternHack Length of output: 30211 Critical: External application filter is unreachable ( In 🤖 Prompt for AI Agents |
||
|
|
||
| useEffect(() => { | ||
| const t = setTimeout(() => setDebouncedSearch(search), 200); | ||
|
|
@@ -268,7 +276,7 @@ export default function MyApplicationsPage() { | |
| useEffect(() => { | ||
| // eslint-disable-next-line react-hooks/set-state-in-effect | ||
| setPage(1); | ||
| }, [debouncedSearch]); | ||
| }, [debouncedSearch, activeFilter]); | ||
|
|
||
| const { data, isLoading } = useQuery({ | ||
| queryKey: queryKeys.applications.mine(), | ||
|
|
@@ -288,9 +296,10 @@ export default function MyApplicationsPage() { | |
| (a) => a.job?.title?.toLowerCase().includes(debouncedSearch.toLowerCase()) || a.job?.company?.toLowerCase().includes(debouncedSearch.toLowerCase()) | ||
| ); | ||
| return sortApplications(base, sortOption); | ||
| }, [applications, debouncedSearch, sortOption]); | ||
| }, [applications, debouncedSearch, sortOption, activeFilter]); | ||
|
|
||
| const filteredExternal = useMemo(() => { | ||
| if (!isExternalVisibleFilter(activeFilter)) return []; | ||
| const base = !debouncedSearch.trim() | ||
| ? externalApplications | ||
| : externalApplications.filter( | ||
|
|
@@ -304,7 +313,7 @@ export default function MyApplicationsPage() { | |
| if (sortOption === "company") return (a.adminJob.company ?? "").localeCompare(b.adminJob.company ?? ""); | ||
| return 0; | ||
| }); | ||
| }, [externalApplications, debouncedSearch, sortOption]); | ||
| }, [externalApplications, debouncedSearch, sortOption, activeFilter]); | ||
|
|
||
| const totalAll = applications.length + externalApplications.length; | ||
| const totalFiltered = filtered.length + filteredExternal.length; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -123,8 +123,27 @@ export default function FirstPRRoadmapPage() { | |||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||
| <Trophy className="w-8 h-8 text-green-500 shrink-0" /> | ||||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||||
| <p className="text-base font-bold text-green-900 dark:text-green-300">You're an open source contributor!</p> | ||||||||||||||||||||||||||||||||||
| <p className="text-sm text-green-700 dark:text-green-400 mt-0.5">You've completed all {totalSteps} steps. Time to find your next issue!</p> | ||||||||||||||||||||||||||||||||||
| <p className="text-base font-bold text-green-900 dark:text-green-300">You shipped your first PR!</p> | ||||||||||||||||||||||||||||||||||
| <p className="text-sm text-green-700 dark:text-green-400 mt-0.5">10 / 10 steps complete. Your open source journey has begun.</p> | ||||||||||||||||||||||||||||||||||
| <div className="flex gap-4 mt-3 flex-wrap items-center"> | ||||||||||||||||||||||||||||||||||
| <Link | ||||||||||||||||||||||||||||||||||
| to="/student/opensource" | ||||||||||||||||||||||||||||||||||
| className="text-sm text-lime-700 dark:text-lime-400 underline font-medium" | ||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||
| Discover repos to contribute to | ||||||||||||||||||||||||||||||||||
| </Link> | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+129
to
+134
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Use Button component with asChild for navigation links. This new navigation link should use the reusable ♻️ Refactor to use Button with asChild- <Link
- to="/student/opensource"
- className="text-sm text-lime-700 dark:text-lime-400 underline font-medium"
- >
- Discover repos to contribute to
- </Link>
+ <Button
+ variant="ghost"
+ mode="link"
+ size="sm"
+ asChild
+ >
+ <Link to="/student/opensource">
+ Discover repos to contribute to
+ </Link>
+ </Button>As per coding guidelines, use the reusable 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| <Button | ||||||||||||||||||||||||||||||||||
| onClick={() => { | ||||||||||||||||||||||||||||||||||
| if (window.confirm("Reset all steps?")) { | ||||||||||||||||||||||||||||||||||
| setCompleted(new Set()); | ||||||||||||||||||||||||||||||||||
| try { localStorage.removeItem(STORAGE_KEY); } catch { /**/ } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||
| className="text-sm text-lime-700 dark:text-lime-400 border border-lime-400 px-3 py-0.5 rounded-lg font-medium" | ||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||
| Start over | ||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+135
to
+145
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Use Button variant/mode/size props instead of custom className. The Button component should use its built-in ♻️ Refactor to use proper Button props <Button
+ variant="secondary"
+ size="sm"
onClick={() => {
if (window.confirm("Reset all steps?")) {
setCompleted(new Set());
try { localStorage.removeItem(STORAGE_KEY); } catch { /**/ }
}
}}
- className="text-sm text-lime-700 dark:text-lime-400 border border-lime-400 px-3 py-0.5 rounded-lg font-medium"
>
Start over
</Button>As per coding guidelines, the Button component supports variants (primary, secondary, mono, ghost, danger), modes (button, icon, link), and sizes (sm, md, lg) that should be used instead of custom className styling. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||
| </motion.div> | ||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -387,6 +387,29 @@ export default function OpenSourceAnalyticsPage() { | |||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Empty state: student has zero contributions | ||||||||||||||||||||||||
| if (!trendIsLoading && !trendIsError && contributionTotal === 0) { | ||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||
| <div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center px-4 text-center"> | ||||||||||||||||||||||||
| <div className="bg-indigo-50 rounded-full p-6 mb-5"> | ||||||||||||||||||||||||
| <BarChart3 className="w-12 h-12 text-indigo-400" /> | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| <h2 className="text-2xl font-bold text-gray-900 mb-3"> | ||||||||||||||||||||||||
| No contributions tracked yet | ||||||||||||||||||||||||
| </h2> | ||||||||||||||||||||||||
| <p className="text-gray-500 max-w-md mb-8"> | ||||||||||||||||||||||||
| Submit a repo suggestion and get it approved to start tracking | ||||||||||||||||||||||||
| your open source journey. | ||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||
| <Link | ||||||||||||||||||||||||
| to="/student/opensource" | ||||||||||||||||||||||||
| className="bg-indigo-600 text-white px-6 py-3 rounded-xl font-medium hover:bg-indigo-700 transition-colors" | ||||||||||||||||||||||||
| > | ||||||||||||||||||||||||
| Discover Repositories → | ||||||||||||||||||||||||
| </Link> | ||||||||||||||||||||||||
|
Comment on lines
+404
to
+409
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Use the shared The Link duplicates Button styling with inline classes. As per coding guidelines, use the reusable ♻️ Refactor to use Button with asChild- <Link
- to="/student/opensource"
- className="bg-indigo-600 text-white px-6 py-3 rounded-xl font-medium hover:bg-indigo-700 transition-colors"
- >
- Discover Repositories →
- </Link>
+ <Button variant="primary" size="lg" asChild>
+ <Link to="/student/opensource">
+ Discover Repositories →
+ </Link>
+ </Button>As per coding guidelines: "Use the reusable 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||
| <div className="min-h-screen bg-gray-50 pb-16"> | ||||||||||||||||||||||||
| {/* Header */} | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused constant or clarify its purpose.
EXTERNAL_STATUSis defined but never referenced. If external applications should always map to an "APPLIED" status for filtering purposes, this logic is missing. Otherwise, remove the dead code.🧹 Proposed fix to remove unused constant
-const EXTERNAL_STATUS = "APPLIED"; const EXTERNAL_VISIBLE_FILTERS = ["ALL", "APPLIED", "IN_PROGRESS"] as const;📝 Committable suggestion
🤖 Prompt for AI Agents