feat: 파비콘 추가 (파란 배경 흰색 S) 및 noImplicitAny 타입 수정

- web/admin 양쪽 앱에 icon.svg, apple-icon.png, favicon.ico 추가
- Prisma .map() 콜백의 implicit any 타입 에러 수정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Johngreen
2026-03-30 07:56:01 +09:00
parent 012c7e0e1a
commit b4639e00cc
16 changed files with 23 additions and 15 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

+2 -2
View File
@@ -100,7 +100,7 @@ export default async function AdminContractsPage() {
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{contracts.map((c) => {
{contracts.map((c: (typeof contracts)[number]) => {
const statusInfo = STATUS_MAP[c.status] ?? {
label: c.status,
color: 'bg-gray-100 text-gray-700',
@@ -109,7 +109,7 @@ export default async function AdminContractsPage() {
label: c.escrowStatus,
color: 'bg-gray-100 text-gray-700',
};
const depositTx = c.escrowTransactions.find((t) => t.transactionType === 'DEPOSIT');
const depositTx = c.escrowTransactions.find((t: (typeof c.escrowTransactions)[number]) => t.transactionType === 'DEPOSIT');
const amount = depositTx ? Number(depositTx.amount) : 0;
return (
<tr key={c.publicId} className="hover:bg-gray-50">
@@ -39,7 +39,7 @@ export default async function AdminInvitePage() {
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
{invites.map((invite) => (
{invites.map((invite: (typeof invites)[number]) => (
<tr key={invite.id.toString()}>
<td className="px-4 py-2">{invite.email}</td>
<td className="px-4 py-2">{invite.role}</td>
+1 -1
View File
@@ -135,7 +135,7 @@ export default async function AdminStoresPage({
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{stores.map((store) => {
{stores.map((store: (typeof stores)[number]) => {
const statusInfo = STATUS_MAP[store.reviewStatus] ?? {
label: store.reviewStatus,
color: 'bg-gray-100 text-gray-700',
+2 -2
View File
@@ -96,14 +96,14 @@ export default async function AdminSubsidiesPage({
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{cases.map((c) => {
{cases.map((c: (typeof cases)[number]) => {
const statusInfo = STATUS_MAP[c.status] ?? {
label: c.status,
color: 'bg-gray-100 text-gray-700',
};
const totalItems = c.checklistItems.length;
const completedItems = c.checklistItems.filter(
(item) => item.status === 'CHECKED',
(item: (typeof c.checklistItems)[number]) => item.status === 'CHECKED',
).length;
return (
<tr key={c.publicId} className="hover:bg-gray-50">
+2 -2
View File
@@ -121,13 +121,13 @@ export default async function AdminVendorsPage({
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{vendors.map((vendor) => {
{vendors.map((vendor: (typeof vendors)[number]) => {
const statusInfo = STATUS_MAP[vendor.certificationStatus] ?? {
label: vendor.certificationStatus,
color: 'bg-gray-100 text-gray-700',
};
const regionNames = vendor.coverageRegions
.map((cr) => cr.region.nameKo)
.map((cr: (typeof vendor.coverageRegions)[number]) => cr.region.nameKo)
.filter(Boolean)
.join(', ');
return (
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

+1 -1
View File
@@ -87,7 +87,7 @@ export default async function ContractsPage() {
{contracts.length === 0 ? (
<p className="text-center text-sm text-gray-500"> </p>
) : (
contracts.map((contract) => {
contracts.map((contract: (typeof contracts)[number]) => {
const statusInfo = STATUS_MAP[contract.status] ?? {
label: contract.status,
color: 'bg-gray-100 text-gray-700',
+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<rect width="32" height="32" rx="6" fill="#2563EB"/>
<text x="16" y="24" font-family="Arial, Helvetica, sans-serif" font-size="24" font-weight="bold" fill="white" text-anchor="middle">S</text>
</svg>

After

Width:  |  Height:  |  Size: 288 B

+1 -1
View File
@@ -162,7 +162,7 @@ export default async function MatchingPage({
{requests.length === 0 ? (
<p className="text-center text-sm text-gray-500"> </p>
) : (
requests.map((req) => {
requests.map((req: (typeof requests)[number]) => {
const statusInfo = STATUS_LABELS[req.status] ?? {
label: req.status,
color: 'bg-gray-100 text-gray-700',
+1 -1
View File
@@ -61,7 +61,7 @@ export default async function StoresPage({
</div>
) : (
stores.map((store) => (
stores.map((store: (typeof stores)[number]) => (
<Link
key={store.publicId}
href={`/stores/${store.publicId}`}
+2 -2
View File
@@ -142,13 +142,13 @@ export default async function SubsidiesPage({
{cases.length === 0 ? (
<p className="text-center text-sm text-gray-500"> </p>
) : (
cases.map((c) => {
cases.map((c: (typeof cases)[number]) => {
const statusInfo = STATUS_MAP[c.status] ?? {
label: c.status,
color: 'bg-gray-100 text-gray-700',
};
const total = c.checklistItems.length;
const checked = c.checklistItems.filter((item) => item.status === 'CHECKED').length;
const checked = c.checklistItems.filter((item: (typeof c.checklistItems)[number]) => item.status === 'CHECKED').length;
return (
<div key={c.publicId} className="rounded-lg border border-gray-200 bg-white p-5">
<div className="flex items-start justify-between">
+2 -2
View File
@@ -71,12 +71,12 @@ export default async function VendorsPage() {
<p className="text-sm text-gray-500"> .</p>
) : (
<div className="space-y-3">
{vendors.map((vendor) => {
{vendors.map((vendor: (typeof vendors)[number]) => {
const badge = STATUS_BADGE[vendor.certificationStatus] ?? {
label: '심사 대기',
className: 'bg-yellow-100 text-yellow-700',
};
const regionNames = vendor.coverageRegions.map((cr) => cr.region.nameKo).join(', ');
const regionNames = vendor.coverageRegions.map((cr: (typeof vendor.coverageRegions)[number]) => cr.region.nameKo).join(', ');
const typeLabel = VENDOR_TYPE_LABEL[vendor.vendorType] ?? vendor.vendorType;
return (