django-admin-react 0.2.0a3__tar.gz → 0.2.0a4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/PKG-INFO +1 -1
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/inlines.py +21 -1
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/serializers.py +18 -3
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/list.py +8 -4
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/static/admin_react/.vite/manifest.json +2 -2
- django_admin_react-0.2.0a4/django_admin_react/static/admin_react/assets/index-Cf63Q57m.css +1 -0
- django_admin_react-0.2.0a4/django_admin_react/static/admin_react/assets/index-Ch1wOBLJ.js +9 -0
- django_admin_react-0.2.0a4/django_admin_react/static/admin_react/assets/index-Ch1wOBLJ.js.map +1 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/static/admin_react/index.html +2 -2
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/templates/admin_react/index.html +7 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/pyproject.toml +1 -1
- django_admin_react-0.2.0a3/django_admin_react/static/admin_react/assets/index-BOdTCQF7.js +0 -9
- django_admin_react-0.2.0a3/django_admin_react/static/admin_react/assets/index-BOdTCQF7.js.map +0 -1
- django_admin_react-0.2.0a3/django_admin_react/static/admin_react/assets/index-BgIZIHRa.css +0 -1
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/LICENSE +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/README.md +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/README.md +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/__init__.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/README.md +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/__init__.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/dates.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/filters.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/inlines_write.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/panels.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/permissions.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/registry.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/urls.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/README.md +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/__init__.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/actions.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/auth.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/autocomplete.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/bulk.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/create.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/create_form.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/delete_preview.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/destroy.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/detail.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/history.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/registry.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/schema.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/update.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/writes.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/apps.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/audit.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/conf.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/pwa.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/templates/admin_react/README.md +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/templates/admin_react/login.html +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/templates/admin_react/sw.js +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/urls.py +0 -0
- {django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/views.py +0 -0
|
@@ -32,9 +32,11 @@ from django.db.models import ManyToManyField
|
|
|
32
32
|
from django.db.models import Model
|
|
33
33
|
from django.http import HttpRequest
|
|
34
34
|
|
|
35
|
+
from django_admin_react.api.serializers import field_type_for
|
|
35
36
|
from django_admin_react.api.serializers import filter_sensitive
|
|
36
37
|
from django_admin_react.api.serializers import is_sensitive_field_name
|
|
37
38
|
from django_admin_react.api.serializers import label_for
|
|
39
|
+
from django_admin_react.api.serializers import safe_get_field
|
|
38
40
|
from django_admin_react.api.serializers import serialize_fk_value
|
|
39
41
|
from django_admin_react.api.serializers import serialize_value
|
|
40
42
|
|
|
@@ -192,7 +194,17 @@ def _fields_meta(
|
|
|
192
194
|
visible_fields: list[str],
|
|
193
195
|
request: HttpRequest,
|
|
194
196
|
) -> list[dict[str, Any]]:
|
|
195
|
-
"""Per-field metadata for the inline header
|
|
197
|
+
"""Per-field metadata for the inline header.
|
|
198
|
+
|
|
199
|
+
Carries ``type`` + ``required`` (in addition to ``name`` / ``label``
|
|
200
|
+
/ ``readonly``) so the SPA can render a *typed* input per inline
|
|
201
|
+
field in edit mode — the prerequisite for inline editing (#54
|
|
202
|
+
write-half UI). ``type`` reuses the same closed vocabulary
|
|
203
|
+
(``field_type_for``) the top-level detail descriptor uses, so the
|
|
204
|
+
frontend can route inline fields through the same ``FieldInput``
|
|
205
|
+
component. Additive — existing read-only consumers ignore the new
|
|
206
|
+
keys.
|
|
207
|
+
"""
|
|
196
208
|
readonly = set(inline.get_readonly_fields(request, None) or ())
|
|
197
209
|
out: list[dict[str, Any]] = []
|
|
198
210
|
for name in visible_fields:
|
|
@@ -200,11 +212,19 @@ def _fields_meta(
|
|
|
200
212
|
label = label_for_field(name, child_model, inline)
|
|
201
213
|
except Exception: # pragma: no cover
|
|
202
214
|
label = name
|
|
215
|
+
model_field = safe_get_field(child_model, name)
|
|
216
|
+
field_type = field_type_for(model_field) if model_field is not None else "unsupported"
|
|
217
|
+
# ``required`` mirrors the form layer: a field is required when
|
|
218
|
+
# it is not ``blank``. ``safe_get_field`` returning ``None`` (a
|
|
219
|
+
# method-only ``list_display`` entry) → not required / unsupported.
|
|
220
|
+
required = bool(model_field is not None and not getattr(model_field, "blank", True))
|
|
203
221
|
out.append(
|
|
204
222
|
{
|
|
205
223
|
"name": name,
|
|
206
224
|
"label": str(label),
|
|
207
225
|
"readonly": name in readonly,
|
|
226
|
+
"type": field_type,
|
|
227
|
+
"required": required,
|
|
208
228
|
}
|
|
209
229
|
)
|
|
210
230
|
return out
|
{django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/serializers.py
RENAMED
|
@@ -196,11 +196,26 @@ def _serialize_range_value(value: Any, field: Field | None) -> dict[str, Any]:
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
|
|
199
|
-
def serialize_fk_value(value: Model | None) -> dict[str, Any] | None:
|
|
200
|
-
"""Serialize an FK as ``{"id": pk, "label": str(obj)}`` or ``None``.
|
|
199
|
+
def serialize_fk_value(value: Model | None, *, admin_site: Any = None) -> dict[str, Any] | None:
|
|
200
|
+
"""Serialize an FK as ``{"id": pk, "label": str(obj)}`` or ``None``.
|
|
201
|
+
|
|
202
|
+
When ``admin_site`` is provided **and** the related model is
|
|
203
|
+
registered on it, the envelope also carries
|
|
204
|
+
``to: {"app_label": <real>, "model_name": ...}`` so the SPA can
|
|
205
|
+
render the cell as a navigable link to the related object's detail
|
|
206
|
+
page (#184). The target is **omitted** when the related model isn't
|
|
207
|
+
registered — surfacing a link the detail endpoint would 404 on (and
|
|
208
|
+
leaking adjacency to an unregistered model) is the exact posture
|
|
209
|
+
#89 removed from filter descriptors. ``app_label`` is the real
|
|
210
|
+
``_meta.app_label`` the detail URL resolves against.
|
|
211
|
+
"""
|
|
201
212
|
if value is None:
|
|
202
213
|
return None
|
|
203
|
-
|
|
214
|
+
out: dict[str, Any] = {"id": value.pk, "label": label_for(value)}
|
|
215
|
+
if admin_site is not None and type(value) in getattr(admin_site, "_registry", {}):
|
|
216
|
+
meta = value._meta
|
|
217
|
+
out["to"] = {"app_label": meta.app_label, "model_name": meta.model_name}
|
|
218
|
+
return out
|
|
204
219
|
|
|
205
220
|
|
|
206
221
|
def label_for(obj: Model) -> str:
|
{django_admin_react-0.2.0a3 → django_admin_react-0.2.0a4}/django_admin_react/api/views/list.py
RENAMED
|
@@ -112,7 +112,10 @@ class ListView(View):
|
|
|
112
112
|
list_display = list(model_admin.get_list_display(request))
|
|
113
113
|
columns = _columns_payload(model_admin, list_display, request)
|
|
114
114
|
|
|
115
|
-
results = [
|
|
115
|
+
results = [
|
|
116
|
+
_row_for(obj, model_admin, list_display, request, admin_site)
|
|
117
|
+
for obj in queryset[start:end]
|
|
118
|
+
]
|
|
116
119
|
|
|
117
120
|
body: dict[str, Any] = {
|
|
118
121
|
"app_label": model._meta.app_label,
|
|
@@ -267,6 +270,7 @@ def _row_for(
|
|
|
267
270
|
model_admin: ModelAdmin,
|
|
268
271
|
list_display: list[str],
|
|
269
272
|
request: HttpRequest,
|
|
273
|
+
admin_site: Any = None,
|
|
270
274
|
) -> dict[str, Any]:
|
|
271
275
|
"""Build one ``results[]`` entry for the list response.
|
|
272
276
|
|
|
@@ -283,11 +287,11 @@ def _row_for(
|
|
|
283
287
|
_f, _attr, value = lookup_field(name, obj, model_admin)
|
|
284
288
|
except Exception: # pragma: no cover — defensive
|
|
285
289
|
value = ""
|
|
286
|
-
fields[name] = _serialize_list_value(obj, name, value)
|
|
290
|
+
fields[name] = _serialize_list_value(obj, name, value, admin_site)
|
|
287
291
|
return {"pk": obj.pk, "label": label_for(obj), "fields": fields}
|
|
288
292
|
|
|
289
293
|
|
|
290
|
-
def _serialize_list_value(obj: Model, name: str, value: Any) -> Any:
|
|
294
|
+
def _serialize_list_value(obj: Model, name: str, value: Any, admin_site: Any = None) -> Any:
|
|
291
295
|
"""Serialize a single ``list_display`` cell.
|
|
292
296
|
|
|
293
297
|
FK fields go through the FK envelope (``{"id", "label"}``);
|
|
@@ -300,5 +304,5 @@ def _serialize_list_value(obj: Model, name: str, value: Any) -> Any:
|
|
|
300
304
|
"""
|
|
301
305
|
model_field = safe_get_field(obj, name)
|
|
302
306
|
if isinstance(model_field, ForeignKey):
|
|
303
|
-
return serialize_fk_value(value)
|
|
307
|
+
return serialize_fk_value(value, admin_site=admin_site)
|
|
304
308
|
return serialize_value(value, field=model_field)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.left-0{left:0}.top-0{top:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.col-span-2{grid-column:span 2 / span 2}.-ml-2{margin-left:-.5rem}.mb-1{margin-bottom:.25rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.max-h-60{max-height:15rem}.max-h-\[85vh\]{max-height:85vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-72{width:18rem}.w-full{width:100%}.min-w-48{min-width:12rem}.min-w-full{min-width:100%}.max-w-\[16rem\]{max-width:16rem}.max-w-full{max-width:100%}.max-w-prose{max-width:65ch}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(243 244 246 / var(--tw-divide-opacity, 1))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-400{--tw-border-opacity: 1;border-color:rgb(248 113 113 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-600{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-500{--tw-bg-opacity: 1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pr-3{padding-right:.75rem}.pt-1{padding-top:.25rem}.pt-20{padding-top:5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.tracking-wide{letter-spacing:.025em}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-gray-500::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(107 114 128 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-500::placeholder{--tw-placeholder-opacity: 1;color:rgb(107 114 128 / var(--tw-placeholder-opacity, 1))}.opacity-25{opacity:.25}.opacity-40{opacity:.4}.opacity-75{opacity:.75}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}html,body,#root{height:100%}.hover\:bg-blue-100:hover{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800:hover{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:no-underline:hover{text-decoration-line:none}.focus\:border-blue-500:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.focus\:ring-gray-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1))}.focus\:ring-red-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:max-w-md{max-width:28rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:items-center{align-items:center}.sm\:rounded-xl{border-radius:.75rem}}@media(min-width:768px){.md\:static{position:static}.md\:z-auto{z-index:auto}.md\:hidden{display:none}.md\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.md\:pt-6{padding-top:1.5rem}}@media(min-width:1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
|