@ansiversa/components 0.0.118 → 0.0.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +6 -3
- package/package.json +8 -4
- package/src/AvAccordion.astro +0 -1
- package/src/Summary/FlashNoteSummary.astro +69 -0
- package/src/Summary/PortfolioCreatorSummary.astro +71 -0
- package/src/Summary/ResumeBuilderSummary.astro +70 -0
- package/src/Summary/types.ts +36 -0
- package/src/layouts/WebLayout.astro +9 -2
- package/src/resume-templates/ResumeBuilderShell.astro +1 -1
- package/src/resume-templates/ResumeTemplateClassic.astro +2 -2
- package/src/resume-templates/ResumeTemplateExecutiveTimeline.astro +2 -2
- package/src/resume-templates/ResumeTemplateMinimal.astro +2 -2
- package/src/resume-templates/ResumeTemplateModernTwoTone.astro +2 -2
- package/{resume-templates → src/resume-templates}/typescript-schema.ts +17 -19
- package/src/utils/appUrls.ts +6 -1
- package/resume-templates/template-1.html +0 -154
- package/resume-templates/template-2.html +0 -172
- package/resume-templates/template-3.html +0 -160
- package/resume-templates/template-4.html +0 -156
- /package/{resume-templates → src/resume-templates}/resumeData.ts +0 -0
package/index.ts
CHANGED
|
@@ -34,14 +34,17 @@ export { default as AvTable } from './src/AvTable.astro';
|
|
|
34
34
|
export { default as AvTableToolbar } from './src/AvTableToolbar.astro';
|
|
35
35
|
export { default as AvTablePagination } from './src/AvTablePagination.astro';
|
|
36
36
|
export { default as QuizSummary } from './src/Summary/QuizSummary.astro';
|
|
37
|
+
export { default as FlashNoteSummary } from './src/Summary/FlashNoteSummary.astro';
|
|
38
|
+
export { default as ResumeBuilderSummary } from './src/Summary/ResumeBuilderSummary.astro';
|
|
39
|
+
export { default as PortfolioCreatorSummary } from './src/Summary/PortfolioCreatorSummary.astro';
|
|
37
40
|
export { default as ResumeBuilderShell } from './src/resume-templates/ResumeBuilderShell.astro';
|
|
38
41
|
export { default as ResumeTemplateClassic } from './src/resume-templates/ResumeTemplateClassic.astro';
|
|
39
42
|
export { default as ResumeTemplateModernTwoTone } from './src/resume-templates/ResumeTemplateModernTwoTone.astro';
|
|
40
43
|
export { default as ResumeTemplateMinimal } from './src/resume-templates/ResumeTemplateMinimal.astro';
|
|
41
44
|
export { default as ResumeTemplateExecutiveTimeline } from './src/resume-templates/ResumeTemplateExecutiveTimeline.astro';
|
|
42
|
-
export type { ResumeData, ResumeTemplateType } from './resume-templates/typescript-schema';
|
|
43
|
-
export { formatDateRange } from './resume-templates/typescript-schema';
|
|
44
|
-
export { resumeData } from './resume-templates/resumeData';
|
|
45
|
+
export type { ResumeData, ResumeTemplateType } from './src/resume-templates/typescript-schema';
|
|
46
|
+
export { formatDateRange } from './src/resume-templates/typescript-schema';
|
|
47
|
+
export { resumeData } from './src/resume-templates/resumeData';
|
|
45
48
|
|
|
46
49
|
export * from "./src/alpine";
|
|
47
50
|
export * from "./src/Summary/types";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ansiversa/components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.120",
|
|
4
4
|
"description": "Shared UI components and layouts for the Ansiversa ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -10,15 +10,19 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"src",
|
|
13
|
-
"resume-templates",
|
|
14
13
|
"index.ts"
|
|
15
14
|
],
|
|
16
15
|
"keywords": [
|
|
17
16
|
"astro-component"
|
|
18
17
|
],
|
|
19
|
-
"scripts": {
|
|
18
|
+
"scripts": {
|
|
19
|
+
"typecheck": "astro check",
|
|
20
|
+
"build": "astro check"
|
|
21
|
+
},
|
|
20
22
|
"devDependencies": {
|
|
21
|
-
"
|
|
23
|
+
"@astrojs/check": "^0.9.6",
|
|
24
|
+
"astro": "^5.16.3",
|
|
25
|
+
"typescript": "^5.9.3"
|
|
22
26
|
},
|
|
23
27
|
"peerDependencies": {
|
|
24
28
|
"astro": "^4.0.0 || ^5.0.0"
|
package/src/AvAccordion.astro
CHANGED
|
@@ -104,7 +104,6 @@ const scriptContent = `
|
|
|
104
104
|
data-id={item.id}
|
|
105
105
|
data-disabled={item.disabled ? "true" : undefined}
|
|
106
106
|
aria-disabled={item.disabled ? "true" : undefined}
|
|
107
|
-
disabled={item.disabled ? true : undefined}
|
|
108
107
|
>
|
|
109
108
|
<summary
|
|
110
109
|
class="av-accordion__summary"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { AvButton, AvCard } from "@ansiversa/components";
|
|
3
|
+
import type { FlashnoteDashboardSummaryV1 } from "./types";
|
|
4
|
+
import { buildAppUrl } from "../utils/appUrls";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
summary: FlashnoteDashboardSummaryV1;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { summary } = Astro.props as Props;
|
|
11
|
+
|
|
12
|
+
const formatDateTime = (value: string | null, fallback = "Not yet") => {
|
|
13
|
+
if (!value) return fallback;
|
|
14
|
+
const parsed = new Date(value);
|
|
15
|
+
return Number.isNaN(parsed.getTime()) ? fallback : parsed.toLocaleString();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const flashnoteBaseUrl = buildAppUrl(summary.appId);
|
|
19
|
+
const decksUrl = buildAppUrl(summary.appId, "/decks");
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<section class="av-auth-stack-lg">
|
|
23
|
+
<div class="av-form-row">
|
|
24
|
+
<div class="av-auth-stack-xxs">
|
|
25
|
+
<div class="av-kicker">
|
|
26
|
+
<span>FlashNote</span>
|
|
27
|
+
</div>
|
|
28
|
+
<h2 class="av-card-heading">FlashNote summary</h2>
|
|
29
|
+
<p class="av-text-soft">Last study: {formatDateTime(summary.lastStudyAt)}</p>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="av-row-wrap">
|
|
32
|
+
<AvButton href={flashnoteBaseUrl} size="sm">Open FlashNote</AvButton>
|
|
33
|
+
<AvButton href={decksUrl} size="sm" variant="ghost">View decks</AvButton>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="av-grid-auto av-grid-auto--260">
|
|
38
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
39
|
+
<div class="av-auth-stack-xxs">
|
|
40
|
+
<p class="av-card-heading">Decks</p>
|
|
41
|
+
<h3 class="av-app-card-title">{summary.decksCount}</h3>
|
|
42
|
+
<p class="av-text-soft">Total decks</p>
|
|
43
|
+
</div>
|
|
44
|
+
</AvCard>
|
|
45
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
46
|
+
<div class="av-auth-stack-xxs">
|
|
47
|
+
<p class="av-card-heading">Cards</p>
|
|
48
|
+
<h3 class="av-app-card-title">{summary.cardsCount}</h3>
|
|
49
|
+
<p class="av-text-soft">Across all decks</p>
|
|
50
|
+
</div>
|
|
51
|
+
</AvCard>
|
|
52
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
53
|
+
<div class="av-auth-stack-xxs">
|
|
54
|
+
<p class="av-card-heading">Reviews today</p>
|
|
55
|
+
<h3 class="av-app-card-title">{summary.reviewsToday}</h3>
|
|
56
|
+
<p class="av-text-soft">Scheduled reviews</p>
|
|
57
|
+
</div>
|
|
58
|
+
</AvCard>
|
|
59
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
60
|
+
<div class="av-auth-stack-xxs">
|
|
61
|
+
<p class="av-card-heading">Last import</p>
|
|
62
|
+
<h3 class="av-app-card-title">
|
|
63
|
+
{formatDateTime(summary.lastImportedFromQuizAt, "No quiz imports")}
|
|
64
|
+
</h3>
|
|
65
|
+
<p class="av-text-soft">Quiz cards</p>
|
|
66
|
+
</div>
|
|
67
|
+
</AvCard>
|
|
68
|
+
</div>
|
|
69
|
+
</section>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { AvButton, AvCard } from "@ansiversa/components";
|
|
3
|
+
import type { PortfolioDashboardSummaryV1 } from "./types";
|
|
4
|
+
import { buildAppUrl } from "../utils/appUrls";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
summary: PortfolioDashboardSummaryV1;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { summary } = Astro.props as Props;
|
|
11
|
+
|
|
12
|
+
const formatDateTime = (value: string | null, fallback = "Not yet") => {
|
|
13
|
+
if (!value) return fallback;
|
|
14
|
+
const parsed = new Date(value);
|
|
15
|
+
return Number.isNaN(parsed.getTime()) ? fallback : parsed.toLocaleString();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const portfolioBaseUrl = buildAppUrl(summary.appId);
|
|
19
|
+
const portfoliosUrl = buildAppUrl(summary.appId, "/app/portfolios");
|
|
20
|
+
const completionLabel =
|
|
21
|
+
typeof summary.completionHint === "number" ? `${summary.completionHint}%` : "—";
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<section class="av-auth-stack-lg">
|
|
25
|
+
<div class="av-form-row">
|
|
26
|
+
<div class="av-auth-stack-xxs">
|
|
27
|
+
<div class="av-kicker">
|
|
28
|
+
<span>Portfolio Creator</span>
|
|
29
|
+
</div>
|
|
30
|
+
<h2 class="av-card-heading">Portfolio summary</h2>
|
|
31
|
+
<p class="av-text-soft">Last updated: {formatDateTime(summary.lastUpdatedAt)}</p>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="av-row-wrap">
|
|
34
|
+
<AvButton href={portfolioBaseUrl} size="sm">Open Portfolio Creator</AvButton>
|
|
35
|
+
<AvButton href={portfoliosUrl} size="sm" variant="ghost">View portfolios</AvButton>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="av-grid-auto av-grid-auto--260">
|
|
40
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
41
|
+
<div class="av-auth-stack-xxs">
|
|
42
|
+
<p class="av-card-heading">Portfolios</p>
|
|
43
|
+
<h3 class="av-app-card-title">{summary.totalPortfolios}</h3>
|
|
44
|
+
<p class="av-text-soft">Total portfolios</p>
|
|
45
|
+
</div>
|
|
46
|
+
</AvCard>
|
|
47
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
48
|
+
<div class="av-auth-stack-xxs">
|
|
49
|
+
<p class="av-card-heading">Published</p>
|
|
50
|
+
<h3 class="av-app-card-title">{summary.publishedCount}</h3>
|
|
51
|
+
<p class="av-text-soft">Live portfolios</p>
|
|
52
|
+
</div>
|
|
53
|
+
</AvCard>
|
|
54
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
55
|
+
<div class="av-auth-stack-xxs">
|
|
56
|
+
<p class="av-card-heading">Completion</p>
|
|
57
|
+
<h3 class="av-app-card-title">{completionLabel}</h3>
|
|
58
|
+
<p class="av-text-soft">Publish ratio</p>
|
|
59
|
+
</div>
|
|
60
|
+
</AvCard>
|
|
61
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
62
|
+
<div class="av-auth-stack-xxs">
|
|
63
|
+
<p class="av-card-heading">Visibility</p>
|
|
64
|
+
<h3 class="av-app-card-title">
|
|
65
|
+
{summary.visibilityBreakdown.public} / {summary.visibilityBreakdown.unlisted} / {summary.visibilityBreakdown.private}
|
|
66
|
+
</h3>
|
|
67
|
+
<p class="av-text-soft">Public / Unlisted / Private</p>
|
|
68
|
+
</div>
|
|
69
|
+
</AvCard>
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { AvButton, AvCard } from "@ansiversa/components";
|
|
3
|
+
import type { ResumeBuilderDashboardSummaryV1 } from "./types";
|
|
4
|
+
import { buildAppUrl } from "../utils/appUrls";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
summary: ResumeBuilderDashboardSummaryV1;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { summary } = Astro.props as Props;
|
|
11
|
+
|
|
12
|
+
const formatDateTime = (value: string | null, fallback = "Not yet") => {
|
|
13
|
+
if (!value) return fallback;
|
|
14
|
+
const parsed = new Date(value);
|
|
15
|
+
return Number.isNaN(parsed.getTime()) ? fallback : parsed.toLocaleString();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const resumeBaseUrl = buildAppUrl(summary.appId);
|
|
19
|
+
const resumesUrl = buildAppUrl(summary.appId, "/app/resumes");
|
|
20
|
+
const templatesLabel = summary.templatesUsed.length > 0 ? summary.templatesUsed.join(", ") : "No templates yet";
|
|
21
|
+
const completionLabel =
|
|
22
|
+
typeof summary.completionHint === "number" ? `${summary.completionHint}%` : "—";
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<section class="av-auth-stack-lg">
|
|
26
|
+
<div class="av-form-row">
|
|
27
|
+
<div class="av-auth-stack-xxs">
|
|
28
|
+
<div class="av-kicker">
|
|
29
|
+
<span>Resume Builder</span>
|
|
30
|
+
</div>
|
|
31
|
+
<h2 class="av-card-heading">Resume builder summary</h2>
|
|
32
|
+
<p class="av-text-soft">Last updated: {formatDateTime(summary.lastUpdatedAt)}</p>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="av-row-wrap">
|
|
35
|
+
<AvButton href={resumeBaseUrl} size="sm">Open Resume Builder</AvButton>
|
|
36
|
+
<AvButton href={resumesUrl} size="sm" variant="ghost">View resumes</AvButton>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class="av-grid-auto av-grid-auto--260">
|
|
41
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
42
|
+
<div class="av-auth-stack-xxs">
|
|
43
|
+
<p class="av-card-heading">Resumes</p>
|
|
44
|
+
<h3 class="av-app-card-title">{summary.totalResumes}</h3>
|
|
45
|
+
<p class="av-text-soft">Total resumes</p>
|
|
46
|
+
</div>
|
|
47
|
+
</AvCard>
|
|
48
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
49
|
+
<div class="av-auth-stack-xxs">
|
|
50
|
+
<p class="av-card-heading">Completion</p>
|
|
51
|
+
<h3 class="av-app-card-title">{completionLabel}</h3>
|
|
52
|
+
<p class="av-text-soft">Enabled sections</p>
|
|
53
|
+
</div>
|
|
54
|
+
</AvCard>
|
|
55
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
56
|
+
<div class="av-auth-stack-xxs">
|
|
57
|
+
<p class="av-card-heading">Default resume</p>
|
|
58
|
+
<h3 class="av-app-card-title">{summary.defaultResumeTitle ?? "Not set"}</h3>
|
|
59
|
+
<p class="av-text-soft">Primary resume</p>
|
|
60
|
+
</div>
|
|
61
|
+
</AvCard>
|
|
62
|
+
<AvCard variant="soft" className="av-card--fullheight">
|
|
63
|
+
<div class="av-auth-stack-xxs">
|
|
64
|
+
<p class="av-card-heading">Templates used</p>
|
|
65
|
+
<h3 class="av-app-card-title">{summary.templatesUsed.length}</h3>
|
|
66
|
+
<p class="av-text-soft">{templatesLabel}</p>
|
|
67
|
+
</div>
|
|
68
|
+
</AvCard>
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
package/src/Summary/types.ts
CHANGED
|
@@ -28,3 +28,39 @@ export type QuizDashboardSummaryV1 = {
|
|
|
28
28
|
avgScorePct: number;
|
|
29
29
|
}>;
|
|
30
30
|
};
|
|
31
|
+
|
|
32
|
+
export type FlashnoteDashboardSummaryV1 = {
|
|
33
|
+
appId: "flashnote";
|
|
34
|
+
version: 1;
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
decksCount: number;
|
|
37
|
+
cardsCount: number;
|
|
38
|
+
reviewsToday: number;
|
|
39
|
+
lastStudyAt: string | null;
|
|
40
|
+
lastImportedFromQuizAt: string | null;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type ResumeBuilderDashboardSummaryV1 = {
|
|
44
|
+
appId: "resume-builder";
|
|
45
|
+
version: 1;
|
|
46
|
+
totalResumes: number;
|
|
47
|
+
defaultResumeTitle: string | null;
|
|
48
|
+
lastUpdatedAt: string;
|
|
49
|
+
templatesUsed: string[];
|
|
50
|
+
sectionsEnabledCount?: number;
|
|
51
|
+
completionHint?: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type PortfolioDashboardSummaryV1 = {
|
|
55
|
+
appId: "portfolio-creator";
|
|
56
|
+
version: 1;
|
|
57
|
+
totalPortfolios: number;
|
|
58
|
+
publishedCount: number;
|
|
59
|
+
lastUpdatedAt: string;
|
|
60
|
+
visibilityBreakdown: {
|
|
61
|
+
public: number;
|
|
62
|
+
unlisted: number;
|
|
63
|
+
private: number;
|
|
64
|
+
};
|
|
65
|
+
completionHint?: number;
|
|
66
|
+
};
|
|
@@ -10,6 +10,7 @@ interface Props {
|
|
|
10
10
|
description?: string;
|
|
11
11
|
notificationUnreadCount?: number;
|
|
12
12
|
miniAppKey?: string;
|
|
13
|
+
links?: { label: string; href: string }[];
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const {
|
|
@@ -17,9 +18,15 @@ const {
|
|
|
17
18
|
description = "Ansiversa – A unified ecosystem of premium Apps designed to feel simple, powerful, and delightful.",
|
|
18
19
|
notificationUnreadCount = 0,
|
|
19
20
|
miniAppKey,
|
|
21
|
+
links,
|
|
20
22
|
} = Astro.props;
|
|
21
23
|
|
|
22
|
-
const user = Astro.locals
|
|
24
|
+
const user = (Astro.locals as { user?: {
|
|
25
|
+
id: string;
|
|
26
|
+
email: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
roleId?: number;
|
|
29
|
+
} }).user;
|
|
23
30
|
|
|
24
31
|
const rawDomain = (
|
|
25
32
|
import.meta.env.PUBLIC_SITE_URL ||
|
|
@@ -80,7 +87,7 @@ const ROOT_URL = rawDomain.match(/^https?:\/\//i)
|
|
|
80
87
|
<AvNavbarActions user={user} notificationUnreadCount={notificationUnreadCount} />
|
|
81
88
|
</AvNavbar>
|
|
82
89
|
|
|
83
|
-
{miniAppKey && <AvMiniAppBar appKey={miniAppKey} />}
|
|
90
|
+
{miniAppKey && <AvMiniAppBar appKey={miniAppKey} links={links} />}
|
|
84
91
|
|
|
85
92
|
<!-- Main content -->
|
|
86
93
|
<main class="av-main">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ResumeData, ResumeTemplateType } from "
|
|
2
|
+
import type { ResumeData, ResumeTemplateType } from "./typescript-schema";
|
|
3
3
|
import ResumeTemplateClassic from "./ResumeTemplateClassic.astro";
|
|
4
4
|
import ResumeTemplateExecutiveTimeline from "./ResumeTemplateExecutiveTimeline.astro";
|
|
5
5
|
import ResumeTemplateMinimal from "./ResumeTemplateMinimal.astro";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ResumeData } from "
|
|
3
|
-
import { formatDateRange } from "
|
|
2
|
+
import type { ResumeData } from "./typescript-schema";
|
|
3
|
+
import { formatDateRange } from "./typescript-schema";
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
data: ResumeData;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ResumeData } from "
|
|
3
|
-
import { formatDateRange } from "
|
|
2
|
+
import type { ResumeData } from "./typescript-schema";
|
|
3
|
+
import { formatDateRange } from "./typescript-schema";
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
data: ResumeData;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ResumeData } from "
|
|
3
|
-
import { formatDateRange } from "
|
|
2
|
+
import type { ResumeData } from "./typescript-schema";
|
|
3
|
+
import { formatDateRange } from "./typescript-schema";
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
data: ResumeData;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ResumeData } from "
|
|
3
|
-
import { formatDateRange } from "
|
|
2
|
+
import type { ResumeData } from "./typescript-schema";
|
|
3
|
+
import { formatDateRange } from "./typescript-schema";
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
data: ResumeData;
|
|
@@ -5,13 +5,13 @@ export type ResumeData = {
|
|
|
5
5
|
|
|
6
6
|
basics: {
|
|
7
7
|
fullName: string;
|
|
8
|
-
headline: string;
|
|
8
|
+
headline: string;
|
|
9
9
|
summary?: string;
|
|
10
10
|
|
|
11
11
|
location?: {
|
|
12
12
|
city?: string;
|
|
13
13
|
country?: string;
|
|
14
|
-
label?: string;
|
|
14
|
+
label?: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
contact: {
|
|
@@ -21,30 +21,30 @@ export type ResumeData = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
links?: Array<{
|
|
24
|
-
label: string;
|
|
24
|
+
label: string;
|
|
25
25
|
url: string;
|
|
26
26
|
}>;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
skills?: Array<{
|
|
30
|
-
name: string;
|
|
30
|
+
name: string;
|
|
31
31
|
level?: "Beginner" | "Intermediate" | "Advanced" | "Expert";
|
|
32
|
-
keywords?: string[];
|
|
32
|
+
keywords?: string[];
|
|
33
33
|
}>;
|
|
34
34
|
|
|
35
|
-
highlights?: string[];
|
|
35
|
+
highlights?: string[];
|
|
36
36
|
|
|
37
37
|
experience?: Array<{
|
|
38
|
-
id: string;
|
|
39
|
-
role: string;
|
|
40
|
-
company: string;
|
|
41
|
-
location?: string;
|
|
38
|
+
id: string;
|
|
39
|
+
role: string;
|
|
40
|
+
company: string;
|
|
41
|
+
location?: string;
|
|
42
42
|
start: { year: number; month?: number };
|
|
43
|
-
end?: { year: number; month?: number };
|
|
43
|
+
end?: { year: number; month?: number };
|
|
44
44
|
present?: boolean;
|
|
45
|
-
summary?: string;
|
|
45
|
+
summary?: string;
|
|
46
46
|
bullets?: string[];
|
|
47
|
-
tags?: string[];
|
|
47
|
+
tags?: string[];
|
|
48
48
|
}>;
|
|
49
49
|
|
|
50
50
|
projects?: Array<{
|
|
@@ -61,12 +61,12 @@ export type ResumeData = {
|
|
|
61
61
|
|
|
62
62
|
education?: Array<{
|
|
63
63
|
id: string;
|
|
64
|
-
degree: string;
|
|
64
|
+
degree: string;
|
|
65
65
|
school: string;
|
|
66
66
|
location?: string;
|
|
67
67
|
start?: { year: number; month?: number };
|
|
68
68
|
end?: { year: number; month?: number };
|
|
69
|
-
grade?: string;
|
|
69
|
+
grade?: string;
|
|
70
70
|
bullets?: string[];
|
|
71
71
|
}>;
|
|
72
72
|
|
|
@@ -79,7 +79,7 @@ export type ResumeData = {
|
|
|
79
79
|
}>;
|
|
80
80
|
|
|
81
81
|
languages?: Array<{
|
|
82
|
-
name: string;
|
|
82
|
+
name: string;
|
|
83
83
|
proficiency?: "Native" | "Fluent" | "Professional" | "Intermediate" | "Basic";
|
|
84
84
|
}>;
|
|
85
85
|
|
|
@@ -97,14 +97,12 @@ export type ResumeData = {
|
|
|
97
97
|
name?: string;
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
-
// Template feature flags (optional)
|
|
101
100
|
settings?: {
|
|
102
|
-
showSkillsAs?: "chips" | "levels";
|
|
101
|
+
showSkillsAs?: "chips" | "levels";
|
|
103
102
|
paper?: "A4" | "Letter";
|
|
104
103
|
};
|
|
105
104
|
};
|
|
106
105
|
|
|
107
|
-
/** Helpers (optional for Codex) */
|
|
108
106
|
export function formatDateRange(item: {
|
|
109
107
|
start: { year: number; month?: number };
|
|
110
108
|
end?: { year: number; month?: number };
|
package/src/utils/appUrls.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const ROOT_DOMAIN = "ansiversa.com";
|
|
2
2
|
|
|
3
|
-
const MINI_APP_SLUGS = new Set([
|
|
3
|
+
const MINI_APP_SLUGS = new Set([
|
|
4
|
+
"quiz",
|
|
5
|
+
"flashnote",
|
|
6
|
+
"resume-builder",
|
|
7
|
+
"portfolio-creator",
|
|
8
|
+
]);
|
|
4
9
|
|
|
5
10
|
export const getAppBaseUrl = (appSlug: string) => {
|
|
6
11
|
if (!appSlug) {
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Resume Template 1 - Classic ATS</title>
|
|
7
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
-
<style>
|
|
9
|
-
@media print {
|
|
10
|
-
.no-print { display: none !important; }
|
|
11
|
-
a { text-decoration: none; color: inherit; }
|
|
12
|
-
}
|
|
13
|
-
</style>
|
|
14
|
-
</head>
|
|
15
|
-
<body class="bg-slate-100 text-slate-900">
|
|
16
|
-
<div class="no-print sticky top-0 z-10 border-b border-slate-200 bg-white/90 backdrop-blur">
|
|
17
|
-
<div class="mx-auto flex max-w-4xl items-center justify-between px-4 py-3">
|
|
18
|
-
<div class="text-sm text-slate-600">Template 1 — Classic ATS</div>
|
|
19
|
-
<button class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50" onclick="window.print()">
|
|
20
|
-
Print / Save PDF
|
|
21
|
-
</button>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<main class="mx-auto max-w-4xl p-4 sm:p-6">
|
|
26
|
-
<section class="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-slate-200 sm:p-10 print:shadow-none print:ring-0">
|
|
27
|
-
<header class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
|
28
|
-
<div>
|
|
29
|
-
<h1 class="text-3xl font-bold tracking-tight">Karthikeyan Ramalingam</h1>
|
|
30
|
-
<p class="mt-1 text-base font-medium text-slate-700">Senior Software Developer</p>
|
|
31
|
-
<p class="mt-3 max-w-2xl text-sm leading-6 text-slate-600">
|
|
32
|
-
Senior software developer focused on scalable systems, clean UX, and production-grade architecture.
|
|
33
|
-
</p>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<div class="text-sm text-slate-700 sm:text-right">
|
|
37
|
-
<div class="flex flex-col gap-1">
|
|
38
|
-
<span>Abu Dhabi, UAE</span>
|
|
39
|
-
<a class="text-slate-900 underline underline-offset-2 hover:text-slate-700" href="mailto:you@email.com">you@email.com</a>
|
|
40
|
-
<a class="text-slate-900 underline underline-offset-2 hover:text-slate-700" href="tel:+971500000000">+971 50 000 0000</a>
|
|
41
|
-
<a class="text-slate-900 underline underline-offset-2 hover:text-slate-700" href="#">ansiversa.com</a>
|
|
42
|
-
<a class="text-slate-900 underline underline-offset-2 hover:text-slate-700" href="#">linkedin.com/in/yourname</a>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</header>
|
|
46
|
-
|
|
47
|
-
<div class="my-8 h-px bg-slate-200"></div>
|
|
48
|
-
|
|
49
|
-
<div class="grid gap-10 lg:grid-cols-3">
|
|
50
|
-
<div class="lg:col-span-2 space-y-10">
|
|
51
|
-
<section>
|
|
52
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">EXPERIENCE</h2>
|
|
53
|
-
<div class="mt-4 space-y-6">
|
|
54
|
-
<article>
|
|
55
|
-
<div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between">
|
|
56
|
-
<div>
|
|
57
|
-
<h3 class="text-base font-semibold">Senior Software Developer</h3>
|
|
58
|
-
<p class="text-sm text-slate-700">Global Aerospace Logistics Company</p>
|
|
59
|
-
</div>
|
|
60
|
-
<p class="text-sm text-slate-600">2023 — Present · UAE</p>
|
|
61
|
-
</div>
|
|
62
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
63
|
-
<li>Designed and shipped internal platforms improving operational visibility and data accuracy.</li>
|
|
64
|
-
<li>Built reusable UI patterns and performance-focused server workflows.</li>
|
|
65
|
-
<li>Collaborated cross-functionally to deliver stable production releases.</li>
|
|
66
|
-
</ul>
|
|
67
|
-
</article>
|
|
68
|
-
|
|
69
|
-
<article>
|
|
70
|
-
<div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between">
|
|
71
|
-
<div>
|
|
72
|
-
<h3 class="text-base font-semibold">Software Developer</h3>
|
|
73
|
-
<p class="text-sm text-slate-700">HCL Technologies</p>
|
|
74
|
-
</div>
|
|
75
|
-
<p class="text-sm text-slate-600">2019 — 2023 · India</p>
|
|
76
|
-
</div>
|
|
77
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
78
|
-
<li>Delivered enterprise features with strong focus on quality and maintainability.</li>
|
|
79
|
-
<li>Improved reporting workflows and data handling for business-critical modules.</li>
|
|
80
|
-
<li>Worked closely with QA and product owners to reduce defects.</li>
|
|
81
|
-
</ul>
|
|
82
|
-
</article>
|
|
83
|
-
</div>
|
|
84
|
-
</section>
|
|
85
|
-
|
|
86
|
-
<section>
|
|
87
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">PROJECTS</h2>
|
|
88
|
-
<div class="mt-4 space-y-5">
|
|
89
|
-
<article>
|
|
90
|
-
<div class="flex items-baseline justify-between gap-3">
|
|
91
|
-
<h3 class="text-base font-semibold">Ansiversa</h3>
|
|
92
|
-
<p class="text-sm text-slate-600">2024 — Present</p>
|
|
93
|
-
</div>
|
|
94
|
-
<p class="mt-2 text-sm leading-6 text-slate-700">
|
|
95
|
-
Built a multi-app ecosystem with shared auth, strict UI standards, and a reusable component library.
|
|
96
|
-
</p>
|
|
97
|
-
<div class="mt-2 flex flex-wrap gap-2">
|
|
98
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-medium text-slate-700">Astro</span>
|
|
99
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-medium text-slate-700">Alpine</span>
|
|
100
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-medium text-slate-700">Tailwind</span>
|
|
101
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-medium text-slate-700">libSQL</span>
|
|
102
|
-
</div>
|
|
103
|
-
</article>
|
|
104
|
-
</div>
|
|
105
|
-
</section>
|
|
106
|
-
|
|
107
|
-
<section>
|
|
108
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">EDUCATION</h2>
|
|
109
|
-
<div class="mt-4">
|
|
110
|
-
<div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between">
|
|
111
|
-
<div>
|
|
112
|
-
<h3 class="text-base font-semibold">B.E. / B.Tech — Computer Science</h3>
|
|
113
|
-
<p class="text-sm text-slate-700">Your University Name</p>
|
|
114
|
-
</div>
|
|
115
|
-
<p class="text-sm text-slate-600">2015 — 2019</p>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
</section>
|
|
119
|
-
</div>
|
|
120
|
-
|
|
121
|
-
<aside class="space-y-10">
|
|
122
|
-
<section>
|
|
123
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">SKILLS</h2>
|
|
124
|
-
<div class="mt-4 flex flex-wrap gap-2">
|
|
125
|
-
<span class="rounded-lg bg-slate-100 px-3 py-1.5 text-sm text-slate-800">TypeScript</span>
|
|
126
|
-
<span class="rounded-lg bg-slate-100 px-3 py-1.5 text-sm text-slate-800">Node.js</span>
|
|
127
|
-
<span class="rounded-lg bg-slate-100 px-3 py-1.5 text-sm text-slate-800">Astro</span>
|
|
128
|
-
<span class="rounded-lg bg-slate-100 px-3 py-1.5 text-sm text-slate-800">PostgreSQL</span>
|
|
129
|
-
<span class="rounded-lg bg-slate-100 px-3 py-1.5 text-sm text-slate-800">System Design</span>
|
|
130
|
-
</div>
|
|
131
|
-
</section>
|
|
132
|
-
|
|
133
|
-
<section>
|
|
134
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">HIGHLIGHTS</h2>
|
|
135
|
-
<ul class="mt-4 space-y-2 text-sm leading-6 text-slate-700">
|
|
136
|
-
<li>• Strong focus on clean UX and predictable components.</li>
|
|
137
|
-
<li>• Production mindset: verification, freeze, stability.</li>
|
|
138
|
-
<li>• Built reusable standards for a 100-app ecosystem.</li>
|
|
139
|
-
</ul>
|
|
140
|
-
</section>
|
|
141
|
-
|
|
142
|
-
<section>
|
|
143
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">LANGUAGES</h2>
|
|
144
|
-
<ul class="mt-4 space-y-2 text-sm text-slate-700">
|
|
145
|
-
<li>English</li>
|
|
146
|
-
<li>Tamil</li>
|
|
147
|
-
</ul>
|
|
148
|
-
</section>
|
|
149
|
-
</aside>
|
|
150
|
-
</div>
|
|
151
|
-
</section>
|
|
152
|
-
</main>
|
|
153
|
-
</body>
|
|
154
|
-
</html>
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Resume Template 2 - Modern Two-Tone</title>
|
|
7
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
-
<style>
|
|
9
|
-
@media print {
|
|
10
|
-
.no-print { display: none !important; }
|
|
11
|
-
a { text-decoration: none; color: inherit; }
|
|
12
|
-
body { background: white !important; }
|
|
13
|
-
}
|
|
14
|
-
</style>
|
|
15
|
-
</head>
|
|
16
|
-
<body class="bg-slate-100 text-slate-900">
|
|
17
|
-
<div class="no-print sticky top-0 z-10 border-b border-slate-200 bg-white/90 backdrop-blur">
|
|
18
|
-
<div class="mx-auto flex max-w-4xl items-center justify-between px-4 py-3">
|
|
19
|
-
<div class="text-sm text-slate-600">Template 2 — Modern Two-Tone</div>
|
|
20
|
-
<button class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50" onclick="window.print()">
|
|
21
|
-
Print / Save PDF
|
|
22
|
-
</button>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<main class="mx-auto max-w-4xl p-4 sm:p-6">
|
|
27
|
-
<section class="overflow-hidden rounded-2xl bg-white shadow-sm ring-1 ring-slate-200 print:shadow-none print:ring-0">
|
|
28
|
-
<div class="grid lg:grid-cols-12">
|
|
29
|
-
<!-- Sidebar -->
|
|
30
|
-
<aside class="lg:col-span-4 bg-slate-900 text-white p-7 sm:p-10">
|
|
31
|
-
<div class="space-y-6">
|
|
32
|
-
<div>
|
|
33
|
-
<h1 class="text-3xl font-bold tracking-tight">Karthikeyan</h1>
|
|
34
|
-
<h1 class="text-3xl font-bold tracking-tight -mt-1">Ramalingam</h1>
|
|
35
|
-
<p class="mt-2 text-sm text-white/80">Senior Software Developer</p>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<div class="h-px bg-white/10"></div>
|
|
39
|
-
|
|
40
|
-
<div class="space-y-2 text-sm">
|
|
41
|
-
<div class="text-white/70">CONTACT</div>
|
|
42
|
-
<div class="space-y-1 text-white/90">
|
|
43
|
-
<div>Abu Dhabi, UAE</div>
|
|
44
|
-
<a class="underline underline-offset-2" href="mailto:you@email.com">you@email.com</a>
|
|
45
|
-
<a class="underline underline-offset-2" href="tel:+971500000000">+971 50 000 0000</a>
|
|
46
|
-
<a class="underline underline-offset-2" href="#">ansiversa.com</a>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
<div class="space-y-3">
|
|
51
|
-
<div class="text-sm text-white/70">SKILLS</div>
|
|
52
|
-
<div class="flex flex-wrap gap-2">
|
|
53
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">TypeScript</span>
|
|
54
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">Astro</span>
|
|
55
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">Alpine</span>
|
|
56
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">SQL</span>
|
|
57
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">Architecture</span>
|
|
58
|
-
<span class="rounded-full bg-white/10 px-3 py-1 text-xs">UI Systems</span>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
|
|
62
|
-
<div class="space-y-2">
|
|
63
|
-
<div class="text-sm text-white/70">LINKS</div>
|
|
64
|
-
<div class="space-y-1 text-sm text-white/90">
|
|
65
|
-
<a class="underline underline-offset-2" href="#">linkedin.com/in/yourname</a>
|
|
66
|
-
<a class="underline underline-offset-2" href="#">github.com/yourname</a>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<div class="space-y-2">
|
|
71
|
-
<div class="text-sm text-white/70">LANGUAGES</div>
|
|
72
|
-
<div class="text-sm text-white/90">English · Tamil</div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</aside>
|
|
76
|
-
|
|
77
|
-
<!-- Main -->
|
|
78
|
-
<div class="lg:col-span-8 p-7 sm:p-10">
|
|
79
|
-
<section>
|
|
80
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">PROFILE</h2>
|
|
81
|
-
<p class="mt-3 text-sm leading-6 text-slate-700">
|
|
82
|
-
Senior software developer with a strong track record in enterprise systems, scalable architecture,
|
|
83
|
-
and premium UI design. Known for predictable standards, verification-first delivery, and long-term maintainability.
|
|
84
|
-
</p>
|
|
85
|
-
</section>
|
|
86
|
-
|
|
87
|
-
<div class="my-8 h-px bg-slate-200"></div>
|
|
88
|
-
|
|
89
|
-
<section>
|
|
90
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">EXPERIENCE</h2>
|
|
91
|
-
<div class="mt-5 space-y-6">
|
|
92
|
-
<article>
|
|
93
|
-
<div class="flex items-start justify-between gap-4">
|
|
94
|
-
<div>
|
|
95
|
-
<h3 class="text-base font-semibold">Senior Software Developer</h3>
|
|
96
|
-
<p class="text-sm text-slate-600">Global Aerospace Logistics Company</p>
|
|
97
|
-
</div>
|
|
98
|
-
<span class="shrink-0 rounded-full bg-slate-100 px-3 py-1 text-xs text-slate-700">2023—Present</span>
|
|
99
|
-
</div>
|
|
100
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
101
|
-
<li>Shipped systems improving operational visibility and data accuracy.</li>
|
|
102
|
-
<li>Built reusable UI patterns and server-side workflows.</li>
|
|
103
|
-
<li>Improved performance and reliability in production releases.</li>
|
|
104
|
-
</ul>
|
|
105
|
-
</article>
|
|
106
|
-
|
|
107
|
-
<article>
|
|
108
|
-
<div class="flex items-start justify-between gap-4">
|
|
109
|
-
<div>
|
|
110
|
-
<h3 class="text-base font-semibold">Software Developer</h3>
|
|
111
|
-
<p class="text-sm text-slate-600">HCL Technologies</p>
|
|
112
|
-
</div>
|
|
113
|
-
<span class="shrink-0 rounded-full bg-slate-100 px-3 py-1 text-xs text-slate-700">2019—2023</span>
|
|
114
|
-
</div>
|
|
115
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
116
|
-
<li>Delivered enterprise features with high maintainability standards.</li>
|
|
117
|
-
<li>Improved reporting and data pipelines for business-critical modules.</li>
|
|
118
|
-
</ul>
|
|
119
|
-
</article>
|
|
120
|
-
</div>
|
|
121
|
-
</section>
|
|
122
|
-
|
|
123
|
-
<div class="my-8 h-px bg-slate-200"></div>
|
|
124
|
-
|
|
125
|
-
<section class="grid gap-8 sm:grid-cols-2">
|
|
126
|
-
<div>
|
|
127
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">PROJECTS</h2>
|
|
128
|
-
<div class="mt-4 space-y-4">
|
|
129
|
-
<div class="rounded-xl border border-slate-200 p-4">
|
|
130
|
-
<div class="flex items-baseline justify-between">
|
|
131
|
-
<h3 class="font-semibold">Ansiversa</h3>
|
|
132
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
133
|
-
</div>
|
|
134
|
-
<p class="mt-2 text-sm leading-6 text-slate-700">
|
|
135
|
-
Multi-app ecosystem with shared components and strict standards.
|
|
136
|
-
</p>
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<div class="rounded-xl border border-slate-200 p-4">
|
|
140
|
-
<div class="flex items-baseline justify-between">
|
|
141
|
-
<h3 class="font-semibold">Quiz Institute</h3>
|
|
142
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
143
|
-
</div>
|
|
144
|
-
<p class="mt-2 text-sm leading-6 text-slate-700">
|
|
145
|
-
Step-based quiz playthrough with metadata loading and results saving.
|
|
146
|
-
</p>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
|
|
151
|
-
<div>
|
|
152
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">EDUCATION</h2>
|
|
153
|
-
<div class="mt-4 rounded-xl border border-slate-200 p-4">
|
|
154
|
-
<h3 class="font-semibold">B.E. / B.Tech — Computer Science</h3>
|
|
155
|
-
<p class="text-sm text-slate-600">Your University Name</p>
|
|
156
|
-
<p class="mt-1 text-xs text-slate-500">2015—2019</p>
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
<h2 class="mt-8 text-xs font-bold tracking-widest text-slate-500">HIGHLIGHTS</h2>
|
|
160
|
-
<ul class="mt-4 space-y-2 text-sm leading-6 text-slate-700">
|
|
161
|
-
<li>• Verification-first delivery mindset</li>
|
|
162
|
-
<li>• Component-driven architecture</li>
|
|
163
|
-
<li>• Premium, consistent UI across apps</li>
|
|
164
|
-
</ul>
|
|
165
|
-
</div>
|
|
166
|
-
</section>
|
|
167
|
-
</div>
|
|
168
|
-
</div>
|
|
169
|
-
</section>
|
|
170
|
-
</main>
|
|
171
|
-
</body>
|
|
172
|
-
</html>
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Resume Template 3 - Minimal Luxury</title>
|
|
7
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
-
<style>
|
|
9
|
-
@media print {
|
|
10
|
-
.no-print { display: none !important; }
|
|
11
|
-
a { text-decoration: none; color: inherit; }
|
|
12
|
-
body { background: white !important; }
|
|
13
|
-
}
|
|
14
|
-
</style>
|
|
15
|
-
</head>
|
|
16
|
-
<body class="bg-slate-100 text-slate-900">
|
|
17
|
-
<div class="no-print sticky top-0 z-10 border-b border-slate-200 bg-white/90 backdrop-blur">
|
|
18
|
-
<div class="mx-auto flex max-w-4xl items-center justify-between px-4 py-3">
|
|
19
|
-
<div class="text-sm text-slate-600">Template 3 — Minimal Luxury</div>
|
|
20
|
-
<button class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50" onclick="window.print()">
|
|
21
|
-
Print / Save PDF
|
|
22
|
-
</button>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<main class="mx-auto max-w-4xl p-4 sm:p-6">
|
|
27
|
-
<section class="rounded-2xl bg-white p-8 sm:p-12 shadow-sm ring-1 ring-slate-200 print:shadow-none print:ring-0">
|
|
28
|
-
<header class="space-y-4">
|
|
29
|
-
<div class="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
|
|
30
|
-
<div>
|
|
31
|
-
<h1 class="text-4xl font-semibold tracking-tight">Karthikeyan Ramalingam</h1>
|
|
32
|
-
<p class="mt-2 text-sm text-slate-600">Senior Software Developer · Abu Dhabi, UAE</p>
|
|
33
|
-
</div>
|
|
34
|
-
<div class="text-sm text-slate-700 sm:text-right">
|
|
35
|
-
<div class="flex flex-col gap-1">
|
|
36
|
-
<a class="underline underline-offset-4 hover:text-slate-900" href="mailto:you@email.com">you@email.com</a>
|
|
37
|
-
<a class="underline underline-offset-4 hover:text-slate-900" href="tel:+971500000000">+971 50 000 0000</a>
|
|
38
|
-
<a class="underline underline-offset-4 hover:text-slate-900" href="#">linkedin.com/in/yourname</a>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<p class="max-w-3xl text-sm leading-7 text-slate-700">
|
|
44
|
-
I build scalable systems and clean user experiences. I prefer strict standards, predictable architecture,
|
|
45
|
-
and verification-first delivery — building products that feel premium and remain maintainable for years.
|
|
46
|
-
</p>
|
|
47
|
-
</header>
|
|
48
|
-
|
|
49
|
-
<div class="my-10 h-px bg-slate-200"></div>
|
|
50
|
-
|
|
51
|
-
<div class="grid gap-10 lg:grid-cols-12">
|
|
52
|
-
<!-- Main -->
|
|
53
|
-
<div class="lg:col-span-8 space-y-10">
|
|
54
|
-
<section>
|
|
55
|
-
<h2 class="text-xs font-semibold tracking-[0.25em] text-slate-500">EXPERIENCE</h2>
|
|
56
|
-
<div class="mt-6 space-y-8">
|
|
57
|
-
<article>
|
|
58
|
-
<div class="flex items-start justify-between gap-4">
|
|
59
|
-
<div>
|
|
60
|
-
<h3 class="text-lg font-medium">Senior Software Developer</h3>
|
|
61
|
-
<p class="text-sm text-slate-600">Global Aerospace Logistics Company</p>
|
|
62
|
-
</div>
|
|
63
|
-
<p class="text-sm text-slate-500">2023 — Present</p>
|
|
64
|
-
</div>
|
|
65
|
-
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-700">
|
|
66
|
-
<li><span class="font-medium">•</span> Led architecture decisions for internal platforms.</li>
|
|
67
|
-
<li><span class="font-medium">•</span> Built reusable UI patterns and shared components.</li>
|
|
68
|
-
<li><span class="font-medium">•</span> Reduced defects via verification and standards.</li>
|
|
69
|
-
</ul>
|
|
70
|
-
</article>
|
|
71
|
-
|
|
72
|
-
<article>
|
|
73
|
-
<div class="flex items-start justify-between gap-4">
|
|
74
|
-
<div>
|
|
75
|
-
<h3 class="text-lg font-medium">Software Developer</h3>
|
|
76
|
-
<p class="text-sm text-slate-600">HCL Technologies</p>
|
|
77
|
-
</div>
|
|
78
|
-
<p class="text-sm text-slate-500">2019 — 2023</p>
|
|
79
|
-
</div>
|
|
80
|
-
<ul class="mt-3 space-y-2 text-sm leading-7 text-slate-700">
|
|
81
|
-
<li><span class="font-medium">•</span> Delivered enterprise features with stable releases.</li>
|
|
82
|
-
<li><span class="font-medium">•</span> Improved reporting and data quality pipelines.</li>
|
|
83
|
-
</ul>
|
|
84
|
-
</article>
|
|
85
|
-
</div>
|
|
86
|
-
</section>
|
|
87
|
-
|
|
88
|
-
<section>
|
|
89
|
-
<h2 class="text-xs font-semibold tracking-[0.25em] text-slate-500">PROJECTS</h2>
|
|
90
|
-
<div class="mt-6 space-y-5">
|
|
91
|
-
<article class="rounded-xl border border-slate-200 p-5">
|
|
92
|
-
<div class="flex items-baseline justify-between gap-3">
|
|
93
|
-
<h3 class="text-base font-semibold">Ansiversa</h3>
|
|
94
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
95
|
-
</div>
|
|
96
|
-
<p class="mt-2 text-sm leading-7 text-slate-700">
|
|
97
|
-
Multi-app ecosystem with shared auth, shared UI components, and strict standards.
|
|
98
|
-
</p>
|
|
99
|
-
<div class="mt-3 flex flex-wrap gap-2">
|
|
100
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">Astro</span>
|
|
101
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">Alpine</span>
|
|
102
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">libSQL</span>
|
|
103
|
-
</div>
|
|
104
|
-
</article>
|
|
105
|
-
|
|
106
|
-
<article class="rounded-xl border border-slate-200 p-5">
|
|
107
|
-
<div class="flex items-baseline justify-between gap-3">
|
|
108
|
-
<h3 class="text-base font-semibold">Quiz Institute</h3>
|
|
109
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
110
|
-
</div>
|
|
111
|
-
<p class="mt-2 text-sm leading-7 text-slate-700">
|
|
112
|
-
Step-based quiz experience with dynamic metadata loading and result saving.
|
|
113
|
-
</p>
|
|
114
|
-
</article>
|
|
115
|
-
</div>
|
|
116
|
-
</section>
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
<!-- Sidebar -->
|
|
120
|
-
<aside class="lg:col-span-4 space-y-10">
|
|
121
|
-
<section>
|
|
122
|
-
<h2 class="text-xs font-semibold tracking-[0.25em] text-slate-500">SKILLS</h2>
|
|
123
|
-
<div class="mt-5 space-y-3 text-sm text-slate-700">
|
|
124
|
-
<div class="flex items-center justify-between">
|
|
125
|
-
<span>TypeScript</span><span class="text-slate-500">Advanced</span>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="flex items-center justify-between">
|
|
128
|
-
<span>System Design</span><span class="text-slate-500">Advanced</span>
|
|
129
|
-
</div>
|
|
130
|
-
<div class="flex items-center justify-between">
|
|
131
|
-
<span>Astro + Alpine</span><span class="text-slate-500">Advanced</span>
|
|
132
|
-
</div>
|
|
133
|
-
<div class="flex items-center justify-between">
|
|
134
|
-
<span>SQL</span><span class="text-slate-500">Intermediate</span>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
</section>
|
|
138
|
-
|
|
139
|
-
<section>
|
|
140
|
-
<h2 class="text-xs font-semibold tracking-[0.25em] text-slate-500">EDUCATION</h2>
|
|
141
|
-
<div class="mt-5 text-sm text-slate-700">
|
|
142
|
-
<div class="font-medium">B.E. / B.Tech — Computer Science</div>
|
|
143
|
-
<div class="text-slate-600">Your University Name</div>
|
|
144
|
-
<div class="text-slate-500">2015 — 2019</div>
|
|
145
|
-
</div>
|
|
146
|
-
</section>
|
|
147
|
-
|
|
148
|
-
<section>
|
|
149
|
-
<h2 class="text-xs font-semibold tracking-[0.25em] text-slate-500">CERTIFICATIONS</h2>
|
|
150
|
-
<ul class="mt-5 space-y-2 text-sm leading-7 text-slate-700">
|
|
151
|
-
<li>• AWS / Azure Fundamentals (Optional)</li>
|
|
152
|
-
<li>• Scrum / Agile (Optional)</li>
|
|
153
|
-
</ul>
|
|
154
|
-
</section>
|
|
155
|
-
</aside>
|
|
156
|
-
</div>
|
|
157
|
-
</section>
|
|
158
|
-
</main>
|
|
159
|
-
</body>
|
|
160
|
-
</html>
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Resume Template 4 - Executive Timeline</title>
|
|
7
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
-
<style>
|
|
9
|
-
@media print {
|
|
10
|
-
.no-print { display: none !important; }
|
|
11
|
-
a { text-decoration: none; color: inherit; }
|
|
12
|
-
body { background: white !important; }
|
|
13
|
-
}
|
|
14
|
-
</style>
|
|
15
|
-
</head>
|
|
16
|
-
<body class="bg-slate-100 text-slate-900">
|
|
17
|
-
<div class="no-print sticky top-0 z-10 border-b border-slate-200 bg-white/90 backdrop-blur">
|
|
18
|
-
<div class="mx-auto flex max-w-4xl items-center justify-between px-4 py-3">
|
|
19
|
-
<div class="text-sm text-slate-600">Template 4 — Executive Timeline</div>
|
|
20
|
-
<button class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50" onclick="window.print()">
|
|
21
|
-
Print / Save PDF
|
|
22
|
-
</button>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<main class="mx-auto max-w-4xl p-4 sm:p-6">
|
|
27
|
-
<section class="rounded-2xl bg-white p-7 sm:p-10 shadow-sm ring-1 ring-slate-200 print:shadow-none print:ring-0">
|
|
28
|
-
<header class="flex flex-col gap-5 sm:flex-row sm:items-end sm:justify-between">
|
|
29
|
-
<div>
|
|
30
|
-
<h1 class="text-3xl font-bold tracking-tight">Karthikeyan Ramalingam</h1>
|
|
31
|
-
<p class="mt-1 text-sm font-medium text-slate-700">Senior Software Developer</p>
|
|
32
|
-
<div class="mt-3 flex flex-wrap gap-2 text-xs text-slate-600">
|
|
33
|
-
<span class="rounded-full bg-slate-100 px-3 py-1">Abu Dhabi, UAE</span>
|
|
34
|
-
<span class="rounded-full bg-slate-100 px-3 py-1">you@email.com</span>
|
|
35
|
-
<span class="rounded-full bg-slate-100 px-3 py-1">+971 50 000 0000</span>
|
|
36
|
-
<span class="rounded-full bg-slate-100 px-3 py-1">linkedin.com/in/yourname</span>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<div class="rounded-xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-700 sm:max-w-sm">
|
|
41
|
-
<div class="text-xs font-semibold tracking-widest text-slate-500">SUMMARY</div>
|
|
42
|
-
<p class="mt-2 leading-6">
|
|
43
|
-
I build scalable products with strict standards, predictable architecture, and premium UX.
|
|
44
|
-
I prefer verification-first delivery and long-term maintainability.
|
|
45
|
-
</p>
|
|
46
|
-
</div>
|
|
47
|
-
</header>
|
|
48
|
-
|
|
49
|
-
<div class="my-8 h-px bg-slate-200"></div>
|
|
50
|
-
|
|
51
|
-
<div class="grid gap-10 lg:grid-cols-3">
|
|
52
|
-
<!-- Main timeline -->
|
|
53
|
-
<div class="lg:col-span-2">
|
|
54
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">EXPERIENCE</h2>
|
|
55
|
-
|
|
56
|
-
<div class="mt-6 space-y-8">
|
|
57
|
-
<!-- Timeline item -->
|
|
58
|
-
<div class="relative pl-6">
|
|
59
|
-
<div class="absolute left-0 top-1.5 h-full w-px bg-slate-200"></div>
|
|
60
|
-
<div class="absolute left-[-5px] top-1.5 h-3 w-3 rounded-full bg-slate-900"></div>
|
|
61
|
-
|
|
62
|
-
<div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between">
|
|
63
|
-
<div>
|
|
64
|
-
<h3 class="text-base font-semibold">Senior Software Developer</h3>
|
|
65
|
-
<p class="text-sm text-slate-700">Global Aerospace Logistics Company</p>
|
|
66
|
-
</div>
|
|
67
|
-
<p class="text-sm text-slate-600">2023 — Present</p>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
71
|
-
<li>Architected internal platforms to improve operational visibility and reliability.</li>
|
|
72
|
-
<li>Built a reusable UI system that reduced feature delivery time.</li>
|
|
73
|
-
<li>Strengthened production quality with standards and verification.</li>
|
|
74
|
-
</ul>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
<div class="relative pl-6">
|
|
78
|
-
<div class="absolute left-0 top-1.5 h-full w-px bg-slate-200"></div>
|
|
79
|
-
<div class="absolute left-[-5px] top-1.5 h-3 w-3 rounded-full bg-slate-900"></div>
|
|
80
|
-
|
|
81
|
-
<div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between">
|
|
82
|
-
<div>
|
|
83
|
-
<h3 class="text-base font-semibold">Software Developer</h3>
|
|
84
|
-
<p class="text-sm text-slate-700">HCL Technologies</p>
|
|
85
|
-
</div>
|
|
86
|
-
<p class="text-sm text-slate-600">2019 — 2023</p>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<ul class="mt-3 list-disc space-y-2 pl-5 text-sm leading-6 text-slate-700">
|
|
90
|
-
<li>Delivered enterprise modules with maintainable architecture and stable releases.</li>
|
|
91
|
-
<li>Improved reporting and data handling for business critical operations.</li>
|
|
92
|
-
</ul>
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
<div class="mt-10">
|
|
97
|
-
<h2 class="text-sm font-bold tracking-widest text-slate-900">PROJECTS</h2>
|
|
98
|
-
<div class="mt-5 space-y-4">
|
|
99
|
-
<div class="rounded-xl border border-slate-200 p-4">
|
|
100
|
-
<div class="flex items-baseline justify-between">
|
|
101
|
-
<h3 class="font-semibold">Ansiversa</h3>
|
|
102
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
103
|
-
</div>
|
|
104
|
-
<p class="mt-2 text-sm leading-6 text-slate-700">
|
|
105
|
-
Multi-app ecosystem with shared auth + shared UI components under strict standards.
|
|
106
|
-
</p>
|
|
107
|
-
</div>
|
|
108
|
-
<div class="rounded-xl border border-slate-200 p-4">
|
|
109
|
-
<div class="flex items-baseline justify-between">
|
|
110
|
-
<h3 class="font-semibold">Quiz Institute</h3>
|
|
111
|
-
<span class="text-xs text-slate-500">2024—Present</span>
|
|
112
|
-
</div>
|
|
113
|
-
<p class="mt-2 text-sm leading-6 text-slate-700">
|
|
114
|
-
Step-based quiz playthrough with dynamic metadata and results saving.
|
|
115
|
-
</p>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
</div>
|
|
120
|
-
|
|
121
|
-
<!-- Sidebar -->
|
|
122
|
-
<aside class="space-y-8">
|
|
123
|
-
<section class="rounded-xl border border-slate-200 p-4">
|
|
124
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">SKILLS</h2>
|
|
125
|
-
<div class="mt-3 flex flex-wrap gap-2">
|
|
126
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">TypeScript</span>
|
|
127
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">Astro</span>
|
|
128
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">Alpine</span>
|
|
129
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">SQL</span>
|
|
130
|
-
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs">Architecture</span>
|
|
131
|
-
</div>
|
|
132
|
-
</section>
|
|
133
|
-
|
|
134
|
-
<section class="rounded-xl border border-slate-200 p-4">
|
|
135
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">EDUCATION</h2>
|
|
136
|
-
<div class="mt-3 text-sm text-slate-700">
|
|
137
|
-
<div class="font-semibold">B.E. / B.Tech — CSE</div>
|
|
138
|
-
<div class="text-slate-600">Your University Name</div>
|
|
139
|
-
<div class="text-slate-500">2015 — 2019</div>
|
|
140
|
-
</div>
|
|
141
|
-
</section>
|
|
142
|
-
|
|
143
|
-
<section class="rounded-xl border border-slate-200 p-4">
|
|
144
|
-
<h2 class="text-xs font-bold tracking-widest text-slate-500">HIGHLIGHTS</h2>
|
|
145
|
-
<ul class="mt-3 space-y-2 text-sm leading-6 text-slate-700">
|
|
146
|
-
<li>• Premium design systems</li>
|
|
147
|
-
<li>• Verification-first delivery</li>
|
|
148
|
-
<li>• Maintainable architecture</li>
|
|
149
|
-
</ul>
|
|
150
|
-
</section>
|
|
151
|
-
</aside>
|
|
152
|
-
</div>
|
|
153
|
-
</section>
|
|
154
|
-
</main>
|
|
155
|
-
</body>
|
|
156
|
-
</html>
|
|
File without changes
|