Kalkulator orientacyjnej wyceny usługi możesz przygotować jako pojedynczy plik HTML, otwierany lokalnie w przeglądarce. Nie potrzebujesz do jego uruchomienia serwera ani konta hostingowego. Poniżej znajdziesz prompt do przygotowania własnej wersji, kompletny kod oraz przypadki kontrolne: trzy filmy z jednym dodatkowym formatem na film kosztują w tym przykładzie 900 zł netto, a z terminem ekspresowym — 1125 zł.
Cennik jest fikcyjny i służy do ćwiczenia. Nie przedstawia stawek rynkowych, a wynik kalkulatora nie jest wiążącą ofertą.
Zapisz cennik i zasady obliczeń
Zanim poprosisz AI o kod, określ, za co pobierasz opłatę i kiedy doliczasz dopłaty. Dzięki temu masz wzór, z którym porównasz wynik programu.
W przykładzie wyceniamy montaż krótkich filmów według następujących założeń:
| Pozycja | Fikcyjna stawka lub zakres |
|---|---|
| Opłata startowa | 300 zł netto za całe zlecenie |
| Montaż jednego filmu | 120 zł netto |
| Dodatkowy format | 80 zł netto za każdy format każdego filmu |
| Termin ekspresowy | Dopłata 25% od całej sumy, także opłaty startowej |
| Liczba filmów | Liczba całkowita od 1 do 20 |
| Dodatkowe formaty na każdy film | Liczba całkowita od 0 do 2 |
Jeden dodatkowy format przy trzech filmach oznacza trzy dopłaty po 80 zł. Obliczenie bez ekspresu wygląda więc tak:
300 + 3 × 120 + 3 × 1 × 80 = 900 złEkspres zwiększa całą tę kwotę o 25%:
900 × 1,25 = 1125 złRozstrzygnij też, które dane są poprawne. Zero dodatkowych formatów jest dozwolone, ale zero filmów ma zatrzymać obliczenie. Tak samo puste pole, ułamek lub liczba spoza zakresu. Po zmianie danych poprzednia wycena powinna zniknąć, żeby nie wyglądała na wynik dla nowych ustawień.
Przekaż AI prompt z konkretnymi wymaganiami
Precyzyjny prompt opisuje oczekiwane działanie, ale nie gwarantuje poprawnego kodu. Odpowiedź modelu porównaj ze wzorem i przypadkami kontrolnymi.
Ten prompt pozwala zlecić przygotowanie kalkulatora o takim samym zakresie jak przykład poniżej. Nie sprawdzano powtarzalności odpowiedzi konkretnych modeli.
Przygotuj jeden kompletny plik kalkulator.html z HTML, CSS i JavaScript.
Ma działać lokalnie bez bibliotek, backendu i połączeń sieciowych.
Użyj fikcyjnego cennika:
- start 300 zł netto,
- 120 zł za film,
- 80 zł za dodatkowy format na każdy film,
- ekspres dodaje 25% do całej sumy, także opłaty startowej.
Filmy: 1–20. Dodatkowe formaty na każdy film: 0–2.
Dopuszczaj tylko liczby całkowite.
Odrzuć puste pola, liczby ujemne, ułamki i wartości poza zakresem.
Nie traktuj pustego pola jako zera.
Trzy filmy i jeden dodatkowy format na każdy film mają dać 900 zł,
a z ekspresem 1125 zł.
Cennik umieść w jednym obiekcie PRICE. Kwoty licz w groszach.
Wynik oznacz jako orientacyjny, netto, bez naliczania podatków
i bez wiążącej oferty.
Po zmianie danych wejściowych ukryj poprzedni wynik.
Nie zbieraj danych klienta.
Zwróć pełną zawartość pliku, bez pomijania fragmentów kodu.Jeśli chcesz odtworzyć sprawdzony przykład, skorzystaj bezpośrednio z kodu w następnej sekcji. Wygenerowana przez model wersja może się od niego różnić i wymaga osobnego sprawdzenia.
Zapisz kod jako plik HTML i otwórz go w przeglądarce
Kompletny przykład zawiera formularz, cennik i funkcję obliczającą cenę. Działa lokalnie, bez zewnętrznych bibliotek i wysyłania danych.
1. Skopiuj cały poniższy blok kodu, od `<!doctype html>` do `</html>`, bez znaczników otaczających blok.
2. Wklej go do edytora zwykłego tekstu, np. Notatnika lub VS Code.
3. Zapisz jako `kalkulator.html` w kodowaniu UTF-8. W Notatniku wybierz typ „Wszystkie pliki”, aby nie powstał plik `kalkulator.html.txt`.
4. Otwórz plik w przeglądarce przez dwuklik lub przeciągnięcie go na jej okno.
5. Przy domyślnych ustawieniach kliknij „Oblicz wycenę”. Wynik powinien wynosić 900,00 zł.
<!doctype html>
<html lang="pl">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Orientacyjna wycena montażu filmów</title>
<style>
*{box-sizing:border-box}body{margin:0;padding:24px;background:#f4f2ec;color:#101012;font:18px/1.5 system-ui,sans-serif}
main{max-width:640px;margin:auto}h1{font-size:clamp(28px,6vw,40px);line-height:1.15}
label{display:block;margin:20px 0}input[type=number]{display:block;width:100%;padding:10px;border:1px solid #1d1d22;font:inherit}
button{padding:12px 22px;border:1px solid #101012;border-radius:999px;background:#101012;color:white;font:inherit;cursor:pointer}
:focus-visible{outline:3px solid #6b3df5;outline-offset:3px}output{display:block;font-weight:700;font-size:28px}
[hidden]{display:none!important}#error{color:#101012;border-left:4px solid #6b3df5;padding-left:12px}
</style>
<main>
<h1>Orientacyjna wycena montażu filmów</h1>
<p>Fikcyjny cennik do ćwiczenia. Podane kwoty są netto, bez naliczania podatków. Wynik jest orientacyjny i nie stanowi wiążącej oferty.</p>
<p id="rates"></p>
<form id="calculator">
<label for="films">Liczba filmów (1–20)
<input id="films" type="number" min="1" max="20" step="1" required value="3"></label>
<label for="formats">Dodatkowe formaty na każdy film (0–2)
<input id="formats" type="number" min="0" max="2" step="1" required value="1"></label>
<label><input id="express" type="checkbox"> Termin ekspresowy</label>
<button type="submit">Oblicz wycenę</button>
<p id="error" role="alert"></p>
<section id="result" hidden aria-live="polite" aria-atomic="true">
<p>Orientacyjna kwota netto, bez naliczania podatków:</p>
<output id="total" for="films formats express"></output>
<p id="details"></p>
<p>To nie jest wiążąca oferta.</p>
</section>
</form>
<noscript>Włącz JavaScript, aby obliczyć wycenę.</noscript>
</main>
<script>
// Kwoty w groszach. Zmieniaj cennik tutaj.
const PRICE = { start: 30000, film: 12000, format: 8000, expressPercent: 25 };
function count(raw, min, max, label) {
if ((typeof raw !== "string" && typeof raw !== "number") ||
String(raw).trim() === "") throw new Error(label + ": uzupełnij pole.");
const value = Number(raw);
if (!Number.isInteger(value) || value < min || value > max)
throw new Error(label + ": wpisz liczbę całkowitą od " + min + " do " + max + ".");
return value;
}
function calculate(rawFilms, rawFormats, express, price = PRICE) {
const films = count(rawFilms, 1, 20, "Liczba filmów");
const formats = count(rawFormats, 0, 2, "Dodatkowe formaty");
const base = price.start + films * price.film + films * formats * price.format;
const extra = express ? Math.round(base * price.expressPercent / 100) : 0;
return { base, extra, total: base + extra };
}
const form = document.getElementById("calculator");
const films = document.getElementById("films");
const formats = document.getElementById("formats");
const express = document.getElementById("express");
const result = document.getElementById("result");
const error = document.getElementById("error");
const money = cents => (cents / 100).toLocaleString("pl-PL", {
style: "currency", currency: "PLN"
});
document.getElementById("rates").textContent =
"Start: " + money(PRICE.start) + ". Film: " + money(PRICE.film) +
". Dodatkowy format na film: " + money(PRICE.format) +
". Ekspres: +" + PRICE.expressPercent + "% od całej sumy.";
form.addEventListener("input", () => {
result.hidden = true;
error.textContent = "";
});
form.addEventListener("invalid", () => {
result.hidden = true;
error.textContent = "Wpisz całkowitą liczbę filmów 1–20 oraz formatów 0–2. Oba pola są wymagane.";
}, true);
form.addEventListener("submit", event => {
event.preventDefault();
result.hidden = true;
error.textContent = "";
try {
const quote = calculate(films.value, formats.value, express.checked);
document.getElementById("total").textContent = money(quote.total);
document.getElementById("details").textContent =
"Suma przed ekspresem: " + money(quote.base) + ". Dopłata: " + money(quote.extra) + ".";
result.hidden = false;
} catch (failure) {
error.textContent = failure.message;
}
});
</script>
</html>W teście logiki obliczeń w Node.js wszystkie 120 poprawnych kombinacji dało wyniki zgodne ze wzorem kontrolnym. Sprawdzono 20 liczb filmów, trzy liczby dodatkowych formatów i dwa ustawienia ekspresu. Funkcje odrzuciły też 18 niepoprawnych wejść.
Osobna próba w przeglądarce potwierdziła wyniki 900,00 zł i 1125,00 zł, w tym dopłatę ekspresową 225,00 zł. Zaznaczenie ekspresu ukrywało wcześniejszą wycenę. Zero lub puste pole liczby filmów zatrzymywało obliczenie, wyświetlało komunikat i nie pozostawiało poprzedniej ceny. Przy szerokości widoku 375 px formularz mieścił się bez poziomego przewijania.
To zakres sprawdzenia tego konkretnego kodu. Nie potwierdza działania dowolnej wersji wygenerowanej z promptu.
Zmień stawki w jednym miejscu
Cennik znajduje się w obiekcie `PRICE` na początku bloku `<script>`. Kwoty zapisane są w groszach: `30000` oznacza 300 zł. Dopłata procentowa jest podana jako liczba procentów, więc `25` oznacza 25%.
Aby zmienić cennik:
1. Otwórz `kalkulator.html` w edytorze tekstu.
2. Znajdź linię zaczynającą się od `const PRICE = {`.
3. Zastąp ją nowymi wartościami.
4. Zapisz plik i odśwież otwartą stronę w przeglądarce.
Przykładowy drugi, również fikcyjny cennik:
const PRICE = { start: 40000, film: 15000, format: 10000, expressPercent: 20 };Oznacza on 400 zł za start, 150 zł za film, 100 zł za dodatkowy format każdego filmu i 20% dopłaty ekspresowej. Dla trzech filmów z jednym dodatkowym formatem na film oraz ekspresem otrzymasz:
(400 + 3 × 150 + 3 × 1 × 100) × 1,20 = 1380 złTen wynik sprawdzono przez przekazanie alternatywnego cennika do funkcji obliczeniowej. Nie testowano osobno edycji pliku i jego ponownego otwarcia w przeglądarce.
Zmiana samych stawek nie wymaga zmiany zakresów pól. Jeśli chcesz dopuścić np. więcej niż 20 filmów, zaktualizuj zarówno atrybut `max` odpowiedniego pola HTML, jak i argument zakresu w wywołaniu `count` wewnątrz funkcji `calculate`. Popraw też etykiety i komunikaty zawierające dotychczasowy limit.
Sprawdź wyniki i odrzucanie błędnych danych
Po zapisaniu własnej kopii przejdź poniższe przypadki. Tabela dotyczy pierwotnego cennika: 300 zł za start, 120 zł za film, 80 zł za dodatkowy format i 25% za ekspres.
| Dane lub czynność | Oczekiwany wynik |
|---|---|
| 3 filmy, 1 dodatkowy format, bez ekspresu | 900,00 zł |
| 3 filmy, 1 dodatkowy format, ekspres | 1125,00 zł, w tym dopłata 225,00 zł |
| 1 film, 0 dodatkowych formatów, bez ekspresu | 420,00 zł |
| 20 filmów, 2 dodatkowe formaty, bez ekspresu | 5900,00 zł |
| 20 filmów, 2 dodatkowe formaty, ekspres | 7375,00 zł |
| 0, −1, 1,5 lub 21 w polu liczby filmów | Brak nowej wyceny i komunikat błędu |
| Puste pole liczby filmów | Brak nowej wyceny i komunikat błędu |
| −1, 0,5 lub 3 w polu dodatkowych formatów | Brak nowej wyceny i komunikat błędu |
| Puste pole dodatkowych formatów | Brak nowej wyceny i komunikat błędu |
| Zmiana liczby lub zaznaczenia ekspresu po obliczeniu | Poprzednia wycena znika |
| Ponowne kliknięcie „Oblicz wycenę” po wpisaniu poprawnych danych | Pojawia się wynik dla bieżących ustawień |
Wyniki liczbowe i odrzucanie niepoprawnych wejść mają potwierdzenie w teście funkcji. Próba formularza w przeglądarce objęła tylko opisane wcześniej interakcje, nie wszystkie wiersze tabeli.
Puste pole zasługuje na osobne sprawdzenie. W JavaScript konwersja `Number("")` daje zero. Funkcja `count` najpierw sprawdza więc, czy użytkownik coś wpisał, a dopiero potem zamienia wartość na liczbę. Dzięki temu brak liczby dodatkowych formatów nie zostaje uznany za świadomie wybrane zero.
Zachowaj granicę między prototypem a przyjmowaniem zamówień
Ten plik oblicza orientacyjną kwotę netto. Nie nalicza podatków, nie zbiera danych klienta i nie wysyła informacji na serwer.
Atrybuty `required`, `min`, `max` i `step` pomagają sprawdzać dane w formularzu. Jak wyjaśnia dokumentacja MDN dotycząca walidacji formularzy, kontrolę w przeglądarce można jednak obejść. Gdyby na podstawie wyceny serwis przyjmował zamówienia, serwer musiałby samodzielnie sprawdzać dane i obliczać cenę.
Przykładu nie sprawdzono z czytnikiem ekranu, w wielu silnikach przeglądarek ani na hostingu. Test nie obejmował płatności.
Szerszy kontekst pracy z kodem generowanym przez AI znajdziesz w artykule o vibe codingu.
Zacznij od zapisania pliku i odtworzenia wyników 900 zł oraz 1125 zł. Potem zmień stawki i ponownie przejdź przypadki kontrolne, zwłaszcza puste pola i granice zakresów.
Źródła
- MDN Web Docs, Client-side form validation — walidacja formularzy i ograniczenia kontroli po stronie klienta.
- MDN Web Docs, \<input type="number"\> — pola liczbowe oraz atrybuty określające wymagane wartości, zakres i krok.



