Ke-san commited on
Commit
9afeafe
·
verified ·
1 Parent(s): dabc31f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -28
app.py CHANGED
@@ -33,7 +33,7 @@ CARD_CSS = """
33
  gap: 12px;
34
  }
35
 
36
- /* Radioは input + label の構造なので label をカード化 */
37
  #job_cards label {
38
  border: 1px solid #e5e7eb !important;
39
  border-radius: 16px !important;
@@ -41,8 +41,9 @@ CARD_CSS = """
41
  background: #ffffff !important;
42
  cursor: pointer !important;
43
  line-height: 1.45 !important;
44
- white-space: pre-wrap !important; /* \n を効かせる */
45
  transition: all .12s ease;
 
46
  }
47
 
48
  /* hover */
@@ -51,13 +52,14 @@ CARD_CSS = """
51
  box-shadow: 0 6px 18px rgba(17, 24, 39, 0.08);
52
  }
53
 
54
- /* 選択時 */
55
  #job_cards input:checked + label {
56
  border-color: #4f46e5 !important;
57
  background: #eef2ff !important;
 
58
  }
59
 
60
- /* ラジオ丸を控えめに(好みで調整可) */
61
  #job_cards input[type="radio"] {
62
  transform: scale(0.95);
63
  margin-top: 6px;
@@ -201,13 +203,12 @@ def bids_table(job_id=None):
201
  return pd.DataFrame(rows)
202
 
203
  # =========================
204
- # Contractor card-like list (Radio choices)
205
  # =========================
206
  def open_job_cards(date_mode: str):
207
  """
208
- 職人タブの「募集中案件カード(Radio)」 choices を作る
209
- 1枚のカードに案件要点をリスト表示する想定。
210
- 期限が近い順(残り日数が小さい順)に並べる。
211
  """
212
  items = []
213
  for j in STATE["jobs"]:
@@ -218,18 +219,12 @@ def open_job_cards(date_mode: str):
218
  rem_days = days_remaining(j["deadline_raw"])
219
  rem = remaining_label(j["deadline_raw"])
220
 
221
- details = (j.get("details") or "").strip()
222
- details_short = details[:60] + ("…" if len(details) > 60 else "")
223
- if not details_short:
224
- details_short = "(詳細なし)"
225
-
226
  label = (
227
  f"{j['title']}\n"
228
- f"・案件ID:{j['job_id']}\n"
229
  f"・エリア:{j['area']}\n"
230
  f"・予算:{yen(j['budget_min'])}〜{yen(j['budget_max'])}\n"
231
- f"・納期:{dl}({rem})\n"
232
- f"・概要:{details_short}"
233
  )
234
 
235
  sort_key = rem_days if rem_days is not None else 10**9
@@ -239,24 +234,39 @@ def open_job_cards(date_mode: str):
239
  return [x[1] for x in items]
240
 
241
  def job_card_md(job_id: str, date_mode: str):
 
 
 
 
242
  j = next((x for x in STATE["jobs"] if x["job_id"] == job_id), None)
243
  if not j:
244
  return "(案件が見つかりません)"
245
- details = j.get("details", "") or "(詳細なし)"
 
246
  dl = format_deadline(j["deadline_raw"], date_mode)
247
  rem = remaining_label(j["deadline_raw"])
248
 
 
249
  return f"""
250
- <div style="border:1px solid #e5e7eb;border-radius:16px;padding:14px;background:#ffffff;">
251
- <div style="font-size:18px;font-weight:800;margin-bottom:8px;">{j['title']}</div>
252
- <div style="display:flex;gap:10px;flex-wrap:wrap;">
253
- <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;">案件ID: <b>{j['job_id']}</b></div>
254
- <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;">エリア: <b>{j['area']}</b></div>
255
- <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;">予算: <b>{yen(j['budget_min'])}〜{yen(j['budget_max'])}</b></div>
256
- <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;">納期: <b>{dl}</b></div>
257
- <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;">{rem}</div>
 
 
 
 
 
 
 
 
 
 
258
  </div>
259
- <div style="margin-top:10px;color:#374151;white-space:pre-wrap;">{details}</div>
260
  </div>
261
  """
262
 
@@ -345,7 +355,7 @@ def refresh_contractor_view(date_mode):
345
 
346
  def on_card_select(job_id, date_mode):
347
  """
