Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
486 changes: 485 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.12.0",
"vaul": "^1.1.2",
"zustand": "^5.0.10"
},
"devDependencies": {
Expand Down
12 changes: 11 additions & 1 deletion src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom'
import {
BrowserRouter,
Routes,
Route,
Navigate,
Outlet,
} from 'react-router-dom'
import { ManagerHomePage } from '@/pages/manager/home'
import { SocialPage } from '@/pages/manager/social'
import { SocialChatPage } from '@/pages/manager/social-chat'
import { LoginPage } from '@/pages/login'
import { SignupPage } from '@/pages/signup'
import { JobLookupMapPage } from '@/pages/user/job-lookup-map'
Expand Down Expand Up @@ -43,6 +51,8 @@ export function App() {
<Route path="/job-lookup-map" element={<JobLookupMapPage />} />
<Route path="/home" element={<UserHomePage />} />
<Route path="/manager/home" element={<ManagerHomePage />} />
<Route path="/manager/social" element={<SocialPage />} />
<Route path="/manager/social/chat" element={<SocialChatPage />} />
</Route>

<Route path="/" element={<Navigate to="/login" replace />} />
Expand Down
3 changes: 3 additions & 0 deletions src/assets/icons/Plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/alba/Bookmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/assets/icons/alba/Calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/icons/alba/Clock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/assets/icons/alba/Thumbsup.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/icons/camera.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/chevron-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/icons/image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/icons/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/socialvector.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/features/social/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { AlbaFindDrawer, type AlbaFindDrawerProps } from './ui/AlbaFindDrawer'
export { DrawerPeekStrip } from './ui/DrawerPeekStrip'
63 changes: 63 additions & 0 deletions src/features/social/ui/AlbaFindDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useState } from 'react'

import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerTitle,
} from '@/features/social/ui/drawer'
import {
AlbaFindCategoryBar,
type AlbaFindFilterId,
type AlbaFindMode,
} from '@/shared/ui/manager/alba-find/AlbaFindCategoryBar'
import { AlbaFindList } from '@/shared/ui/manager/alba-find/AlbaFindList'
import {
Albabox,
type AlbaboxProps,
} from '@/shared/ui/manager/alba-find/Albabox'
Comment on lines +16 to +18
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix unresolved Albabox import (currently breaks TypeScript build).

Line 18 imports @/shared/ui/manager/alba-find/Albabox, but CI reports TS2307 for this module. Please align the import path/casing with the actual file/export name so tsc can resolve it on case-sensitive environments.

🧰 Tools
🪛 GitHub Actions: CI

[error] 18-18: TypeScript (tsc) build failed: TS2307 Cannot find module '@/shared/ui/manager/alba-find/Albabox' or its corresponding type declarations.

🪛 GitHub Check: quality

