Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/feat/#72'
Browse files Browse the repository at this point in the history
  • Loading branch information
kanguk01 committed Nov 15, 2024
2 parents fe1e805 + 31e0745 commit 18bf475
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 42 deletions.
136 changes: 136 additions & 0 deletions src/components/common/Notification/Notification.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/** @jsxImportSource @emotion/react */
import { useState, useEffect } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { X, CheckCircle, AlertCircle, Info } from 'lucide-react'
import styled from '@emotion/styled'
import { css } from '@emotion/react'

type NotificationType = 'success' | 'error' | 'info'

interface NotificationProps {
type: NotificationType
message: string
duration?: number
onClose?: () => void
}

const iconMap = {
success: CheckCircle,
error: AlertCircle,
info: Info,
}

const bgColorMap = {
success: '#38A169', // Green
error: '#E53E3E', // Red
info: '#3182CE', // Blue
}

// Styled components
const NotificationContainer = styled(motion.div)<{ type: NotificationType }>`
position: fixed;
top: 16px;
right: 16px;
z-index: 50;
width: 100%;
max-width: 24rem;
overflow: hidden;
border-radius: 0.375rem;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
background-color: ${({ type }) => bgColorMap[type]};
`

const NotificationContent = styled.div`
padding: 1rem;
display: flex;
align-items: start;
`

const IconContainer = styled.div`
flex-shrink: 0;
`

const MessageContainer = styled.div`
margin-left: 0.75rem;
width: 0;
flex-grow: 1;
padding-top: 0.125rem;
`

const CloseButton = styled.button`
margin-left: 1rem;
display: inline-flex;
color: white;
transition: color 0.2s;
&:hover {
color: #e2e8f0; // Light gray on hover
}
&:focus {
outline: none;
box-shadow: 0 0 0 2px white;
}
`

const srOnly = css`
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
`

export default function Notification({
type,
message,
duration = 5000,
onClose,
}: NotificationProps) {
const [isVisible, setIsVisible] = useState(true)

useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(false)
onClose && onClose()
}, duration)

return () => clearTimeout(timer)
}, [duration, onClose])

const Icon = iconMap[type]

return (
<AnimatePresence>
{isVisible && (
<NotificationContainer
type={type}
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -50 }}
>
<NotificationContent>
<IconContainer>
<Icon className="h-6 w-6" color="white" />
</IconContainer>
<MessageContainer>
<p style={{ fontSize: '0.875rem', fontWeight: 500, color: 'white' }}>{message}</p>
</MessageContainer>
<CloseButton
onClick={() => {
setIsVisible(false)
onClose && onClose()
}}
>
<span css={srOnly}>Close</span>
<X className="h-5 w-5" />
</CloseButton>
</NotificationContent>
</NotificationContainer>
)}
</AnimatePresence>
)
}
31 changes: 28 additions & 3 deletions src/components/features/CustomCalendar/CustomCalendar.styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { css } from "@emotion/react";

import breakpoints from "@/variants/breakpoints";
export const appContainerStyles = css`
margin: 0 auto;
padding-bottom: 0.4rem;
Expand All @@ -15,16 +15,41 @@ export const calendarStyles = css`
display: flex;
flex-direction: column;
width: 100%;
height: calc(100vh - 6.4rem - 40px);
height: calc(100vh - 6.4rem - 30px);
min-height: 400px;
max-height: 720px;
font-size: 0.7rem;
.fc-scroller {
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.3);
}
&::-webkit-scrollbar-thumb:hover {
background-color: rgba(0, 0, 0, 0.5);
}
&::-webkit-scrollbar-track {
background-color: rgba(0, 0, 0, 0.1);
}
}
.fc-toolbar {
flex-direction: row;
align-items: center;
${breakpoints.mobile}{
flex-direction: column;
}
}
.fc-toolbar-chunk {
margin-bottom: 0.5rem;
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion src/components/features/CustomCalendar/CustomCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ const CustomCalendar: React.FC<CustomCalendarProps> = ({
dayMaxEvents
weekends
firstDay={1}
timeZone="UTC"
timeZone="KST"
events={parsedEvents}
viewDidMount={({ view }) => setCurrentView(view.type)}
datesSet={(dateInfo) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ export const ButtonContainer = styled(motion.button)`
&:focus {
outline: none;
}
`;

export const Circle = styled(motion.ellipse)`
fill: #2196f3;
filter: drop-shadow(0px 4px 6px rgba(0, 0, 0, 0.2));
width: 58px;
height: 58px;
export const CircleBackground = styled.div`
width: 54px;
height: 54px;
border-radius: 50%;
background-color: #2196f3;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
position: absolute;
`;

export const MicrophoneIcon = styled(motion.g)`
Expand Down
40 changes: 14 additions & 26 deletions src/components/features/MicrophoneButton/MicrophoneButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// src/components/features/MicrophoneButton/MicrophoneButton.tsx
import React from "react";
import { AnimatePresence } from "framer-motion";
import { Mic } from "lucide-react"; // Lucide에서 mic 아이콘 가져오기
import {
ButtonContainer,
Circle,
MicrophoneIcon,
CircleBackground,
WaveContainer,
Wave,
} from "./MicrophoneButton.styles";
Expand All @@ -22,29 +21,18 @@ const MicrophoneButton: React.FC<MicrophoneButtonProps> = ({
}) => {
return (
<ButtonContainer onClick={isRecording ? onStopClick : onStartClick}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 92.045 90"
fill="none"
overflow="visible"
>
<Circle cx="46.0225" cy="45" rx="46.0225" ry="45" />
<AnimatePresence>
{!isRecording && (
<MicrophoneIcon
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
>
{/* 마이크 아이콘 경로 */}
<path d="M58.5 42.5C58.5 49.4 52.9 55 46 55C39.1 55 33.5 49.4 33.5 42.5H28.5C28.5 51.325 35.025 58.575 43.5 59.8V67.5H48.5V59.8C56.975 58.575 63.5 51.325 63.5 42.5H58.5Z" />
<path d="M46 50C50.15 50 53.5 46.65 53.5 42.5V27.5C53.5 23.35 50.15 20 46 20C41.85 20 38.5 23.35 38.5 27.5V42.5C38.5 46.65 41.85 50 46 50ZM43.5 27.5C43.5 26.125 44.625 25 46 25C47.375 25 48.5 26.125 48.5 27.5V42.5C48.5 43.875 47.375 45 46 45C44.625 45 43.5 43.875 43.5 42.5V27.5Z" />
<path d="M46 50C50.15 50 53.5 46.65 53.5 42.5V27.5C53.5 23.35 50.15 20 46 20C41.85 20 38.5 23.35 38.5 27.5V42.5C38.5 46.65 41.85 50 46 50Z" />
</MicrophoneIcon>
)}
</AnimatePresence>
</svg>
<CircleBackground /> {/* 원형 배경으로 사용할 div */}
<AnimatePresence>
{!isRecording && (
<Mic
color="white"
size={28}
style={{
position: "absolute",
}}
/>
)}
</AnimatePresence>
<AnimatePresence>
{isRecording && (
<WaveContainer
Expand Down
1 change: 1 addition & 0 deletions src/pages/Friend/FriendDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ const CommentItem = styled.div`
padding: 16px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #e5e7eb;
`;

const CommentContent = styled.div`
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Friend/FriendPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ const FriendItemContainer = styled.div`
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
}
border: 1px solid #e5e7eb;
${breakpoints.mobile} {
padding: 12px;
gap: 12px;
Expand Down
17 changes: 13 additions & 4 deletions src/pages/LoginModal/RedirectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import useAuth from "@/hooks/useAuth";
import RouterPath from "@/router/RouterPath";
import { apiClient } from "@/api/instance";

const OAuthRedirectHandler = () => {
const navigate = useNavigate();
Expand All @@ -21,15 +22,17 @@ const OAuthRedirectHandler = () => {
document.cookie = `access_token=${accessToken}; ${cookieOptions}`;
document.cookie = `refresh_token=${refreshToken}; ${cookieOptions}`;
document.cookie = `device_id=${deviceId}; ${cookieOptions}`;

apiClient.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
// 상태 업데이트

const newAuthState = {
isAuthenticated: true,
};
setAuthState(newAuthState);
localStorage.setItem("authState", JSON.stringify(newAuthState));
// axios 인스턴스 헤더에 토큰 추가
// apiClient.defaults.headers.common.Authorization = `Bearer ${accessToken}`;


} else {
// 토큰이 없으면 메인 페이지로 리다이렉트
navigate(RouterPath.HOME);
Expand All @@ -42,9 +45,15 @@ const OAuthRedirectHandler = () => {

// authState가 업데이트되었을 때 메인 페이지로 리다이렉트
useEffect(() => {
// console.log("현재 authState:", authState);
const cookieValue = document.cookie
.split("; ")
.find((row) => row.startsWith("access_token="))
?.split("=")[1];
console.log("현재 access_token:", cookieValue);
if (authState.isAuthenticated) {
navigate(RouterPath.MAIN);
setTimeout(() => {
navigate(RouterPath.MAIN);
}, 500); // 500ms 지연
}
}, [authState, navigate]);

Expand Down
3 changes: 2 additions & 1 deletion src/pages/Mypage/Mypage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ const Card = styled(motion.div)`
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15); /* hover:shadow-lg */
}
border: 1px solid #e5e7eb;
${breakpoints.mobile} {
padding: 16px;
margin-bottom: 12px;
}
`;

const ProfileCard = styled(motion.div)`
border: 1px solid #e5e7eb;
display: flex;
justify-content: space-between;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/TeamPlan/TeamPlan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const PlanCard = styled.div`
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
}
border: 1px solid #e5e7eb;
${breakpoints.mobile} {
padding: 16px;
flex-direction: row;
Expand Down

0 comments on commit 18bf475

Please sign in to comment.