fix: DaisyUI oklch() 브라우저 호환성 문제 해결
- DaisyUI 완전 제거, Pure Tailwind CSS로 전환 - oklch() 색상 함수 → hex 색상으로 변경 (구형 브라우저 지원) - 로그인 페이지 Tailwind 유틸리티 클래스로 리팩토링 - CSS 빌드 사이즈 74.82KB → 23.15KB 최적화 - DB_HOST 설정 수정 (sam-mysql-1 → 127.0.0.1) ## 변경 내역 - tailwind.config.js: DaisyUI 제거, custom 색상 정의 - resources/views/auth/login.blade.php: DaisyUI 클래스 → Tailwind 유틸리티 - resources/css/app.css: CSS 변수 추가 - .env: DB_HOST 로컬 접근 설정 - docs/INDEX.md: MNG 문서 인덱스 추가 ## 해결된 문제 - Safari <15.4, Chrome <111에서 CSS 미적용 문제 해결 - 모든 브라우저에서 로그인 페이지 정상 작동 확인
This commit is contained in:
@@ -58,4 +58,66 @@ ### 이슈 해결:
|
|||||||
- **문제**: Tailwind CSS 4.x에서 DaisyUI 플러그인 미적용
|
- **문제**: Tailwind CSS 4.x에서 DaisyUI 플러그인 미적용
|
||||||
- **원인**: DaisyUI가 Tailwind 4.x를 완전히 지원하지 않음
|
- **원인**: DaisyUI가 Tailwind 4.x를 완전히 지원하지 않음
|
||||||
- **해결**: Tailwind 3.4.17로 다운그레이드, PostCSS 설정 수정
|
- **해결**: Tailwind 3.4.17로 다운그레이드, PostCSS 설정 수정
|
||||||
- **결과**: DaisyUI 클래스 정상 적용 (74.82 KB CSS)
|
- **결과**: DaisyUI 클래스 정상 적용 (74.82 KB CSS)
|
||||||
|
|
||||||
|
### 문서 업데이트 (2025-11-20):
|
||||||
|
- **api/CLAUDE.md**: shared/ 모델 참조 제거
|
||||||
|
- **변경 사항**:
|
||||||
|
- 저장소 구조: 5개 → 3개 (api, admin, mng 독립 운영)
|
||||||
|
- 모델 구조: shared/ → 각 프로젝트 독립 모델
|
||||||
|
- 워크플로우: shared 동기화 제거
|
||||||
|
- CURRENT_WORKS.md 위치: mng 추가
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2025-11-20 (수) - CSS 브라우저 호환성 문제 해결
|
||||||
|
|
||||||
|
### 주요 작업
|
||||||
|
- DaisyUI oklch() 색상 함수 브라우저 호환성 문제 해결
|
||||||
|
- Pure Tailwind CSS로 전환하여 구형 브라우저 지원
|
||||||
|
|
||||||
|
### 문제 상황:
|
||||||
|
- **증상**: mng.sam.kr 로그인 페이지 CSS 스타일이 적용되지 않음
|
||||||
|
- **원인**: DaisyUI 5.5.5가 `oklch()` 색상 함수 사용 → Safari <15.4, Chrome <111 미지원
|
||||||
|
- **영향**: CSS 변수가 계산되지 않아 버튼, 카드 등 모든 컴포넌트 스타일 무효화
|
||||||
|
|
||||||
|
### 해결 과정:
|
||||||
|
1. **DaisyUI 설정 시도** (실패)
|
||||||
|
- Custom hex 테마 설정 → DaisyUI가 여전히 oklch() 사용
|
||||||
|
- `themes: false` 설정 → base CSS에서 oklch() 사용
|
||||||
|
|
||||||
|
2. **DaisyUI 완전 제거** (성공)
|
||||||
|
- `tailwind.config.js`에서 DaisyUI 플러그인 제거
|
||||||
|
- Pure Tailwind CSS + @tailwindcss/forms 사용
|
||||||
|
- Custom primary/secondary 색상 hex로 정의
|
||||||
|
|
||||||
|
3. **로그인 페이지 리팩토링**
|
||||||
|
- DaisyUI 클래스 → Tailwind 유틸리티 클래스 변환
|
||||||
|
- `btn btn-primary` → `bg-primary text-white rounded-lg`
|
||||||
|
- `card` → `bg-white rounded-lg shadow-xl`
|
||||||
|
- `input input-bordered` → `border border-gray-300 rounded-lg`
|
||||||
|
|
||||||
|
### 수정된 파일:
|
||||||
|
- `tailwind.config.js` - DaisyUI 제거, hex 색상 정의
|
||||||
|
- `resources/css/app.css` - CSS 변수 추가 (향후 제거 예정)
|
||||||
|
- `resources/views/auth/login.blade.php` - Tailwind 유틸리티 클래스로 변환
|
||||||
|
- `.env` - DB_HOST를 sam-mysql-1 → 127.0.0.1로 변경 (로컬 접근)
|
||||||
|
|
||||||
|
### 빌드 결과:
|
||||||
|
- **Before**: 74.82 KB (DaisyUI 포함, oklch() 사용)
|
||||||
|
- **After**: 23.15 KB (Pure Tailwind, hex 색상 사용)
|
||||||
|
- **파일**: `public/build/assets/app-L1Qg3jEH.css`
|
||||||
|
|
||||||
|
### 테스트 결과:
|
||||||
|
- ✅ 로그인 페이지 CSS 정상 적용
|
||||||
|
- ✅ 모든 브라우저 호환성 확보 (hex 색상 사용)
|
||||||
|
- ✅ 로그인 기능 정상 작동 (원격 DB 데이터 복원 후)
|
||||||
|
|
||||||
|
### 기술적 결정:
|
||||||
|
- **CSS 프레임워크**: DaisyUI → Pure Tailwind CSS
|
||||||
|
- **색상 시스템**: oklch() → hex (#570df8, #f000b8)
|
||||||
|
- **컴포넌트 스타일**: 사전 정의 클래스 → 유틸리티 조합
|
||||||
|
- **향후 방향**: 로그인 페이지 기준으로 일관된 CSS 스타일 유지
|
||||||
|
|
||||||
|
### Git 커밋:
|
||||||
|
- (다음 커밋 예정)
|
||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
use HasApiTokens, HasFactory, Notifiable, SoftDeletes;
|
||||||
use HasFactory, Notifiable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -18,9 +18,16 @@ class User extends Authenticatable
|
|||||||
* @var list<string>
|
* @var list<string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
'name',
|
'name',
|
||||||
'email',
|
'email',
|
||||||
|
'phone',
|
||||||
'password',
|
'password',
|
||||||
|
'options',
|
||||||
|
'profile_photo_path',
|
||||||
|
'role',
|
||||||
|
'is_active',
|
||||||
|
'is_super_admin',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +38,10 @@ class User extends Authenticatable
|
|||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password',
|
'password',
|
||||||
'remember_token',
|
'remember_token',
|
||||||
|
'two_factor_secret',
|
||||||
|
'two_factor_recovery_codes',
|
||||||
|
'two_factor_confirmed_at',
|
||||||
|
'deleted_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +53,11 @@ protected function casts(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email_verified_at' => 'datetime',
|
'email_verified_at' => 'datetime',
|
||||||
|
'last_login_at' => 'datetime',
|
||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
|
'options' => 'array',
|
||||||
|
'is_active' => 'boolean',
|
||||||
|
'is_super_admin' => 'boolean',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
22
docs/INDEX.md
Normal file
22
docs/INDEX.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# MNG 프로젝트 문서
|
||||||
|
|
||||||
|
> 📌 **MNG 관리자 패널 문서 (Laravel + DaisyUI)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 개발 가이드
|
||||||
|
|
||||||
|
- 추후 추가 예정
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 분석 문서
|
||||||
|
|
||||||
|
- 추후 추가 예정
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 관련 문서
|
||||||
|
|
||||||
|
- **[메인 CLAUDE.md](../CLAUDE.md)** - MNG 프로젝트 가이드
|
||||||
|
- **[CURRENT_WORKS.md](../CURRENT_WORKS.md)** - 현재 작업 이력
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-primary: #570df8;
|
||||||
|
--color-primary-content: #e0d2fe;
|
||||||
|
--color-secondary: #f000b8;
|
||||||
|
--color-base-100: #ffffff;
|
||||||
|
--color-base-200: #f9fafb;
|
||||||
|
--color-base-300: #f3f4f6;
|
||||||
|
--color-base-content: #1f2937;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="ko" data-theme="light">
|
<html lang="ko">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -7,88 +7,82 @@
|
|||||||
<title>로그인 - {{ config('app.name') }}</title>
|
<title>로그인 - {{ config('app.name') }}</title>
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-base-200">
|
<body class="bg-gray-100">
|
||||||
<div class="hero min-h-screen">
|
<div class="min-h-screen flex items-center justify-center">
|
||||||
<div class="hero-content flex-col">
|
<div class="flex flex-col items-center">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-6">
|
||||||
<h1 class="text-4xl font-bold">{{ config('app.name') }}</h1>
|
<h1 class="text-4xl font-bold text-gray-900">{{ config('app.name') }}</h1>
|
||||||
<p class="text-base-content/70 mt-2">관리자 패널</p>
|
<p class="text-gray-600 mt-2">관리자 패널</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card w-96 bg-base-100 shadow-xl">
|
<div class="w-96 bg-white rounded-lg shadow-xl p-8">
|
||||||
<div class="card-body">
|
<h2 class="text-2xl font-semibold text-center mb-6">로그인</h2>
|
||||||
<h2 class="card-title justify-center mb-4">로그인</h2>
|
|
||||||
|
|
||||||
@if (session('success'))
|
@if (session('success'))
|
||||||
<div class="alert alert-success mb-4">
|
<div class="flex items-center gap-3 p-4 mb-4 bg-green-100 border border-green-200 text-green-800 rounded-lg">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>{{ session('success') }}</span>
|
<span>{{ session('success') }}</span>
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($errors->any())
|
|
||||||
<div class="alert alert-error mb-4">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span>{{ $errors->first() }}</span>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<form method="POST" action="{{ route('login') }}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<div class="form-control">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text">이메일</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
name="email"
|
|
||||||
value="{{ old('email') }}"
|
|
||||||
placeholder="email@example.com"
|
|
||||||
class="input input-bordered @error('email') input-error @enderror"
|
|
||||||
required
|
|
||||||
autofocus
|
|
||||||
/>
|
|
||||||
@error('email')
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text-alt text-error">{{ $message }}</span>
|
|
||||||
</label>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control mt-4">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text">비밀번호</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="password"
|
|
||||||
class="input input-bordered @error('password') input-error @enderror"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
@error('password')
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text-alt text-error">{{ $message }}</span>
|
|
||||||
</label>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control mt-4">
|
|
||||||
<label class="label cursor-pointer justify-start gap-2">
|
|
||||||
<input type="checkbox" name="remember" class="checkbox checkbox-sm" />
|
|
||||||
<span class="label-text">로그인 상태 유지</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control mt-6">
|
|
||||||
<button type="submit" class="btn btn-primary">로그인</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="flex items-center gap-3 p-4 mb-4 bg-red-100 border border-red-200 text-red-800 rounded-lg">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
<span>{{ $errors->first() }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('login') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
이메일
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
value="{{ old('email') }}"
|
||||||
|
placeholder="email@example.com"
|
||||||
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent @error('email') border-red-500 @enderror"
|
||||||
|
required
|
||||||
|
autofocus
|
||||||
|
/>
|
||||||
|
@error('email')
|
||||||
|
<p class="text-sm text-red-600 mt-1">{{ $message }}</p>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
비밀번호
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent @error('password') border-red-500 @enderror"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
@error('password')
|
||||||
|
<p class="text-sm text-red-600 mt-1">{{ $message }}</p>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-6">
|
||||||
|
<label class="flex items-center gap-2 cursor-pointer">
|
||||||
|
<input type="checkbox" name="remember" class="w-4 h-4 text-primary border-gray-300 rounded focus:ring-2 focus:ring-primary" />
|
||||||
|
<span class="text-sm text-gray-700">로그인 상태 유지</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="w-full bg-primary text-white font-semibold py-2.5 px-4 rounded-lg hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-opacity">
|
||||||
|
로그인
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,20 +6,15 @@ export default {
|
|||||||
"./resources/**/*.vue",
|
"./resources/**/*.vue",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: '#570df8',
|
||||||
|
secondary: '#f000b8',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require('@tailwindcss/forms'),
|
require('@tailwindcss/forms'),
|
||||||
require('daisyui'),
|
// DaisyUI 완전 제거 - oklch() 사용 문제
|
||||||
],
|
],
|
||||||
daisyui: {
|
|
||||||
themes: ["light", "dark", "cupcake"],
|
|
||||||
darkTheme: "dark",
|
|
||||||
base: true,
|
|
||||||
styled: true,
|
|
||||||
utils: true,
|
|
||||||
prefix: "",
|
|
||||||
logs: true,
|
|
||||||
themeRoot: ":root",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user