[failure] 18-18:
Cannot find module '@/shared/ui/manager/alba-find/Albabox' or its corresponding type declarations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/social/ui/AlbaFindDrawer.tsx` around lines 16 - 18, The import
for Albabox and AlbaboxProps in AlbaFindDrawer.tsx is unresolved (TS2307);
update the import path/casing to match the actual exported module name and file
location so TypeScript can resolve it — locate the import statement that
references '@/shared/ui/manager/alba-find/Albabox' and correct it to the exact
file/export name (e.g., adjust folder name, filename casing, or export name)
that actually exports Albabox and AlbaboxProps so the build succeeds.

Comment on lines +16 to +18
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Albabox가 없어요 뭘까요


export type AlbaFindDrawerProps = {
open: boolean
onOpenChange: (open: boolean) => void
jobs: AlbaboxProps[]
}

export function AlbaFindDrawer({
open,
onOpenChange,
jobs,
}: AlbaFindDrawerProps) {
const [mode, setMode] = useState<AlbaFindMode>('nearby')
const [activeFilter, setActiveFilter] = useState<AlbaFindFilterId>('sort')

return (
<Drawer open={open} onOpenChange={onOpenChange}>
<DrawerContent className="flex max-h-[90vh] flex-col gap-0 p-0">
<div className="sr-only">
<DrawerTitle>알바 찾기</DrawerTitle>
<DrawerDescription>
주변 또는 지역 기준으로 알바 공고를 확인할 수 있습니다.
</DrawerDescription>
</div>

<div className="shrink-0 px-4 pb-4 pt-1">
<AlbaFindCategoryBar
mode={mode}
onModeChange={setMode}
activeFilter={activeFilter}
onFilterChange={setActiveFilter}
/>
</div>

<div className="flex min-h-0 flex-1 flex-col">
<AlbaFindList className="px-4 pb-6">
{jobs.map((job, index) => (
<Albabox key={`${job.title}-${index}`} {...job} />
))}
</AlbaFindList>
</div>
</DrawerContent>
</Drawer>
)
}
16 changes: 16 additions & 0 deletions src/features/social/ui/DrawerHandleBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export type DrawerHandleBarProps = {
className?: string
size?: 'sm' | 'md'
}

export function DrawerHandleBar({
className,
size = 'md',
}: DrawerHandleBarProps) {
return (
<div
className={`mx-auto shrink-0 rounded-full bg-line-2 ${size === 'sm' ? 'h-1.5 w-10' : 'h-2 w-[100px]'} ${className ?? ''}`.trim()}
aria-hidden
/>
)
}
82 changes: 82 additions & 0 deletions src/features/social/ui/DrawerPeekStrip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useRef, type PointerEvent } from 'react'

import { DrawerHandleBar } from './DrawerHandleBar'

type DrawerPeekStripProps = {
show: boolean
onRequestOpen: () => void
dragThresholdPx?: number
}

export function DrawerPeekStrip({
show,
onRequestOpen,
dragThresholdPx = 40,
}: DrawerPeekStripProps) {
const dragRef = useRef<{ pointerId: number; startY: number } | null>(null)

const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {
dragRef.current = {
pointerId: event.pointerId,
startY: event.clientY,
}
event.currentTarget.setPointerCapture(event.pointerId)
}

const handlePointerMove = (event: PointerEvent<HTMLDivElement>) => {
if (!dragRef.current || dragRef.current.pointerId !== event.pointerId)
return
const deltaUp = dragRef.current.startY - event.clientY
if (deltaUp >= dragThresholdPx) {
onRequestOpen()
dragRef.current = null
try {
event.currentTarget.releasePointerCapture(event.pointerId)
} catch {
// noop
}
}
}

const endDrag = (event: PointerEvent<HTMLDivElement>) => {
if (!dragRef.current || dragRef.current.pointerId !== event.pointerId)
return
dragRef.current = null
try {
event.currentTarget.releasePointerCapture(event.pointerId)
} catch {
// noop
}
}

if (!show) return null

return (
<div
className="fixed inset-x-0 bottom-0 z-30 cursor-grab touch-none select-none active:cursor-grabbing"
onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerUp={endDrag}
onPointerCancel={endDrag}
role="button"
tabIndex={0}
aria-label="손잡이를 누른 채 위로 드래그하여 패널 열기"
onKeyDown={event => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault()
onRequestOpen()
}
}}
>
<div className="mx-auto max-w-lg rounded-t-[12px] border border-b-0 border-line-2 bg-white px-4 pb-0 pt-3 shadow-[0_-8px_24px_rgba(0,0,0,0.08)]">
<div className="flex flex-col items-center">
<DrawerHandleBar size="sm" className="bg-[#dcdcdc]" />
<div
className="mt-2.5 h-2 w-full rounded-t-[4px] bg-bg-dark"
aria-hidden
/>
</div>
</div>
</div>
)
}
112 changes: 112 additions & 0 deletions src/features/social/ui/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import * as React from 'react'
import { Drawer as DrawerPrimitive } from 'vaul'

import { DrawerHandleBar } from './DrawerHandleBar'

const Drawer = ({
shouldScaleBackground = true,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
<DrawerPrimitive.Root
shouldScaleBackground={shouldScaleBackground}
{...props}
/>
)
Drawer.displayName = 'Drawer'

const DrawerTrigger = DrawerPrimitive.Trigger

const DrawerPortal = DrawerPrimitive.Portal

const DrawerClose = DrawerPrimitive.Close

const DrawerOverlay = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={`fixed inset-0 z-50 bg-black/80 ${className ?? ''}`.trim()}
{...props}
/>
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName

const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={`fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto max-h-[96vh] flex-col rounded-t-[10px] border border-line-2 bg-white ${className ?? ''}`.trim()}
{...props}
>
<div className="mt-4">
<DrawerHandleBar size="md" />
</div>
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
))
DrawerContent.displayName = 'DrawerContent'

const DrawerHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={`grid gap-1.5 p-4 text-center sm:text-left ${className ?? ''}`.trim()}
{...props}
/>
)
DrawerHeader.displayName = 'DrawerHeader'

const DrawerFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={`mt-auto flex flex-col gap-2 p-4 ${className ?? ''}`.trim()}
{...props}
/>
)
DrawerFooter.displayName = 'DrawerFooter'

const DrawerTitle = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={`typography-headline03 text-text-100 ${className ?? ''}`.trim()}
{...props}
/>
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName

const DrawerDescription = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={`typography-body02-regular text-text-70 ${className ?? ''}`.trim()}
{...props}
/>
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName

export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
}
Loading
Loading