-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] : 네온 나이트 다크 테마 적용 (#179) #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,9 @@ | ||
| name: Tagging Songs | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: "0 14 * * *" # 한국 시간 23:00 실행 (UTC+9 → UTC 14:00) | ||
| workflow_dispatch: | ||
| # schedule: | ||
| # - cron: "0 14 * * *" # 한국 시간 23:00 실행 (UTC+9 → UTC 14:00) | ||
| # workflow_dispatch: | ||
|
Comment on lines
3
to
+6
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. 3. Workflow triggers removed .github/workflows/tagging_song.yml now has an on: key with no actual events (only comments), so the workflow has no valid trigger and will be rejected/disabled by GitHub Actions. This stops the scheduled/manual song-tagging automation entirely. Agent Prompt
|
||
|
|
||
| permissions: | ||
| contents: write # push 권한을 위해 필요 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "name": "web", | ||
| "version": "2.3.0", | ||
| "version": "2.4.0", | ||
| "type": "module", | ||
| "private": true, | ||
| "scripts": { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"> | ||
| <url><loc>https://www.singcode.kr</loc><lastmod>2026-03-30T15:15:37.869Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url> | ||
| <url><loc>https://www.singcode.kr</loc><lastmod>2026-04-05T15:20:24.064Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url> | ||
| </urlset> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,61 @@ | ||
| 'use client'; | ||
|
|
||
| import { CalendarCheck, MessageCircleQuestion } from 'lucide-react'; | ||
| import { CalendarCheck, MessageCircleQuestion, Moon, Sun } from 'lucide-react'; | ||
| import { useTheme } from 'next-themes'; | ||
| import { useRouter } from 'next/navigation'; | ||
| import { useState } from 'react'; | ||
| import { type ReactNode, useEffect, useRef, useState } from 'react'; | ||
|
|
||
| import { Button } from '@/components/ui/button'; | ||
| import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog'; | ||
| import { Dialog, DialogContent } from '@/components/ui/dialog'; | ||
| import { useUserQuery } from '@/queries/userQuery'; | ||
|
|
||
| import Sidebar from './Sidebar'; | ||
| import CheckInModal from './components/CheckInModal'; | ||
|
|
||
| type ExpandedButton = 'theme' | 'checkin' | 'contact' | null; | ||
|
|
||
| interface ExpandableButtonProps { | ||
| buttonKey: ExpandedButton; | ||
| expanded: ExpandedButton; | ||
| label: string; | ||
| icon: ReactNode; | ||
| disabled?: boolean; | ||
| onClick: () => void; | ||
| } | ||
|
|
||
| function ExpandableButton({ | ||
| buttonKey, | ||
| expanded, | ||
| label, | ||
| icon, | ||
| disabled, | ||
| onClick, | ||
| }: ExpandableButtonProps) { | ||
| const isExpanded = expanded === buttonKey; | ||
|
|
||
| return ( | ||
| <Button | ||
| variant="outline" | ||
| size={isExpanded ? 'default' : 'icon'} | ||
| className="dark:hover:bg-primary dark:hover:text-primary-foreground transition-all" | ||
| disabled={disabled} | ||
| onClick={onClick} | ||
| > | ||
| {icon} | ||
| {isExpanded && label} | ||
| </Button> | ||
|
Comment on lines
+37
to
+46
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. 2. Buttons missing glow effect Updated buttons (e.g., the new ExpandableButton and other outline buttons) add hover color changes but do not add a glow (box-shadow/filter) in active/hover states. This falls short of the requirement that buttons (in addition to active tabs) display a subtle neon glow. Agent Prompt
|
||
| ); | ||
| } | ||
|
|
||
| export default function Header() { | ||
| const [open, setOpen] = useState(false); | ||
| const [expanded, setExpanded] = useState<ExpandedButton>(null); | ||
| const { theme, setTheme } = useTheme(); | ||
| const headerRef = useRef<HTMLDivElement>(null); | ||
|
|
||
| const router = useRouter(); | ||
|
|
||
| const { data: user, isLoading, error } = useUserQuery(); | ||
| const { data: user, isLoading } = useUserQuery(); | ||
|
|
||
| const lastCheckIn = user?.last_check_in ?? new Date(); | ||
|
|
||
|
|
@@ -30,23 +69,58 @@ export default function Header() { | |
| setOpen(false); | ||
| }; | ||
|
|
||
| const handleExpandableClick = (key: ExpandedButton, action: () => void) => { | ||
| if (expanded === key) { | ||
| action(); | ||
| setExpanded(null); | ||
| } else { | ||
| setExpanded(key); | ||
| } | ||
| }; | ||
|
|
||
| useEffect(() => { | ||
| const handleClickOutside = (e: MouseEvent) => { | ||
| if (headerRef.current && !headerRef.current.contains(e.target as Node)) { | ||
| setExpanded(null); | ||
| } | ||
| }; | ||
| document.addEventListener('mousedown', handleClickOutside); | ||
| return () => document.removeEventListener('mousedown', handleClickOutside); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <header className="bg-background sticky top-0 z-50 flex h-16 w-full max-w-md items-center justify-between p-4 shadow-sm"> | ||
| <header className="bg-background sticky top-0 z-50 flex h-16 w-full max-w-md items-center justify-between border-b p-4"> | ||
| <div | ||
| className="font-barcode hover:text-accent cursor-pointer text-5xl transition-colors" | ||
| onClick={() => router.push('/')} | ||
| > | ||
| SINGCODE | ||
| </div> | ||
| <div className="flex items-center gap-2"> | ||
| <Dialog open={open} onOpenChange={setOpen}> | ||
| <DialogTrigger asChild> | ||
| <Button variant="outline" className="justify-start" disabled={isLoading}> | ||
| <CalendarCheck className="h-4 w-4" /> | ||
| 출석체크 | ||
| </Button> | ||
| </DialogTrigger> | ||
| <div ref={headerRef} className="flex items-center gap-2"> | ||
| <ExpandableButton | ||
| buttonKey="theme" | ||
| expanded={expanded} | ||
| label={theme === 'dark' ? '라이트 모드' : '다크 모드'} | ||
| icon={ | ||
| <span className="relative h-4 w-4"> | ||
| <Sun className="absolute h-4 w-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" /> | ||
| <Moon className="absolute h-4 w-4 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" /> | ||
| </span> | ||
| } | ||
| onClick={() => | ||
| handleExpandableClick('theme', () => setTheme(theme === 'dark' ? 'light' : 'dark')) | ||
| } | ||
| /> | ||
|
Comment on lines
+100
to
+113
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. 1. Header exposes light mode toggle The updated Header adds a prominent theme toggle that enables switching to Light Mode, so Light Mode is not removed/minimized as required. This undermines the requirement that the Neon/Night experience be primarily dark by default with Light Mode not prominently available. Agent Prompt
|
||
|
|
||
| <ExpandableButton | ||
| buttonKey="checkin" | ||
| expanded={expanded} | ||
| label="출석체크" | ||
| icon={<CalendarCheck className="h-4 w-4" />} | ||
| disabled={isLoading} | ||
| onClick={() => handleExpandableClick('checkin', () => setOpen(true))} | ||
| /> | ||
| <Dialog open={open} onOpenChange={setOpen}> | ||
| <DialogContent> | ||
| <CheckInModal | ||
| lastCheckIn={lastCheckIn} | ||
|
|
@@ -56,10 +130,13 @@ export default function Header() { | |
| </DialogContent> | ||
| </Dialog> | ||
|
|
||
| <Button variant="outline" className="justify-start" onClick={() => handleClickContact()}> | ||
| <MessageCircleQuestion className="h-4 w-4" /> | ||
| 문의 | ||
| </Button> | ||
| <ExpandableButton | ||
| buttonKey="contact" | ||
| expanded={expanded} | ||
| label="문의" | ||
| icon={<MessageCircleQuestion className="h-4 w-4" />} | ||
| onClick={() => handleExpandableClick('contact', handleClickContact)} | ||
| /> | ||
|
|
||
| <Sidebar /> | ||
| </div> | ||
|
|
||
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.
2. Workflow has no triggers
🐞 Bug☼ ReliabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools