|
3 | 3 | @using DotNetDevLottery.Models |
4 | 4 | @using Microsoft.AspNetCore.Components.Forms |
5 | 5 |
|
6 | | -<FluentDialog @bind-Hidden="@isHidden" Modal="true" TrapFocus="true" @ondialogdismiss="OnDialogDismiss"> |
7 | | - <DialogHeader> |
8 | | - <FluentStack Orientation="Orientation.Horizontal"> |
9 | | - <FluentLabel Typo="Typography.PaneHeader">볼 디자인 설정</FluentLabel> |
10 | | - </FluentStack> |
11 | | - </DialogHeader> |
12 | | - <DialogBody> |
13 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 1.5rem;"> |
14 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
15 | | - <FluentLabel Style="font-weight: 600;">일반 볼 이미지 업로드</FluentLabel> |
16 | | - <InputFile OnChange="@(e => OnBallImageSelected(e, false))" accept="image/*" class="file-input" /> |
17 | | - @if (!string.IsNullOrEmpty(settings.BallImageUrl)) |
18 | | - { |
19 | | - <FluentStack Orientation="Orientation.Horizontal" Style="align-items: center; gap: 1rem; padding: 0.5rem; background: var(--neutral-layer-2); border-radius: 4px;"> |
20 | | - <img src="@settings.BallImageUrl" alt="볼 이미지 미리보기" style="width: 60px; height: 60px; object-fit: contain; border-radius: 4px;" /> |
21 | | - <FluentButton Appearance="Appearance.Lightweight" OnClick="@(() => ClearImage(false))">삭제</FluentButton> |
22 | | - </FluentStack> |
23 | | - } |
24 | | - </FluentStack> |
25 | | - |
26 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
27 | | - <FluentLabel Style="font-weight: 600;">당첨 볼 이미지 업로드</FluentLabel> |
28 | | - <InputFile OnChange="@(e => OnBallImageSelected(e, true))" accept="image/*" class="file-input" /> |
29 | | - @if (!string.IsNullOrEmpty(settings.DrawedBallImageUrl)) |
30 | | - { |
31 | | - <FluentStack Orientation="Orientation.Horizontal" Style="align-items: center; gap: 1rem; padding: 0.5rem; background: var(--neutral-layer-2); border-radius: 4px;"> |
32 | | - <img src="@settings.DrawedBallImageUrl" alt="당첨 볼 이미지 미리보기" style="width: 60px; height: 60px; object-fit: contain; border-radius: 4px;" /> |
33 | | - <FluentButton Appearance="Appearance.Lightweight" OnClick="@(() => ClearImage(true))">삭제</FluentButton> |
34 | | - </FluentStack> |
35 | | - } |
36 | | - </FluentStack> |
37 | | - |
38 | | - <FluentDivider Style="width: 100%;" /> |
39 | | - <FluentLabel Style="text-align: center; color: var(--neutral-foreground-hint);">또는 색상 사용</FluentLabel> |
40 | | - |
41 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
42 | | - <FluentLabel Style="font-weight: 600;">일반 볼 색상</FluentLabel> |
43 | | - <input type="color" @bind="@settings.BallColor" style="width: 100%; height: 40px; border: 1px solid var(--neutral-stroke-rest); border-radius: 4px; cursor: pointer;" /> |
44 | | - </FluentStack> |
45 | | - |
46 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
47 | | - <FluentLabel Style="font-weight: 600;">일반 볼 테두리 색상</FluentLabel> |
48 | | - <input type="color" @bind="@settings.BallBorderColor" style="width: 100%; height: 40px; border: 1px solid var(--neutral-stroke-rest); border-radius: 4px; cursor: pointer;" /> |
49 | | - </FluentStack> |
50 | | - |
51 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
52 | | - <FluentLabel Style="font-weight: 600;">당첨 볼 색상</FluentLabel> |
53 | | - <input type="color" @bind="@settings.DrawedBallColor" style="width: 100%; height: 40px; border: 1px solid var(--neutral-stroke-rest); border-radius: 4px; cursor: pointer;" /> |
54 | | - </FluentStack> |
55 | | - |
56 | | - <FluentStack Orientation="Orientation.Vertical" Style="gap: 0.5rem;"> |
57 | | - <FluentLabel Style="font-weight: 600;">당첨 볼 텍스트 색상</FluentLabel> |
58 | | - <input type="color" @bind="@settings.DrawedBallTextColor" style="width: 100%; height: 40px; border: 1px solid var(--neutral-stroke-rest); border-radius: 4px; cursor: pointer;" /> |
59 | | - </FluentStack> |
60 | | - </FluentStack> |
61 | | - </DialogBody> |
62 | | - <DialogFooter> |
63 | | - <FluentButton Appearance="Appearance.Neutral" OnClick="OnCancel">취소</FluentButton> |
64 | | - <FluentButton Appearance="Appearance.Accent" OnClick="OnSave">저장</FluentButton> |
65 | | - </DialogFooter> |
| 6 | +<FluentDialog @bind-Hidden="@isHidden" Modal="true" TrapFocus="true" @ondialogdismiss="OnDialogDismiss" class="!p-0 !rounded-3xl !border-0 !shadow-2xl overflow-hidden"> |
| 7 | + <div class="flex flex-col h-full bg-white w-full"> |
| 8 | + <!-- Header --> |
| 9 | + <div class="px-6 py-5 border-b border-gray-100 flex items-center justify-between"> |
| 10 | + <h2 class="text-xl font-bold text-gray-800 m-0">볼 디자인 설정</h2> |
| 11 | + <button @onclick="OnCancel" class="text-gray-400 hover:text-gray-600 transition-colors p-1 rounded-full hover:bg-gray-100"> |
| 12 | + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> |
| 13 | + </button> |
| 14 | + </div> |
| 15 | + |
| 16 | + <!-- Body --> |
| 17 | + <div class="p-6 overflow-y-auto max-h-[70vh]"> |
| 18 | + <div class="flex flex-col gap-8"> |
| 19 | + <!-- Image Upload Section --> |
| 20 | + <div class="flex flex-col gap-6"> |
| 21 | + <div class="flex flex-col gap-3"> |
| 22 | + <label class="text-sm font-bold text-gray-700">일반 볼 이미지</label> |
| 23 | + <div class="relative group"> |
| 24 | + <InputFile OnChange="@(e => OnBallImageSelected(e, false))" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10" /> |
| 25 | + <div class="flex items-center justify-center p-4 border-2 border-dashed border-gray-200 rounded-xl bg-gray-50 transition-all group-hover:border-primary/50 group-hover:bg-primary/5"> |
| 26 | + <span class="text-sm text-gray-500 group-hover:text-primary font-medium">Click to upload image</span> |
| 27 | + </div> |
| 28 | + </div> |
| 29 | + @if (!string.IsNullOrEmpty(settings.BallImageUrl)) |
| 30 | + { |
| 31 | + <div class="flex items-center gap-4 p-3 bg-gray-50 rounded-xl border border-gray-100"> |
| 32 | + <img src="@settings.BallImageUrl" alt="Preview" class="w-12 h-12 object-contain rounded-lg bg-white shadow-sm" /> |
| 33 | + <div class="flex-1 min-w-0"> |
| 34 | + <p class="text-xs text-gray-400 font-mono truncate">Selected Image</p> |
| 35 | + </div> |
| 36 | + <button @onclick="@(() => ClearImage(false))" class="text-xs font-bold text-red-500 hover:bg-red-50 px-3 py-1.5 rounded-lg transition-colors"> |
| 37 | + 삭제 |
| 38 | + </button> |
| 39 | + </div> |
| 40 | + } |
| 41 | + </div> |
| 42 | + |
| 43 | + <div class="flex flex-col gap-3"> |
| 44 | + <label class="text-sm font-bold text-gray-700">당첨 볼 이미지</label> |
| 45 | + <div class="relative group"> |
| 46 | + <InputFile OnChange="@(e => OnBallImageSelected(e, true))" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10" /> |
| 47 | + <div class="flex items-center justify-center p-4 border-2 border-dashed border-gray-200 rounded-xl bg-gray-50 transition-all group-hover:border-primary/50 group-hover:bg-primary/5"> |
| 48 | + <span class="text-sm text-gray-500 group-hover:text-primary font-medium">Click to upload image</span> |
| 49 | + </div> |
| 50 | + </div> |
| 51 | + @if (!string.IsNullOrEmpty(settings.DrawedBallImageUrl)) |
| 52 | + { |
| 53 | + <div class="flex items-center gap-4 p-3 bg-gray-50 rounded-xl border border-gray-100"> |
| 54 | + <img src="@settings.DrawedBallImageUrl" alt="Preview" class="w-12 h-12 object-contain rounded-lg bg-white shadow-sm" /> |
| 55 | + <div class="flex-1 min-w-0"> |
| 56 | + <p class="text-xs text-gray-400 font-mono truncate">Selected Image</p> |
| 57 | + </div> |
| 58 | + <button @onclick="@(() => ClearImage(true))" class="text-xs font-bold text-red-500 hover:bg-red-50 px-3 py-1.5 rounded-lg transition-colors"> |
| 59 | + 삭제 |
| 60 | + </button> |
| 61 | + </div> |
| 62 | + } |
| 63 | + </div> |
| 64 | + </div> |
| 65 | + |
| 66 | + <div class="relative py-2"> |
| 67 | + <div class="absolute inset-0 flex items-center"> |
| 68 | + <div class="w-full border-t border-gray-200"></div> |
| 69 | + </div> |
| 70 | + <div class="relative flex justify-center text-sm"> |
| 71 | + <span class="px-4 bg-white text-gray-500 font-medium">또는 색상 직접 지정</span> |
| 72 | + </div> |
| 73 | + </div> |
| 74 | + |
| 75 | + <!-- Color Config Section --> |
| 76 | + <div class="grid grid-cols-2 gap-4"> |
| 77 | + <div class="flex flex-col gap-2"> |
| 78 | + <label class="text-xs font-bold text-gray-600 uppercase tracking-wide">일반 볼 색상</label> |
| 79 | + <div class="flex items-center gap-2 p-1.5 border border-gray-200 rounded-xl bg-white focus-within:ring-2 focus-within:ring-primary/20 transition-shadow"> |
| 80 | + <input type="color" @bind="@settings.BallColor" class="w-8 h-8 rounded cursor-pointer border-0 p-0" /> |
| 81 | + <span class="text-xs font-mono text-gray-500">@settings.BallColor</span> |
| 82 | + </div> |
| 83 | + </div> |
| 84 | + |
| 85 | + <div class="flex flex-col gap-2"> |
| 86 | + <label class="text-xs font-bold text-gray-600 uppercase tracking-wide">테두리 색상</label> |
| 87 | + <div class="flex items-center gap-2 p-1.5 border border-gray-200 rounded-xl bg-white focus-within:ring-2 focus-within:ring-primary/20 transition-shadow"> |
| 88 | + <input type="color" @bind="@settings.BallBorderColor" class="w-8 h-8 rounded cursor-pointer border-0 p-0" /> |
| 89 | + <span class="text-xs font-mono text-gray-500">@settings.BallBorderColor</span> |
| 90 | + </div> |
| 91 | + </div> |
| 92 | + |
| 93 | + <div class="flex flex-col gap-2"> |
| 94 | + <label class="text-xs font-bold text-gray-600 uppercase tracking-wide">당첨 볼 색상</label> |
| 95 | + <div class="flex items-center gap-2 p-1.5 border border-gray-200 rounded-xl bg-white focus-within:ring-2 focus-within:ring-primary/20 transition-shadow"> |
| 96 | + <input type="color" @bind="@settings.DrawedBallColor" class="w-8 h-8 rounded cursor-pointer border-0 p-0" /> |
| 97 | + <span class="text-xs font-mono text-gray-500">@settings.DrawedBallColor</span> |
| 98 | + </div> |
| 99 | + </div> |
| 100 | + |
| 101 | + <div class="flex flex-col gap-2"> |
| 102 | + <label class="text-xs font-bold text-gray-600 uppercase tracking-wide">텍스트 색상</label> |
| 103 | + <div class="flex items-center gap-2 p-1.5 border border-gray-200 rounded-xl bg-white focus-within:ring-2 focus-within:ring-primary/20 transition-shadow"> |
| 104 | + <input type="color" @bind="@settings.DrawedBallTextColor" class="w-8 h-8 rounded cursor-pointer border-0 p-0" /> |
| 105 | + <span class="text-xs font-mono text-gray-500">@settings.DrawedBallTextColor</span> |
| 106 | + </div> |
| 107 | + </div> |
| 108 | + </div> |
| 109 | + </div> |
| 110 | + </div> |
| 111 | + |
| 112 | + <!-- Footer --> |
| 113 | + <div class="px-6 py-4 bg-gray-50 border-t border-gray-100 flex justify-end gap-3 rounded-b-3xl"> |
| 114 | + <button @onclick="OnCancel" class="px-5 py-2.5 text-gray-600 font-bold bg-white border border-gray-200 rounded-xl hover:bg-gray-50 hover:border-gray-300 transition-all shadow-sm"> |
| 115 | + 취소 |
| 116 | + </button> |
| 117 | + <button @onclick="OnSave" class="px-5 py-2.5 bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-secondary)] text-white font-bold rounded-xl shadow-md hover:shadow-lg hover:-translate-y-0.5 transition-all"> |
| 118 | + 저장하기 |
| 119 | + </button> |
| 120 | + </div> |
| 121 | + </div> |
66 | 122 | </FluentDialog> |
67 | 123 |
|
68 | 124 | @code { |
|
0 commit comments