Merge pull request #223 from IBCornelsen/UMBE

update UMBE
This commit is contained in:
UMBENOMENA
2024-12-16 23:13:58 +01:00
committed by GitHub
7 changed files with 171 additions and 501 deletions

View File

@@ -46,6 +46,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
placeholder="Anlass"
required
>
<option disabled selected value={false}>Bitte auswählen</option>
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
<option value={ausstellgrund}>{name}</option>
{/each}
@@ -67,7 +68,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required
bind:value={gebaeude_aufnahme_allgemein.gebaeudetyp}
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
<option value="Einfamilienhaus">Einfamilienhaus</option>
<option value="Freistehendes Einfamilienhaus"
>Freistehendes Einfamilienhaus</option

View File

@@ -43,7 +43,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
<div class="grid grid-cols-2 gap-x-4 order-2 md:order-2 xl:order-2">
<div class="input-plz">
<div class="input-noHelp">
<Inputlabel title="PLZ *"></Inputlabel>
<ZipSearch
@@ -112,7 +112,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required
bind:value={gebaeude_aufnahme_allgemein.keller}
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
@@ -136,7 +136,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
bind:value={gebaeude_aufnahme_allgemein.dachgeschoss}
required
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>

View File

@@ -0,0 +1,139 @@
<script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte";
import Inputlabel from "#labels/InputLabel.svelte";
import ZipSearch from "#components/PlzSuche.svelte";
import { Enums } from "@ibcornelsen/database/client"
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
</script>
<div id="lueftungundleerstand" class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
">
<!-- Gebäudeteil -->
<div class="grid grid-cols-2 gap-x-4 order-2 md:order-2 xl:order-2">
<div class="input-standard">
<Inputlabel title="Gebäudeteil *"></Inputlabel>
<select
name="gebaeudeteil"
data-test="gebaeudeteil"
bind:value={gebaeude_aufnahme_allgemein.gebaeudeteil}
required
>
<option disabled selected value={false}>Bitte auswählen</option>
<option value="Gesamtgebäude">Gesamtgebäude</option>
<option value="Wohnen">Wohnen</option>
</select>
<div class="help-label">
<HelpLabel>
Bitte geben Sie hier den Gebäudeteil ein. In den meisten
Fällen handelt es sich um das Gesamtgebäude. Sollte es sich
allerdings um ein Gebäude mit mehr als 10% Gewerbeanteil
handeln, so sollten 2 Ausweise erstellt werden. In diesem
Fall wählen Sie Gebäudeteil 'Wohnen' bzw. Gebäudeteil
'Gewerbe'.
</HelpLabel>
</div>
</div>
<div class="input-standard">
<Inputlabel title="Leerstand in %"></Inputlabel>
<input
name="leerstand"
data-test="leerstand"
maxlength="2"
type="number"
bind:value={gebaeude_aufnahme_allgemein.leerstand}
/>
<div class="help-label">
<HelpLabel>
Bitte geben Sie hier den Leerstand in % des Gesamtzeitraumes
(3 Jahre) ein. Zum Beispiel 4 Monate Leerstand in 36 Monaten
wären dann ca. 11%.
</HelpLabel>
</div>
</div>
</div>
<!-- Lüftung -->
<div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="Lüftung durch *"></Inputlabel>
<select
name="lueftung"
data-test="lueftung"
required
bind:value={gebaeude_aufnahme_allgemein.lueftung}
>
<option disabled selected value={false}>Bitte auswählen</option>
<option value="Fensterlüftung">Fensterlüftung</option>
<option value="Schachtlüftung">Schachtlüftung</option>
<option value="Lüftungsanlage ohne Wärmerückgewinnung"
>Lüftungsanlage ohne Wärmerückgewinnung</option
>
<option value="Lüftungsanlage mit Wärmerückgewinnung"
>Lüftungsanlage mit Wärmerückgewinnung</option
>
</select>
<div class="help-label">
<HelpLabel>
Bitte geben Sie hier den Gebäudeteil ein. In den meisten
Fällen handelt es sich um das Gesamtgebäude. Sollte es sich
allerdings um ein Gebäude mit mehr als 10% Gewerbeanteil
Bitte geben Sie hier ein ob über die Fenster natürlich
belüftet wird oder über eine Lüftungsanlage.
</HelpLabel>
</div>
</div>
<!-- Kühlung -->
<div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="Anlage Kühlung *"></Inputlabel>
<select
name="kuehlung"
data-test="kuehlung"
required
bind:value={gebaeude_aufnahme_allgemein.kuehlung}
>
<option disabled selected value={false}>Bitte auswählen</option>
<option value="1">vorhanden</option>
<option value="0">nicht vorhanden</option>
</select>
<div class="help-label">
<HelpLabel>
Bitte geben Sie an ob das Gebäude im Sommer zusätzlich
gekühlt wird.
</HelpLabel>
</div>
</div>
</div>