348
- 職人:カード(Radio)を選ぶ → 入札先Dropdownへ自動セット + 詳細カード表示 + 入札一覧更新
349
  """
350
  if not job_id:
351
  return (
@@ -517,7 +527,6 @@ with gr.Blocks(title="ギルドビルド|プロトタイプ", theme=gr.themes.
517
  )
518
  refresh_jobs_btn = gr.Button("案件リスト更新")
519
 
520
- # ★カード化されたRadio(CSSでカードUI)
521
  job_cards = gr.Radio(
522
  label="募集中案件(カード)",
523
  choices=open_job_cards(date_mode.value),
 
33
  gap: 12px;
34
  }
35
 
36
+ /* label をカード化(常に文字色を濃色に固定) */
37
  #job_cards label {
38
  border: 1px solid #e5e7eb !important;
39
  border-radius: 16px !important;
 
41
  background: #ffffff !important;
42
  cursor: pointer !important;
43
  line-height: 1.45 !important;
44
+ white-space: pre-wrap !important;
45
  transition: all .12s ease;
46
+ color: #111827 !important; /* ★選択時に文字が消えるのを防ぐ */
47
  }
48
 
49
  /* hover */
 
52
  box-shadow: 0 6px 18px rgba(17, 24, 39, 0.08);
53
  }
54
 
55
+ /* 選択時:背景 + 枠 + 文字色を明示 */
56
  #job_cards input:checked + label {
57
  border-color: #4f46e5 !important;
58
  background: #eef2ff !important;
59
+ color: #111827 !important; /* ★checkedで白文字化されても上書き */
60
  }
61
 
62
+ /* ラジオ丸 */
63
  #job_cards input[type="radio"] {
64
  transform: scale(0.95);
65
  margin-top: 6px;
 
203
  return pd.DataFrame(rows)
204
 
205
  # =========================
206
+ # Contractor card list (simple)
207
  # =========================
208
  def open_job_cards(date_mode: str):
209
  """
210
+ 職人タブの「募集中案件カード(Radio)」 choices
211
+ カード内はシンプルに:タイトル/エリア/予算/納期/残り
 
212
  """
213
  items = []
214
  for j in STATE["jobs"]:
 
219
  rem_days = days_remaining(j["deadline_raw"])
220
  rem = remaining_label(j["deadline_raw"])
221
 
 
 
 
 
 
222
  label = (
223
  f"{j['title']}\n"
 
224
  f"・エリア:{j['area']}\n"
225
  f"・予算:{yen(j['budget_min'])}〜{yen(j['budget_max'])}\n"
226
+ f"・納期:{dl}\n"
227
+ f"・{rem}"
228
  )
229
 
230
  sort_key = rem_days if rem_days is not None else 10**9
 
234
  return [x[1] for x in items]
235
 
236
  def job_card_md(job_id: str, date_mode: str):
237
+ """
238
+ 選択後の詳細表示(見栄え重視)
239
+ ※案件IDは表示しない(要望)
240
+ """
241
  j = next((x for x in STATE["jobs"] if x["job_id"] == job_id), None)
242
  if not j:
243
  return "(案件が見つかりません)"
244
+
245
+ details = (j.get("details") or "").strip() or "(詳細なし)"
246
  dl = format_deadline(j["deadline_raw"], date_mode)
247
  rem = remaining_label(j["deadline_raw"])
248
 
249
+ # status表示(職人は基本OPENを見る想定なので「募集中」を固定表示)
250
  return f"""
251
+ <div style="border:1px solid #e5e7eb;border-radius:18px;padding:16px;background:#ffffff;">
252
+ <div style="display:flex;align-items:flex-start;justify-content:space-between;gap:12px;">
253
+ <div style="font-size:20px;font-weight:900;line-height:1.2;">{j['title']}</div>
254
+ <div style="padding:6px 10px;border-radius:999px;background:#f3f4f6;color:#111827;font-weight:700;">
255
+ 募集中
256
+ </div>
257
+ </div>
258
+
259
+ <div style="margin-top:10px;display:flex;gap:10px;flex-wrap:wrap;">
260
+ <div style="padding:7px 10px;border-radius:999px;background:#f3f4f6;">エリア:<b>{j['area']}</b></div>
261
+ <div style="padding:7px 10px;border-radius:999px;background:#f3f4f6;">予算:<b>{yen(j['budget_min'])}〜{yen(j['budget_max'])}</b></div>
262
+ <div style="padding:7px 10px;border-radius:999px;background:#f3f4f6;">納期:<b>{dl}</b></div>
263
+ <div style="padding:7px 10px;border-radius:999px;background:#eef2ff;color:#111827;"><b>{rem}</b></div>
264
+ </div>
265
+
266
+ <div style="margin-top:14px;padding:12px;border-radius:14px;background:#fafafa;border:1px solid #f3f4f6;">
267
+ <div style="font-weight:800;margin-bottom:6px;color:#111827;">詳細</div>
268
+ <div style="color:#374151;white-space:pre-wrap;line-height:1.6;">{details}</div>
269
  </div>
 
270
  </div>
271
  """
272
 
 
355
 
356
  def on_card_select(job_id, date_mode):
357
  """
358
+ 職人:カード選択 → 入札先Dropdownへ自動セット + 詳細表示 + 入札一覧更新
359
  """
360
  if not job_id:
361
  return (
 
527
  )
528
  refresh_jobs_btn = gr.Button("案件リスト更新")
529
 
 
530
  job_cards = gr.Radio(
531
  label="募集中案件(カード)",
532
  choices=open_job_cards(date_mode.value),