feat: 앨범 상세 UI 개선 - 소개 스크롤, 작사/작곡 자동변환, 타입별 개수 표시

This commit is contained in:
caadiq 2026-01-02 17:04:27 +09:00
parent d9d1a447c4
commit 3c06a20ea4
5 changed files with 28 additions and 16 deletions

View file

@ -1,8 +1,10 @@
services:
# 프론트엔드 - Vite 개발 서버
fromis9-web:
fromis9-frontend:
image: node:20-alpine
container_name: fromis9-web
container_name: fromis9-frontend
labels:
- "com.centurylinklabs.watchtower.enable=false"
working_dir: /app
command: sh -c "npm install && npm run dev -- --host 0.0.0.0 --port 80"
volumes:

View file

@ -1,7 +1,9 @@
services:
fromis9-web:
build: .
container_name: fromis9-web
container_name: fromis9-frontend
labels:
- "com.centurylinklabs.watchtower.enable=false"
env_file:
- .env
networks:

View file

@ -279,11 +279,13 @@ function AlbumDetail() {
className="col-span-1"
>
<h2 className="text-xl font-bold mb-4">앨범 소개</h2>
<div className="bg-white rounded-2xl shadow-lg p-6">
<p className="text-gray-600 leading-relaxed text-sm whitespace-pre-line">
<div className="bg-white rounded-2xl shadow-lg overflow-hidden">
<div className="max-h-[460px] overflow-y-auto p-6">
<p className="text-gray-600 leading-relaxed text-sm whitespace-pre-line text-justify break-all">
{album.description}
</p>
</div>
</div>
</motion.div>
)}

View file

@ -35,11 +35,12 @@ function Discography() {
return titleTrack ? titleTrack.title : tracks[0].title;
};
//
// (album_type_short )
const getAlbumType = (album) => album.album_type_short || album.album_type;
const albumStats = {
정규: albums.filter(a => a.album_type === '정규').length,
미니: albums.filter(a => a.album_type === '미니').length,
싱글: albums.filter(a => a.album_type === '싱글').length,
정규: albums.filter(a => getAlbumType(a) === '정규').length,
미니: albums.filter(a => getAlbumType(a) === '미니').length,
싱글: albums.filter(a => getAlbumType(a) === '싱글').length,
: albums.length
};

View file

@ -456,8 +456,14 @@ function AdminAlbumForm() {
};
const updateTrack = (index, field, value) => {
// // '' ( ) ', '
let processedValue = value;
if (['lyricist', 'composer', 'arranger'].includes(field)) {
processedValue = value.replace(/[|]/g, ', ');
}
setTracks(prev => prev.map((track, i) =>
i === index ? { ...track, [field]: value } : track
i === index ? { ...track, [field]: processedValue } : track
));
};
@ -746,7 +752,7 @@ function AdminAlbumForm() {
name="description"
value={formData.description}
onChange={handleInputChange}
rows={4}
rows={8}
className="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent resize-none"
placeholder="앨범에 대한 설명을 입력하세요..."
/>
@ -830,7 +836,7 @@ function AdminAlbumForm() {
value={track.duration || ''}
onChange={(e) => updateTrack(index, 'duration', e.target.value)}
className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-center"
placeholder="3:30"
placeholder="0:00"
/>
</div>
</div>
@ -857,7 +863,6 @@ function AdminAlbumForm() {
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.2 }}
className="overflow-hidden"
>
{/* 작사/작곡/편곡 */}
<div className="space-y-3 mt-3">
@ -912,7 +917,7 @@ function AdminAlbumForm() {
value={track.lyrics || ''}
onChange={(e) => updateTrack(index, 'lyrics', e.target.value)}
rows={12}
className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent resize-y min-h-[200px]"
className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent resize-none min-h-[200px]"
placeholder="가사를 입력하세요..."
/>
</div>