View File

@@ -67,7 +67,7 @@
$: abweichung = auditVerbrauchAbweichung(ausweis, gebaeude);
function labelClick(event){
function labelClick(event: any){
var x = event.target.previousElementSibling;
x.click();
}
@@ -135,8 +135,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
name="brennstoff_1"
required bind:value={gebaeude_aufnahme_allgemein.brennstoff_1}
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
@@ -181,8 +180,8 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required
bind:value={ausweis.einheit_1}
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(gebaeude_aufnahme_allgemein.brennstoff_1) ? fuelMap[gebaeude_aufnahme_allgemein.brennstoff_1] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
@@ -214,7 +213,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required
>
<option disabled> Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
@@ -260,7 +259,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
bind:value={ausweis.einheit_2}
required
>
<option disabled>Bitte auswählen</option>
<option disabled selected value={false}>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(gebaeude_aufnahme_allgemein.brennstoff_2) ? fuelMap[gebaeude_aufnahme_allgemein.brennstoff_2] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
@@ -289,8 +288,8 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
class="rounded-tr-none rounded-br-none w-full m-0"
bind:value={month}
required
>
<option>Monat</option>
>
<option disabled>Monat</option>
{#if year !== null}
{#each availableDates.filter(date => date.year == year) as date}
<option value={date.month}>{monthNames[date.month]}</option>
@@ -322,7 +321,7 @@ class="rounded-tl-none rounded-bl-none w-full m-0"
bind:value={year}
required
>
<option>Jahr</option>
<option disabled>Jahr</option>
{#each Array.from(availableDates.reduce((a,c) => {
a.add(c.year);
return a;
@@ -412,7 +411,7 @@ required
<div class="input-standard"></div>
<div class="input-standard">
<div class="input-noHelp">
<Inputlabel title="von:"></Inputlabel>
<input
@@ -423,15 +422,10 @@ required
readonly
/>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>
<div class="input-standard">
<div class="input-noHelp">
<Inputlabel title="bis:"></Inputlabel>
<input
@@ -441,12 +435,6 @@ required
readonly
/>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>
@@ -499,7 +487,7 @@ required
<div class="input-standard"></div>
<div class="input-standard">
<div class="input-noHelp">
<Inputlabel title="von:"></Inputlabel>
<input
@@ -510,15 +498,9 @@ required
readonly
/>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>
<div class="input-standard">
<div class="input-noHelp">
<Inputlabel title="bis:"></Inputlabel>
<input
@@ -528,12 +510,6 @@ required
readonly
/>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>

View File

@@ -1,458 +0,0 @@
<script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte";
import Inputlabel from "#labels/InputLabel.svelte";
import Label from "../Label.svelte";
import moment from "moment";
import fuelList from "./brennstoffListe.js";
import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung.js";
import { GebaeudeAufnahmeClient, GebaeudeClient, VerbrauchsausweisWohnenClient } from "./types.js";
export let gebaeude: GebaeudeClient;
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
export let ausweis: VerbrauchsausweisWohnenClient;
// Wir dürfen bis zu 4.5 Jahre alte Klimafaktoren benutzen, also nehmen wir alle Monate seitdem und generieren daraus die Auswahl.
// Allerdings müssen wir auch berücksichtigen, dass wir drei folgende Jahre brauchen, also
// kann der Nutzer nur 36 + 18 Monate zurückgehen.
let availableDates: {
year: number;
month: number;
}[] = [];
let monthNames = [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember",
];
const startDate = moment(ausweis.gebaeude_aufnahme_allgemein.erstellungsdatum || Date.now()).subtract(4, "years").subtract(6, "months");
const endDate = moment(ausweis.gebaeude_aufnahme_allgemein.erstellungsdatum || Date.now()).subtract(3, "years");
for (let m = moment(startDate); m.isBefore(endDate); m.add(1, "month")) {
availableDates.push({
year: m.year(),
month: m.month(),
});
}
const fuelMap: Record<string, string[]> = {};
for (const fuel of fuelList) {
// fuelMap[fuel.energietraeger] = ...
fuelMap[fuel[0]] = fuelMap[fuel[0]] || [];
fuelMap[fuel[0]].push(fuel[1]);
}
let month = ausweis.startdatum?.getMonth() || null;
let year = ausweis.startdatum?.getFullYear() || null;
$: {
if (typeof month === "number" && typeof year === "number") {
// Wir addieren einfach 2 Tage auf das Datum, falls der Nutzer außerhalb Deutschlands und in einer anderen Zeitzone ist.
// NOTE: Das ist eine grauenvolle Lösung aber alle anderen funktionieren irgendwie nicht...
ausweis.startdatum = moment().set("month", month).set("year", year).startOf("month").add(2, "days").toDate();
}
}
$: abweichung = auditVerbrauchAbweichung(ausweis, gebaeude);
</script>
<div id="verbrauch" class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
">
<div class="input-standard order-1 md:order-1 xl:order-1">
<Inputlabel title="Warmwasser im Verbrauch enthalten"></Inputlabel>
<div class="input-checkboxen">
<div class="grid grid-cols-[40px_max-content] items-center justify-items-start">
<input
type="checkbox"
class="checkbox"
name="warmwasser_enthalten"
data-test="warmwasser_enthalten"
bind:checked={ausweis.warmwasser_enthalten}
/>
<label for="warmwasser_enthalten" class="cursor-pointer" on:click={() => labelClick(event)}>Ja</label>
</div>
<div class="grid grid-cols-[40px_max-content] items-center justify-items-start">
<input
type="checkbox"
class="checkbox"
name="warmwasser_anteil_bekannt"
data-test="warmwasser_anteil_bekannt"
bind:checked={ausweis.warmwasser_anteil_bekannt}
disabled={!ausweis.warmwasser_enthalten}
/>
<label for="warmwasser_anteil_bekannt" class="cursor-pointer" on:click={() => labelClick(event)}>Anteil bekannt</label>
</div>
</div>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>
<div class="grid grid-cols-[40px_1fr] mb-4 xl:mb-0">
<input
type="checkbox"
class="checkbox w-[20px] h-[20px] self-center -mt-1"
name="zusaetzliche_heizquelle"
bind:checked={ausweis.zusaetzliche_heizquelle}
/>
<div class="w-[150px]">
<HelpLabel title="zusätzliche Heizquelle">
Wenn eine zusätzliche Heizquelle vorhanden geben Sie hier drei
zusammenhängende Verbrauchsjahre ein. Es sollen die gleichen
Verbrauchszeiträume wie bei der primären Heizung verwendet
werden.
</HelpLabel>
</div>
</div>
<input class="hidden xl:invisible xl:block"/>
<div class="grid grid-cols-[40px_120px] gap-x-1 items-center">
<div></div>
<span>Zeitraum:</span>
</div>
<div class="grid grid-cols-[30px_1fr_1fr_30px_1fr] gap-x-2 items-center justify-items-center">
<span class="">von</span>
<select
name="energieverbrauch_zeitraum_monat"
class="rounded-tr-none rounded-br-none w-full m-0"
bind:value={month}
required
>
<option>Monat</option>
{#if year !== null}
{#each availableDates.filter(date => date.year == year) as date}
<option value={date.month}>{monthNames[date.month]}</option>
{/each}
{:else}
{#each Array.from(availableDates.reduce((a,c) => {
a.add(c.month);
return a;
}, new Set())) as month}
<option value={month}>{monthNames[month]}</option>
{/each}
{/if}
</select>
<select
name="energieverbrauch_zeitraum_jahr"
class="rounded-tl-none rounded-bl-none w-full m-0"
bind:value={year}
required
>
<option>Jahr</option>
{#each Array.from(availableDates.reduce((a,c) => {
a.add(c.year);
return a;
}, new Set())) as year}
<option value={year}>{year}</option>
{/each}
</select>
<span class="">bis</span>
<input
value={moment(ausweis.startdatum)
.add("1", "year")
.format("MM.Y")}
readonly
/>
</div>
<div class="invisible">
<span>leer</span>
</div>
<div class="grid grid-cols-[1fr_30px_1fr_30px_1fr] gap-x-2 items-center justify-items-center">
<div></div>
<span class="justify-self-center">von</span>
<input
class="klima text-right"
value={moment(ausweis.startdatum)
.add("1", "year")
.format("MM.Y")}
readonly
/>
<span class="justify-self-center">bis</span>
<input
value={moment(ausweis.startdatum)
.add("2", "years")
.format("MM.Y")}
readonly
/>
</div>
<div class="invisible">
<span>leer</span>
</div>
<div class="grid grid-cols-[1fr_30px_1fr_30px_1fr] gap-x-2 items-center justify-items-center">
<div></div>
<span class="justify-self-center">von</span>
<input
class="klima text-right"
value={moment(ausweis.startdatum)
.add("2", "years")
.format("MM.Y")}
readonly
/>
<span class="justify-self-center">bis</span>
<input
value={moment(ausweis.startdatum)
.add("3", "years")
.format("MM.Y")}
readonly
/>
</div>
</div>
<div class="grid grid-cols-2 gap-x-6">
<div>
<div class="grid grid-cols-[3fr_2fr] gap-x-2">
<div>
<HelpLabel title="* Brennstoff">
<b>Heizöl:</b> Flüssiger Brennstoff; Heizöl wird aus schwer
entflammbaren Anteilen des Erdöls hergestellt.<br /><br />
<b>Erdgas H, Erdgas L:</b> Brennbares Naturgas das in
unterirdischen Lagerstätten vorkommt. Erdgas H hat im Vergleich
zu Erdgas L einen leicht höheren Methangehalt, und daher einen
etwas besseren Brennwert.<br /><br />
<b>Flüssiggas:</b> Meist Propan, Butan und deren Gemische, die
bei Raumtemperatur unter vergleichsweise geringem Druck flüssig
bleiben.<br /><br />
<b>Braunkohle:</b> Durch Druck und Luftabschluss von organischen
Substanzen entstandenes, bräunlich-schwarzes Sedimentgestein.<br
/><br />
<b>Holz-Pellets:</b> Stäbchenförmige Pellets die vollständig
oder überwiegend aus Holz oder Sägenebenprodukten hergestellt
werden.<br /><br />
<b>Holzhackschnitzel:</b> Mit schneidenden Werkzeugen
zerkleinertes Holz.<br /><br />
<b>Nahwärme, Fernwärme:</b> Versorgung von thermischer Energie
über wärmegedämmte Rohrsysteme. Die Wärme wird dabei örtlich von
Heizwerken produziert oder besteht aus Prozesswärme von BHKW's.
Im Unterschied zu Fernwärme wird Nahwärme in kleineren Einheiten
dezentral realisiert.<br /><br />
<b>Strommix:</b> Heizen mit Strom (Nachtspeicher).<br /><br />
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
</HelpLabel>
<div>
<select
class="rounded-e-none"
name="brennstoff_1"
required bind:value={gebaeude_aufnahme_allgemein.brennstoff_1}
>
<option disabled>Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
</select>
</div>
</div>
<div>
<HelpLabel title="* Einheit">
Bitte geben Sie die Einheit ein. Erdgas wird meist auf der
Abrechnung in kWh ausgewiesen. Heizöl liegt meistens in Litern
vor. Pellets oder Brennholz in SRm (Schüttraummetern).
</HelpLabel>
<select
class="rounded-s-none"
name="einheit_1"
required
bind:value={ausweis.einheit_1}
>
<option disabled>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(gebaeude_aufnahme_allgemein.brennstoff_1) ? fuelMap[gebaeude_aufnahme_allgemein.brennstoff_1] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
</select>
</div>
</div>
<div>
<span>* Verbrauch</span>
<input
name="verbrauch_1"
type="number"
class:linked={abweichung.indexOf(1) > -1}
bind:value={ausweis.verbrauch_1}
required
/>
<span>* Verbrauch</span>
<input
name="verbrauch_2"
type="number"
class:linked={abweichung.indexOf(2) > -1}
bind:value={ausweis.verbrauch_2}
required
/>
<span>* Verbrauch</span>
<input
name="verbrauch_3"
type="number"
class:linked={abweichung.indexOf(3) > -1}
bind:value={ausweis.verbrauch_3}
required
/>
</div>
</div>
<div>
<div class="grid grid-cols-[3fr_2fr] gap-x-2">
<div>
<Label>* Brennstoff</Label>
<select
class="rounded-e-none"
name="brennstoff_2"
bind:value={gebaeude_aufnahme_allgemein.brennstoff_2}
disabled={!ausweis.zusaetzliche_heizquelle}
required
>
<option disabled> Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
</select>
</div>
<div>
<Label>* Einheit</Label>
<select
class="rounded-s-none"
name="einheit_2"
disabled={!ausweis.zusaetzliche_heizquelle}
bind:value={ausweis.einheit_2}
required
>
<option disabled>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(gebaeude_aufnahme_allgemein.brennstoff_2) ? fuelMap[gebaeude_aufnahme_allgemein.brennstoff_2] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
</select>
</div>
</div>
<div>
<span>Verbrauch</span>
<input
name="verbrauch_4"
type="number"
bind:value={ausweis.verbrauch_4}
class:linked={abweichung.indexOf(4) > -1}
disabled={!ausweis.zusaetzliche_heizquelle}
/>
<span>Verbrauch</span>
<input
name="verbrauch_5"
type="number"
bind:value={ausweis.verbrauch_5}
class:linked={abweichung.indexOf(5) > -1}
disabled={!ausweis.zusaetzliche_heizquelle}
/>
<span>Verbrauch</span>
<input
name="verbrauch_6"
type="number"
bind:value={ausweis.verbrauch_6}
class:linked={abweichung.indexOf(6) > -1}
disabled={!ausweis.zusaetzliche_heizquelle}
/>
</div>
</div>
</div>
<style lang="postcss">
input[type="checkbox"] {@apply accent-secondary}
</style>

