Skip to content

Commit f036001

Browse files
create issues
1 parent 2d06d83 commit f036001

41 files changed

Lines changed: 2217 additions & 1347 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/REPO_MAP.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ Each module: `<name>.routes.ts` → `<name>.controller.ts` → `<name>.service.t
9696
| `ats` | `/api/ats` | AI resume scoring, score history, cover letters, AI LaTeX chat, JD optimization, resume generation |
9797
| `latex` | `/api/latex` | Compile LaTeX to PDF (local pdflatex → online API fallback), supporting files |
9898
| `company` | `/api/companies` | Company directory, reviews, contacts, contributions |
99-
| `college` | `/api/colleges` | College discovery, search/filter, courses, placements, reviews, cutoffs |
10099
| `scraper` | `/api/scraped-jobs` | External job aggregation, cron-based scraping |
100+
101+
> **Note:** There is no `college` module. `seed-colleges.ts` loads AICTE data, but no CRUD module, routes, or client pages exist. College is only referenced as a string field on student profiles.
101102
| `admin` | `/api/admin` | Full platform management — users, jobs, companies, colleges, repos, DSA, aptitude, skill-tests, hackathons, blog, badges |
102103
| `upload` | `/api/upload` | S3 uploads with local fallback |
103104
| `newsletter` | `/api/newsletter` | Email subscription management |

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Thanks for your interest in contributing! InternHack is a full-stack career plat
44

55
This guide walks you through everything from setting up the project to submitting your first PR.
66

7+
> 💬 **Join our WhatsApp community:** [Contributors Group](https://chat.whatsapp.com/DeUn3AeowvAJedw60Mt1EN)
8+
>
9+
> Hop in to discuss ideas, ask for guidance on a PR, get unstuck, share what you're working on, or just get to know the other contributors. Whether you're picking up your first `good first issue` or shipping a major feature, it's the fastest way to get a response and meet the people building InternHack with you.
10+
711
---
812

913
## Table of Contents
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from "react";
2+
3+
interface CircularProgressProps {
4+
progress: number;
5+
size?: number;
6+
strokeWidth?: number;
7+
/** Tailwind class applied to the progress arc, e.g. "stroke-indigo-500". */
8+
progressClassName?: string;
9+
/** Tailwind class applied when progress === 100. Falls back to progressClassName. */
10+
completeClassName?: string;
11+
/** Tailwind class applied to the track (background) circle. */
12+
trackClassName?: string;
13+
/** Tailwind class applied to the % label. */
14+
labelClassName?: string;
15+
}
16+
17+
/**
18+
* Shared circular progress ring. Clamps progress to [0, 100] so callers can
19+
* pass raw ratios without worrying about overflow.
20+
*/
21+
export const CircularProgress = React.memo(function CircularProgress({
22+
progress,
23+
size = 52,
24+
strokeWidth = 4,
25+
progressClassName = "stroke-indigo-500",
26+
completeClassName = "stroke-emerald-500",
27+
trackClassName = "stroke-gray-100 dark:stroke-gray-800",
28+
labelClassName = "text-xs font-bold text-gray-700 dark:text-gray-300",
29+
}: CircularProgressProps) {
30+
const clamped = Math.min(100, Math.max(0, progress));
31+
const r = (size - strokeWidth - 2) / 2;
32+
const circ = 2 * Math.PI * r;
33+
const offset = circ - (clamped / 100) * circ;
34+
const arcClass = clamped === 100 ? completeClassName : progressClassName;
35+
36+
return (
37+
<div className="relative shrink-0" style={{ width: size, height: size }} aria-hidden>
38+
<svg className="-rotate-90" width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
39+
<circle cx={size / 2} cy={size / 2} r={r} fill="none" className={trackClassName} strokeWidth={strokeWidth} />
40+
<circle
41+
cx={size / 2}
42+
cy={size / 2}
43+
r={r}
44+
fill="none"
45+
className={arcClass}
46+
strokeWidth={strokeWidth}
47+
strokeLinecap="round"
48+
strokeDasharray={`${circ}`}
49+
strokeDashoffset={offset}
50+
style={{ transition: "stroke-dashoffset 0.6s ease" }}
51+
/>
52+
</svg>
53+
<span className={`absolute inset-0 flex items-center justify-center ${labelClassName}`}>
54+
{Math.round(clamped)}%
55+
</span>
56+
</div>
57+
);
58+
});

client/src/components/ui/form.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Shared form styling tokens. Previously duplicated across ATS and Open
2+
// Source forms (and inlined inside RepoDiscoveryPage). Centralising here
3+
// keeps focus ring + border + dark mode styles consistent across modules.
4+
5+
type AccentColor = "violet" | "purple";
6+
7+
const ACCENT_FOCUS: Record<AccentColor, string> = {
8+
violet: "focus:ring-violet-500/20 focus:border-violet-400",
9+
purple: "focus:ring-purple-500/20 focus:border-purple-300",
10+
};
11+
12+
/**
13+
* Returns the Tailwind class string for a form <input>/<textarea>/<select>.
14+
* Pass the module's accent so ATS (violet) and Open Source (purple) stay
15+
* visually distinct without maintaining two separate constants.
16+
*/
17+
export function getInputCls(accent: AccentColor = "violet"): string {
18+
return [
19+
"w-full px-3.5 py-2.5 text-sm",
20+
"border border-gray-200 dark:border-gray-700 rounded-xl",
21+
"bg-gray-50/50 dark:bg-gray-800/50",
22+
"text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500",
23+
"focus:outline-none focus:ring-2 transition-all",
24+
ACCENT_FOCUS[accent],
25+
].join(" ");
26+
}
27+
28+
export const labelCls = "block text-xs font-medium text-gray-500 dark:text-gray-500 mb-1";

client/src/lib/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@ export interface Pagination {
181181
totalPages: number;
182182
}
183183

184+
export interface ExternalJob {
185+
id: number;
186+
slug: string | null;
187+
company: string | null;
188+
role: string | null;
189+
description: string | null;
190+
salary: string | null;
191+
currency: string | null;
192+
location: string | null;
193+
applyLink: string | null;
194+
tags: string[];
195+
expiresAt?: string;
196+
createdAt?: string;
197+
}
198+
184199
// Scraped Jobs
185200
export type ScrapedJobStatus = "ACTIVE" | "EXPIRED" | "REMOVED";
186201

0 commit comments

Comments
 (0)