-
Notifications
You must be signed in to change notification settings - Fork 2
🏆 Transform Projects to Zenith Hall with Enhanced Branding #228
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 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,7 +58,7 @@ export default function Header() { | |
| { href: "/", label: "Home" }, | ||
| { href: "/about", label: "About" }, | ||
| { href: "/opportunities", label: "Opportunities" }, | ||
| { href: "/projects", label: "Projects" }, | ||
| { href: "/zenith-hall", label: "Zenith Hall" }, | ||
| { href: "/blog", label: "Blog" }, | ||
|
Comment on lines
+61
to
62
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 Add a redirect from Prevents 404s from bookmarks, SEO, and external refs. Add to module.exports = {
async redirects() {
return [
+ { source: '/projects', destination: '/zenith-hall', permanent: true },
+ { source: '/projects/:path*', destination: '/zenith-hall', permanent: true },
];
},
};
🤖 Prompt for AI Agents |
||
| { href: "/join", label: "Join Codeunia" }, | ||
| { href: "/contact", label: "Contact Us" }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,6 @@ | ||||||||||||||||||||||||||||||||||||
| import DOMPurify from 'dompurify'; | ||||||||||||||||||||||||||||||||||||
| import { JSDOM } from 'jsdom'; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Create a DOMPurify instance for server-side use | ||||||||||||||||||||||||||||||||||||
| const window = new JSDOM('').window; | ||||||||||||||||||||||||||||||||||||
| const purify = DOMPurify(window as any); | ||||||||||||||||||||||||||||||||||||
| import DOMPurify from 'isomorphic-dompurify'; | ||||||||||||||||||||||||||||||||||||
| // Works in both server and client without jsdom | ||||||||||||||||||||||||||||||||||||
| const purify = DOMPurify; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| export interface ValidationResult { | ||||||||||||||||||||||||||||||||||||
| isValid: boolean; | ||||||||||||||||||||||||||||||||||||
|
|
@@ -467,6 +464,10 @@ export function withInputValidation<T extends Record<string, unknown>>( | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| for (const [key, options] of Object.entries(schema)) { | ||||||||||||||||||||||||||||||||||||
| const value = body[key]; | ||||||||||||||||||||||||||||||||||||
| if (typeof value !== 'string') { | ||||||||||||||||||||||||||||||||||||
| errors.push(`${key}: must be a string`); | ||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+467
to
+470
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. Required-field regression: missing values now report “must be a string”. The new typeof check fires for undefined/null, masking “required” errors and changing API behavior. Let validateText handle required-ness for absent values; reserve the type error for non-string present values. Apply: - const value = body[key];
- if (typeof value !== 'string') {
- errors.push(`${key}: must be a string`);
- continue;
- }
- const result = InputValidator.validateText(value, options);
+ const raw = body[key];
+ if (raw === undefined || raw === null) {
+ // Let validateText emit required/empty errors as appropriate
+ const result = InputValidator.validateText('', options);
+ if (!result.isValid) errors.push(`${key}: ${result.error}`);
+ else validatedData[key as keyof T] = result.sanitizedValue as T[keyof T];
+ continue;
+ }
+ if (typeof raw !== 'string') {
+ errors.push(`${key}: must be a string`);
+ continue;
+ }
+ const result = InputValidator.validateText(raw, options);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| const result = InputValidator.validateText(value, options); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if (!result.isValid) { | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,20 @@ export function generateMetadata(config: SEOConfig): Metadata { | |
| creator: author, | ||
| publisher: defaultConfig.siteName, | ||
|
|
||
| // Favicon configuration | ||
| icons: { | ||
| icon: [ | ||
| { url: '/favicon.ico', type: 'image/x-icon' }, | ||
| { url: '/codeunia-favicon-light.svg', media: '(prefers-color-scheme: light)' }, | ||
| { url: '/codeunia-favicon-dark.svg', media: '(prefers-color-scheme: dark)' }, | ||
| { url: '/codeunia-favicon-light.svg' } | ||
| ], | ||
| apple: [ | ||
| { url: '/apple-touch-icon.png', sizes: '180x180', type: 'image/png' } | ||
| ], | ||
| shortcut: '/favicon.ico' | ||
| }, | ||
|
|
||
|
Comment on lines
+58
to
+71
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. 💡 Verification agent 🧩 Analysis chainAvoid duplicate favicon declarations and fix Apple touch icon format. You’re defining icons here and again in Apply: - // Favicon configuration
- icons: {
- icon: [
- { url: '/favicon.ico', type: 'image/x-icon' },
- { url: '/codeunia-favicon-light.svg', media: '(prefers-color-scheme: light)' },
- { url: '/codeunia-favicon-dark.svg', media: '(prefers-color-scheme: dark)' },
- { url: '/codeunia-favicon-light.svg' }
- ],
- apple: '/codeunia-favicon-light.svg',
- shortcut: '/favicon.ico'
- },
+ // Favicon configuration
+ icons: {
+ icon: [
+ { url: '/favicon.ico', type: 'image/x-icon' },
+ { url: '/codeunia-favicon-light.svg', media: '(prefers-color-scheme: light)' },
+ { url: '/codeunia-favicon-dark.svg', media: '(prefers-color-scheme: dark)' },
+ { url: '/codeunia-favicon-light.svg' }
+ ],
+ apple: [{ url: '/apple-touch-icon.png', sizes: '180x180' }],
+ shortcut: ['/favicon.ico']
+ },Verification script (checks files exist and flags duplicates in layout): 🏁 Script executed: #!/bin/bash
# Icons present?
fd -a 'favicon|apple-touch' --base-directory . public || true
# Check if layout also injects <link rel="icon"> (should be removed if using Metadata)
rg -n "rel=[\"']icon|apple-touch-icon|shortcut icon" app/layout.tsx -n || trueLength of output: 686 Consolidate favicon config and fix Apple touch icon
🤖 Prompt for AI Agents |
||
| // Open Graph | ||
| openGraph: { | ||
| type, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -60,6 +60,13 @@ const nextConfig: NextConfig = { | |||||||||||||||||||||||||
| compress: true, | ||||||||||||||||||||||||||
| poweredByHeader: false, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| async redirects() { | ||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||
| { source: '/projects', destination: '/zenith-hall', permanent: true }, | ||||||||||||||||||||||||||
| { source: '/projects/:path*', destination: '/zenith-hall', permanent: true }, | ||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+63
to
+69
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. Deep-link redirect drops path segments.
async redirects() {
return [
{ source: '/projects', destination: '/zenith-hall', permanent: true },
- { source: '/projects/:path*', destination: '/zenith-hall', permanent: true },
+ { source: '/projects/:path*', destination: '/zenith-hall/:path*', permanent: true },
];
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| async headers() { | ||||||||||||||||||||||||||
| const isDev = process.env.NODE_ENV === 'development' | ||||||||||||||||||||||||||
| const isProd = process.env.NODE_ENV === 'production' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
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.
🛠️ Refactor suggestion
Duplicate “Jobs” link (also under Career) — de-duplicate to avoid confusion.
You now have two items pointing to /protected/jobs (“Jobs” here and “Job Opportunities” under Career). Keep one to maintain IA clarity.
Apply one of:
or rename/retarget as needed.
📝 Committable suggestion
🤖 Prompt for AI Agents