View File

@@ -11,8 +11,9 @@
import Ausweisart from "#components/Ausweis/Ausweisart.svelte";
import GebaeudeDaten from "#components/Ausweis/GebaeudeDaten.svelte";
import Warmwasseranteil from "#components/Ausweis/Warmwasseranteil.svelte";
import Verbrauch from "#components/Ausweis/Verbrauch.svelte";
import LueftungundLeerstand from "#components/Ausweis/LueftungundLeerstand.svelte";
//import ZipSearch from "#components/PlzSuche.svelte";
import moment from "moment";
import BilderZusatzsysteme from "#components/Ausweis/BilderZusatzsysteme.svelte";
@@ -232,6 +233,17 @@
/>
</div>
<!-- E Eingabe von Gebäudeteil, Lüftung, Kühlung und Leerstand -->
<BereichLabel bereich="E">Eingabe&nbsp;von&nbsp;Gebäudeteil, Lüftung,&nbsp;Kühlung&nbsp;und&nbsp;Leerstand</BereichLabel>
<div class="collapseBereich">
<LueftungundLeerstand
bind:gebaeude
bind:gebaeude_aufnahme_allgemein
bind:ausweis
/>
</div>

View File

@@ -31,7 +31,7 @@
.input-standard{@apply w-full grid grid-cols-[1fr_25px] items-center relative mt-2}
.input-plz{@apply w-full grid grid-cols-[1fr] items-center relative mt-2}
.input-noHelp{@apply w-full grid grid-cols-[1fr] items-center relative mt-2}
.input-checkboxen{@apply h-[38px] grid grid-cols-[1fr_1fr] gap-2 items-center ring-1 ring-black/15 rounded-sm bg-white}
.input-row{@apply w-full min-h-[38px] grid grid-cols-[1fr_1fr] sm:grid-cols-[1fr_1fr_1fr_1fr] items-center py-[6px] px-[10px] ring-1 ring-black/15 rounded-sm bg-white }