Enhances achievements with images and confetti#45
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds a client-side ConfettiProvider and useConfetti hook, wires confetti triggers into AchievementsProvider and Footer, adds a required Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Footer as Footer (client)
participant Confetti as ConfettiProvider
participant Canvas as canvas-confetti
User->>Footer: Click "Kilian Tyler"
Footer->>Confetti: triggerConfettiFromCorners()
Note over Confetti: Check/throttle pending set (~1s)
Confetti->>Canvas: Fire left/right bursts (angles/origins)
Canvas-->>Confetti: Rendered
Confetti-->>Footer: Completed
sequenceDiagram
autonumber
participant App as UI
participant AchProv as AchievementsProvider
participant Toast as ToastSystem
participant Confetti as ConfettiProvider
participant Canvas as canvas-confetti
App->>AchProv: unlock(achievementId)
AchProv->>Toast: show unlocked toast
alt achievement.confetti && not pending
AchProv->>Confetti: triggerConfettiFromCorners()
Note over Confetti: Throttle pending id (~1s)
Confetti->>Canvas: Fire corner bursts
Canvas-->>Confetti: Rendered
else no confetti
Note over AchProv: No confetti triggered
end
AchProv-->>App: unlock complete
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (2)
src/images/pets/index.ts (1)
1-6: Same: avoid index.ts barrels; move to a concrete moduleRename to a non-index module (e.g.,
src/images/pets.ts) or import assets directly; update all imports accordingly.src/images/projects/index.ts (1)
1-5: Same: avoid index.ts barrels; move to a concrete moduleRename to a non-index module (e.g.,
src/images/projects.ts) or import assets directly; update all imports accordingly.
🧹 Nitpick comments (12)
package.json (2)
37-37: Move @types to devDependencies@types/canvas-confetti should be a devDependency to avoid bloating prod installs.
- "@types/canvas-confetti": "1.9.0", +And add under devDependencies:
"devDependencies": { + "@types/canvas-confetti": "1.9.0",
39-39: Optional: lazy‑load canvas-confetti to trim initial bundleImporting at module scope ships confetti on every page load. Consider dynamic import inside trigger methods.
-import confetti from 'canvas-confetti' +let _confetti: typeof import('canvas-confetti')['default'] | null = null +const getConfetti = async () => (_confetti ??= (await import('canvas-confetti')).default)Then replace calls like:
-void confetti({...}) +;(await getConfetti())({ ... })src/components/providers/confetti-provider.tsx (6)
1-1: Fix Prettier warningCI flagged formatting. Run prettier --write on this file.
18-24: Respect reduced‑motion usersAdd disableForReducedMotion to avoid triggering animations for users who prefer reduced motion.
const triggerConfetti = useCallback(() => { - void confetti({ + void confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 }, + disableForReducedMotion: true, }) }, [])
26-52: Remove unsupported props; add a11y flagx and y at top level are not confetti options (use origin). Also add disableForReducedMotion.
const leftCorner = { - x: 0, - y: 1, angle: 45, startVelocity: 55, spread: 90, particleCount: 50, origin: { x: 0, y: 1 }, + disableForReducedMotion: true, } const rightCorner = { - x: 1, - y: 1, angle: 135, startVelocity: 55, spread: 90, particleCount: 50, origin: { x: 1, y: 1 }, + disableForReducedMotion: true, }
62-77: Add reduced‑motion guard (top)Same rationale as above.
void confetti({ particleCount: 150, spread: 180, origin: { y: 0 }, angle: 270, startVelocity: 45, + disableForReducedMotion: true, })
79-93: Add reduced‑motion guard (center)Maintain consistency across triggers.
void confetti({ particleCount: 200, spread: 360, origin: { x: 0.5, y: 0.5 }, startVelocity: 30, + disableForReducedMotion: true, })
95-103: Optional: dedupe helper to DRY pending logicExtract a withDedupe(id, fn) to reduce repetition and centralize cleanup.
-const value = useMemo<ConfettiContextValue>( +const withDedupe = useCallback((id: string, fn: () => void) => { + if (pendingConfettiRef.current.has(id)) return + pendingConfettiRef.current.add(id) + fn() + setTimeout(() => pendingConfettiRef.current.delete(id), 1000) +}, []) + +const value = useMemo<ConfettiContextValue>( () => ({ - triggerConfetti, - triggerConfettiFromCorners, - triggerConfettiFromTop, - triggerConfettiFromCenter, + triggerConfetti, + triggerConfettiFromCorners: () => withDedupe('corners', () => { void confetti({ /* ... */ }) }), + triggerConfettiFromTop: () => withDedupe('top', () => { void confetti({ /* ... */ }) }), + triggerConfettiFromCenter: () => withDedupe('center', () => { void confetti({ /* ... */ }) }), }), - [triggerConfetti, triggerConfettiFromCorners, triggerConfettiFromTop, triggerConfettiFromCenter], + [triggerConfetti, withDedupe], )Note: Inline the specific options as shown in existing functions.
src/components/layout/footer.tsx (1)
11-19: Convert inline handler to named handler and set type="button"Aligns with guidelines (no inline handlers; handler prefix handle*). Prevents accidental form submit.
export function Footer() { - const { triggerConfettiFromCorners } = useConfetti() + const { triggerConfettiFromCorners } = useConfetti() + const handleNameClick = React.useCallback(() => { + triggerConfettiFromCorners() + }, [triggerConfettiFromCorners]) return ( ... - <button - onClick={() => { - triggerConfettiFromCorners() - }}> + <button type="button" onClick={handleNameClick} aria-label="Celebrate with confetti"> Kilian Tyler </button>src/app/about/head.tsx (1)
6-11: Preload budget: consider downsizing or using next/image priorityPreloading 6 images can be heavy. If only some appear above the fold, prefer next/image with priority or reduce to critical assets only.
src/components/layout/home/hero/profile-image.tsx (1)
159-168: Drop priority/eager on overlay to protect LCPThe overlay image sits above the themed base images; marking it priority/eager can regress LCP. Let it lazy-load unless absolutely needed on first paint.
Apply this diff:
<Image alt={imageAlt} src={imageSrc} className={`${isEnvDrivenVariant && !isImageLoaded ? 'opacity-0' : 'opacity-100'} rounded-lg transition-transform duration-500 ease-(--ease-fluid) translate-y-0 scale-100 transform-gpu group-hover:-translate-y-1 group-hover:scale-105`} - loading="eager" - priority + loading="lazy" fill sizes="(min-width: 1024px) 500px, 100vw" onLoad={() => setIsImageLoaded(true)} />src/components/providers/providers.tsx (1)
22-24: Provider order is correct; add reduced‑motion + lazy confetti loadConfettiProvider placement looks good. To reduce bundle cost and respect a11y, gate animations on prefers‑reduced‑motion and dynamically import canvas‑confetti inside the provider’s trigger functions.
Apply in src/components/providers/confetti-provider.tsx (illustrative):
- const triggerConfetti = useCallback(() => { - void confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }) - }, []) + const triggerConfetti = useCallback(() => { + if (typeof window === 'undefined') return + if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return + void import('canvas-confetti').then(m => + m.default({ particleCount: 100, spread: 70, origin: { y: 0.6 } }) + ) + }, [])Repeat the same pattern for fromCorners/fromTop/fromCenter.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (18)
package.json(1 hunks)src/app/about/head.tsx(1 hunks)src/components/layout/footer.tsx(1 hunks)src/components/layout/home/hero/profile-image.tsx(2 hunks)src/components/providers/achievements-provider.tsx(2 hunks)src/components/providers/confetti-provider.tsx(1 hunks)src/components/providers/providers.tsx(2 hunks)src/images/achievements/index.ts(1 hunks)src/images/headshot/index.ts(1 hunks)src/images/logos/index.ts(1 hunks)src/images/pets/index.ts(1 hunks)src/images/projects/index.ts(1 hunks)src/lib/achievements.ts(2 hunks)src/lib/experience.ts(4 hunks)src/lib/pets.ts(7 hunks)src/lib/projects.ts(6 hunks)src/lib/themes.ts(1 hunks)src/types/achievements.d.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,cjs,mjs}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
**/*.{ts,tsx,js,jsx,cjs,mjs}: Never hardcode or hallucinate the PostHog API key; always read it from the value populated in the .env file
Create new feature flag names that are clear and descriptive
Gate flag-dependent code on a check that verifies the flag’s values are valid and expected
If a custom property for a person or event is referenced in two or more files or in two or more callsites within the same file, centralize the property name in an enum (TS) or const object (JS)
Files:
src/components/providers/providers.tsxsrc/images/pets/index.tssrc/app/about/head.tsxsrc/images/headshot/index.tssrc/images/projects/index.tssrc/components/layout/home/hero/profile-image.tsxsrc/lib/pets.tssrc/images/logos/index.tssrc/components/layout/footer.tsxsrc/types/achievements.d.tssrc/components/providers/confetti-provider.tsxsrc/lib/projects.tssrc/lib/experience.tssrc/images/achievements/index.tssrc/lib/themes.tssrc/components/providers/achievements-provider.tsxsrc/lib/achievements.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/posthog-integration.mdc)
In TypeScript, store feature flag names in an enum with members written in UPPERCASE_WITH_UNDERSCORE and use a consistent naming convention
**/*.{ts,tsx}: Use Zod for schema validation (client and server)
Model expected errors as return values in Server Actions
Never use unknown or any; always use existing types or define explicit, specific types
Files:
src/components/providers/providers.tsxsrc/images/pets/index.tssrc/app/about/head.tsxsrc/images/headshot/index.tssrc/images/projects/index.tssrc/components/layout/home/hero/profile-image.tsxsrc/lib/pets.tssrc/images/logos/index.tssrc/components/layout/footer.tsxsrc/types/achievements.d.tssrc/components/providers/confetti-provider.tsxsrc/lib/projects.tssrc/lib/experience.tssrc/images/achievements/index.tssrc/lib/themes.tssrc/components/providers/achievements-provider.tsxsrc/lib/achievements.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Use early returns to simplify control flow and reduce nesting
Use descriptive variable and function names; event handlers prefixed with "handle" (e.g., handleClick, handleKeyDown)
Refactor large files into smaller modules; organize components in folders when refactoring
Standard.js: 2-space indentation; single quotes; no semicolons (unless required); no unused variables; space after keywords; === only; spaced infix operators; commas followed by a space; same-line else; curly braces for multi-line if; camelCase for vars/functions; PascalCase for constructors/React components
Minimize global styles; prefer modular or scoped styles and utility classes
Prioritize error handling and edge cases; use guard clauses and early returns; place happy path last; avoid unnecessary else by using if-return
Naming Convention: enforce consistent naming for files, types, and functions per project rules
Files:
src/components/providers/providers.tsxsrc/images/pets/index.tssrc/app/about/head.tsxsrc/images/headshot/index.tssrc/images/projects/index.tssrc/components/layout/home/hero/profile-image.tsxsrc/lib/pets.tssrc/images/logos/index.tssrc/components/layout/footer.tsxsrc/types/achievements.d.tssrc/components/providers/confetti-provider.tsxsrc/lib/projects.tssrc/lib/experience.tssrc/images/achievements/index.tssrc/lib/themes.tssrc/components/providers/achievements-provider.tsxsrc/lib/achievements.ts
**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.tsx: Use shadcn/ui (and Radix) as the foundation for UI components; install via shadcn CLI, do not create component files manually
Use shadcn/ui components for UI code
Files:
src/components/providers/providers.tsxsrc/app/about/head.tsxsrc/components/layout/home/hero/profile-image.tsxsrc/components/layout/footer.tsxsrc/components/providers/confetti-provider.tsxsrc/components/providers/achievements-provider.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{tsx,jsx}: Implement responsive design with Tailwind CSS; avoid custom style tags and prefer Tailwind utility classes
Add a11y attributes and keyboard handlers (aria-*, onKeyDown) to interactive elements
Use the function keyword for React component definitions (not arrow components for top-level components)
Follow React Hooks rules; use proper hooks (useState, useEffect, useContext, useReducer, useMemo, useCallback)
Extract reusable logic into custom hooks
Use React.memo for component memoization when appropriate
Use useCallback for functions passed as props to avoid unnecessary re-renders
Use useMemo for expensive computations
Avoid inline function definitions in render
Prefer composition over inheritance; use children and render props for flexibility
Use refs sparingly and mainly for DOM access
Prefer controlled components over uncontrolled for forms
Implement error boundaries to catch and handle UI errors
Use cleanup functions in useEffect to prevent memory leaks
Use short-circuit and ternaries for conditional rendering
Minimize 'use client' and client-side hooks; favor React Server Components in Next.js
Wrap client components in with a fallback
Use dynamic loading for non-critical components
Implement route-based code splitting in Next.js
Optimize images in UI: prefer WebP, include intrinsic size, and enable lazy loading when rendering
Use controlled components and client-side validation for forms; consider react-hook-form for complex forms
Provide user-friendly error messages and proper logging in UI paths
Use semantic HTML and proper ARIA attributes; ensure full keyboard navigation
Sanitize user inputs to prevent XSS; avoid dangerouslySetInnerHTML unless content is sanitized
Prefer named exports for components
Files:
src/components/providers/providers.tsxsrc/app/about/head.tsxsrc/components/layout/home/hero/profile-image.tsxsrc/components/layout/footer.tsxsrc/components/providers/confetti-provider.tsxsrc/components/providers/achievements-provider.tsx
**/index.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Do not create index.ts files; import from concrete module paths
Files:
src/images/pets/index.tssrc/images/headshot/index.tssrc/images/projects/index.tssrc/images/logos/index.tssrc/images/achievements/index.ts
🧬 Code graph analysis (3)
src/components/providers/providers.tsx (2)
src/components/providers/confetti-provider.tsx (1)
ConfettiProvider(15-106)src/components/providers/achievements-provider.tsx (1)
AchievementsProvider(56-293)
src/components/layout/footer.tsx (1)
src/components/providers/confetti-provider.tsx (1)
useConfetti(108-112)
src/components/providers/achievements-provider.tsx (2)
src/components/providers/confetti-provider.tsx (1)
useConfetti(108-112)src/lib/achievements.ts (1)
ACHIEVEMENTS(6-112)
🪛 GitHub Actions: Lint
src/components/providers/confetti-provider.tsx
[warning] 1-1: Prettier formatting issues found in 'src/components/providers/confetti-provider.tsx'. Run 'prettier --write' to fix.
🔇 Additional comments (12)
src/types/achievements.d.ts (1)
12-12: New required field: ensure all definitions are updatedconfetti is now required. Confirm all AchievementDefinition objects (e.g., in src/lib/achievements.ts) set this flag to avoid TS breaks at build.
src/components/providers/confetti-provider.tsx (1)
108-111: Providers order: verify ConfettiProvider wraps all consumersuseConfetti throws if missing provider. Confirm src/components/providers/providers.tsx includes ConfettiProvider above AchievementsProvider and Footer mounts under it.
src/lib/themes.ts (2)
1-1: LGTM — asset import consolidationNamespace import cleans up consumers and keeps assets centralized.
9-10: Verify assets exported from indexEnsure Headshots.Headshot, .Cyberpunk, .Halloween, .Thanksgiving exist in src/images/headshot/index.ts and are StaticImageData.
Also applies to: 16-17, 23-24, 30-31, 38-39
src/lib/projects.ts (2)
1-1: LGTM — projects images via namespaceConsistent with the new assets pattern.
14-15: Type check imageSrc typesConfirm Projects.* exports are StaticImageData to satisfy Project.imageSrc type.
Also applies to: 25-26, 37-38, 53-54, 63-64
src/lib/pets.ts (1)
1-1: LGTM — pets images via namespaceGood consolidation; alt text remains descriptive.
src/components/layout/home/hero/profile-image.tsx (1)
29-31: LGTM: typed variant-to-image mappingThe StaticImageData mapping via the namespace import is correct and keeps variant handling clean.
src/lib/experience.ts (1)
28-28: LGTM: logo assignments now reference consolidated exportsNamespace usage reads clearly and matches the typed structure.
Also applies to: 49-49, 70-70
src/lib/achievements.ts (1)
12-18: LGTM: image consolidation and confetti flagsSwitch to Images.* and explicit confetti booleans align with the provider’s behavior.
Also applies to: 24-29, 35-41, 47-52, 58-64, 70-75, 81-87, 93-98, 104-111
src/components/providers/achievements-provider.tsx (1)
114-141: Confetti gating and de‑dupe look good — provider nesting verified.
AchievementsProvider is only rendered inside in src/components/providers/providers.tsx (line 23); Providers is mounted in src/app/layout.tsx (lines 64–75).src/images/headshot/index.ts (1)
1-7: Remove barrel (src/images/headshot/index.ts) — import images from concrete pathsThis index.ts creates a barrel and violates the repo guideline "Do not create index.ts files; import from concrete module paths".
- Option A (preferred): remove this file and update callsites to import assets directly, e.g.
import Confused from '@/images/headshot/cartoon-confused.webp'.- Option B: if an aggregator is required, rename/create a concrete module like
src/images/headshot/headshots.tsand export the assets from there.Verified: index barrels exist at src/images/{achievements, headshot, logos, pets, projects}/index.ts and tsconfig.json maps
"@/*"→"./src/*". Automated search did not locate callsites; confirm usage and update imports accordingly.
| import Confused from '@/images/headshot/cartoon-confused.webp' | ||
| import Grumpy from '@/images/headshot/cartoon-grumpy.webp' | ||
| import Ladybird from '@/images/headshot/cartoon-ladybird.webp' | ||
| import * as Headshots from '@/images/headshot' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid barrel import (index.ts) per repo rule
Guideline says “Do not create index.ts files; import from concrete module paths.” Replace the barrel at @/images/headshot with a concrete module (e.g., a named module like @/images/headshot.ts or direct asset imports) and remove the underlying index.ts.
🤖 Prompt for AI Agents
In src/components/layout/home/hero/profile-image.tsx around line 6, the file
currently does a barrel import from '@/images/headshot' which violates the repo
rule against index.ts barrels; replace that line with concrete imports from the
actual module(s) (for example import specific named exports from
'@/images/headshot.ts' or import individual asset files like
'@/images/headshot.jpg' or '@/images/headshot.png' as used in this component),
adjust any references to Headshots.* to the new local names, and remove the
underlying index.ts barrel file from the images/headshot directory so future
imports must use the concrete module paths.
| export { default as AboutAmblerAchievement } from './about-ambler.webp' | ||
| export { default as ConfusedClickAchievement } from './confused-click.webp' | ||
| export { default as ExperienceExplorerAchievement } from './experience-explorer.webp' | ||
| export { default as GrumpyGlimpseAchievement } from './grumpy-glimpse.webp' | ||
| export { default as LadybirdLandingAchievement } from './ladybird-landing.webp' | ||
| export { default as PetParadeAchievement } from './pet-parade.webp' | ||
| export { default as PlaceholderAchievement } from './placeholder.webp' | ||
| export { default as ProjectsPeruserAchievement } from './projects-peruser.webp' | ||
| export { default as RecursiveRewardAchievement } from './recursive-reward.webp' | ||
| export { default as ThemeTapdanceAchievement } from './theme-tapdance.webp' | ||
| export { default as UnknownAchievement } from './unknown.webp' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
❓ Verification inconclusive
No index.ts per guidelines: switch to concrete imports or a named aggregator module
Same guideline applies here. Either import assets directly where used, or move these re-exports into a concrete file name (e.g., achievementImages.ts) and import via @/images/achievements/achievementImages.
If keeping an aggregator, create src/images/achievements/achievementImages.ts:
export { default as AboutAmblerAchievement } from './about-ambler.webp'
export { default as ConfusedClickAchievement } from './confused-click.webp'
export { default as ExperienceExplorerAchievement } from './experience-explorer.webp'
export { default as GrumpyGlimpseAchievement } from './grumpy-glimpse.webp'
export { default as LadybirdLandingAchievement } from './ladybird-landing.webp'
export { default as PetParadeAchievement } from './pet-parade.webp'
export { default as PlaceholderAchievement } from './placeholder.webp'
export { default as ProjectsPeruserAchievement } from './projects-peruser.webp'
export { default as RecursiveRewardAchievement } from './recursive-reward.webp'
export { default as ThemeTapdanceAchievement } from './theme-tapdance.webp'
export { default as UnknownAchievement } from './unknown.webp'Minor: Namespace barrels may reduce treeshaking; direct per-asset imports are safest for bundle size.
Remove the barrel index.ts — import assets directly or use a named aggregator
Per repo guideline, avoid index.ts barrels. Either import each .webp where used, or replace this barrel with a concrete module (e.g., src/images/achievements/achievementImages.ts).
Suggested aggregator (if keeping one):
export { default as AboutAmblerAchievement } from './about-ambler.webp'
export { default as ConfusedClickAchievement } from './confused-click.webp'
export { default as ExperienceExplorerAchievement } from './experience-explorer.webp'
export { default as GrumpyGlimpseAchievement } from './grumpy-glimpse.webp'
export { default as LadybirdLandingAchievement } from './ladybird-landing.webp'
export { default as PetParadeAchievement } from './pet-parade.webp'
export { default as PlaceholderAchievement } from './placeholder.webp'
export { default as ProjectsPeruserAchievement } from './projects-peruser.webp'
export { default as RecursiveRewardAchievement } from './recursive-reward.webp'
export { default as ThemeTapdanceAchievement } from './theme-tapdance.webp'
export { default as UnknownAchievement } from './unknown.webp'🤖 Prompt for AI Agents
In src/images/achievements/index.ts (lines 1-11) the file is an index barrel
exporting .webp assets which violates the repo guideline; remove this barrel or
replace it with a concrete aggregator module and update imports. Either delete
this index.ts and change all call sites to import the individual .webp files
directly, or rename the file to a specific module name (e.g.,
achievementImages.ts) that exports the same named assets, then search and update
all imports to reference the new module path (or the direct asset paths) so no
index barrel remains. Ensure all exports remain the same identifiers and run a
quick build to verify resolving paths.
| export { default as DraftKingsLogo } from './draftkings.webp' | ||
| export { default as NewInnovationsLogo } from './newinnov.webp' | ||
| export { default as QGendaLogo } from './qgenda.webp' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Do not use index.ts barrels in this repo
Per guidelines, replace this index.ts with a concrete module (e.g., src/images/logos.ts) or import assets directly where used. Update callers (e.g., src/lib/experience.ts) to the concrete path and remove this file.
List existing barrels to clean up:
🏁 Script executed:
#!/bin/bash
fd --glob 'index.ts' src/images -x ls -la {}Length of output: 381
Remove index.ts barrels under src/images and replace with concrete modules
Barrel files found: src/images/projects/index.ts, src/images/pets/index.ts, src/images/achievements/index.ts, src/images/logos/index.ts, src/images/headshot/index.ts. Replace each barrel with a concrete module (e.g., src/images/logos.ts) or import assets directly where used; update callers (e.g., src/lib/experience.ts) to the concrete paths and delete these index.ts files.
| import PlaceholderAchievement from '@/images/achievements/placeholder.webp' | ||
| import RecursiveRewardAchievement from '@/images/achievements/recursive-reward.webp' | ||
| import ThemeTapdanceAchievement from '@/images/achievements/theme-tapdance.webp' | ||
| import * as Images from '@/images/achievements' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid barrel import (index.ts) per repo rule
Replace @/images/achievements barrel with a concrete module path (e.g., src/images/achievements.ts) or import specific assets directly; remove the index.ts.
🤖 Prompt for AI Agents
In src/lib/achievements.ts around line 1, the code uses a barrel import "import
* as Images from '@/images/achievements'" which violates the repo rule; replace
this with a concrete module path or direct asset imports (for example import the
module file as "src/images/achievements.ts" or import specific assets like
"src/images/achievements/award.png" or "@/images/achievements/award.png"), and
remove or stop relying on the index.ts barrel export so imports reference
explicit files to enable clearer dependency tracking and tree-shaking.
| import draftKingsLogo from '@/images/logos/draftkings.webp' | ||
| import newInnovationsLogo from '@/images/logos/newinnov.webp' | ||
| import qgendaLogo from '@/images/logos/qgenda.webp' | ||
| import * as Logos from '@/images/logos' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid barrel import (index.ts) per repo rule
Replace @/images/logos barrel with a concrete module path (e.g., move exports to src/images/logos.ts or import the specific assets directly) and remove the index.ts.
🤖 Prompt for AI Agents
In src/lib/experience.ts around line 1, the file currently uses a barrel import
from "@/images/logos" which violates the repo rule; replace that barrel import
with a concrete module path by either (A) creating a single module file at
src/images/logos.ts that explicitly exports the required logo assets and import
from '@/images/logos.ts', or (B) import each required asset directly from their
true file paths (e.g., '@/images/logos/logoName.svg') and then remove the
index.ts barrel file from src/images so no barrel imports remain.
Adds images to achievements and introduces confetti effects upon unlocking certain achievements, enhancing the user experience.
index.tsfiles to keep code organized and clean.Summary by CodeRabbit