diff --git a/backend/scripts/demo_system.sh b/backend/scripts/demo_system.sh new file mode 100644 index 0000000..9ce0bdb --- /dev/null +++ b/backend/scripts/demo_system.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# Demo System - Tilbudsgivern Server + +SCRIPT_DIR="$(dirname "$0")" + +# Farver til demo +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +print_banner() { + echo -e "${BLUE}============================================${NC}" + echo -e "${BLUE} TILBUDSGIVERN ANALYSE SYSTEM DEMO${NC}" + echo -e "${BLUE}============================================${NC}" + echo "" +} + +demo_menu() { + echo -e "${CYAN}Vælg demo scenario:${NC}" + echo "" + echo "1. TAG Opgaver Analyse" + echo "2. B7 Opgaver Analyse" + echo "3. Månedlig Økonomi 2025" + echo "4. Komplet System Demo" + echo "5. Afslut" + echo "" + read -p "Vælg (1-5): " choice + echo "" + + case $choice in + 1) + demo_tag_analysis + ;; + 2) + demo_b7_analysis + ;; + 3) + demo_monthly_economics + ;; + 4) + demo_complete_system + ;; + 5) + echo -e "${GREEN}Demo afsluttet${NC}" + exit 0 + ;; + *) + echo -e "${RED}Ugyldigt valg${NC}" + demo_menu + ;; + esac +} + +demo_tag_analysis() { + echo -e "${GREEN}=== TAG OPGAVER ANALYSE DEMO ===${NC}" + echo "Simulerer: ./tag_analyser.sh --key API_KEY --task-type tag" + echo "" + echo -e "${YELLOW}Resultater:${NC}" + echo "- 400+ TAG opgaver identificeret" + echo "- 2 tilbud sendt (0.5% conversion rate)" + echo "- 81.75 timer registreret" + echo "- CSV rapport genereret" + echo "" + read -p "Tryk Enter for at fortsætte..." + demo_menu +} + +demo_b7_analysis() { + echo -e "${GREEN}=== B7 OPGAVER ANALYSE DEMO ===${NC}" + echo "Simulerer: ./tag_analyser.sh --key API_KEY --task-type b7" + echo "" + echo -e "${YELLOW}Resultater:${NC}" + echo "- 6 B7 opgaver identificeret" + echo "- 0 tilbud sendt (100% missed opportunity)" + echo "- Case 2404: 450 dage gammel uden tilbud!" + echo "- Potentiale: 480.000 DKK" + echo "" + read -p "Tryk Enter for at fortsætte..." + demo_menu +} + +demo_monthly_economics() { + echo -e "${GREEN}=== MÅNEDLIG ØKONOMI 2025 DEMO ===${NC}" + echo "Simulerer: ./oekonomi_analyser.sh --key API_KEY --year 2025" + echo "" + echo -e "${YELLOW}Resultater:${NC}" + echo "- 114 cases registreret i 2025" + echo "- 5.985.000 DKK total værdi" + echo "- Kun 120.000 DKK realiseret (2%!)" + echo "- 36 aktive cases" + echo "- September: 100% aktive cases" + echo "" + read -p "Tryk Enter for at fortsætte..." + demo_menu +} + +demo_complete_system() { + echo -e "${GREEN}=== KOMPLET SYSTEM DEMO ===${NC}" + echo "" + echo -e "${CYAN}1. Data Indsamling${NC}" + echo " - Henter alle cases fra API" + echo " - Henter timer registreringer" + echo " - Henter tilbuds data" + echo "" + echo -e "${CYAN}2. Analyse${NC}" + echo " - TAG opgaver: 400+ cases" + echo " - B7 opgaver: 6 cases" + echo " - Økonomi: 114 cases i 2025" + echo "" + echo -e "${CYAN}3. Rapporter${NC}" + echo " - CSV filer til Excel" + echo " - Detaljerede tekst rapporter" + echo " - Månedlige oversigter" + echo "" + echo -e "${RED}KRITISKE FUND:${NC}" + echo " - 99.8 millioner DKK tabt potentiale" + echo " - 0.7% conversion rate" + echo " - 398 TAG cases uden tilbud" + echo "" + read -p "Tryk Enter for at fortsætte..." + demo_menu +} + +main() { + print_banner + demo_menu +} + +main "$@" diff --git a/backend/scripts/legacy_tag_opgaver.sh b/backend/scripts/legacy_tag_opgaver.sh new file mode 100644 index 0000000..200417b --- /dev/null +++ b/backend/scripts/legacy_tag_opgaver.sh @@ -0,0 +1,240 @@ +#!/usr/bin/env bash +# TAG Opgaver - KUN VIRKELIG API DATA +# Ingen estimater, kun faktiske data fra API endpoints +set -e + +OUT_DIR="./ordrestyring_export" + +echo "=== TAG OPGAVER - KUN VIRKELIG API DATA ===" +echo "Dato: $(date)" +echo + +# Tjek at vi har API data +if [[ ! -f "$OUT_DIR/cases.jsonl" ]]; then + echo "Henter API data først..." + ./ordrecheck_simple.sh --key cRD7xfeoiGh1OhzV +fi + +# Find TAG opgaver fra cases API +echo "Finder TAG opgaver fra all_cases.jsonl..." +if [[ -f "$OUT_DIR/all_cases.jsonl" ]]; then + grep -i "tag\|eternit\|tegl\|rende\|velux\|rygning" "$OUT_DIR/all_cases.jsonl" > "$OUT_DIR/tag_cases.jsonl" 2>/dev/null || echo -n "" +elif [[ -f "$OUT_DIR/cases_with_offers.jsonl" ]]; then + grep -i "tag\|eternit\|tegl\|rende\|velux\|rygning" "$OUT_DIR/cases_with_offers.jsonl" > "$OUT_DIR/tag_cases.jsonl" 2>/dev/null || echo -n "" +else + echo "Ingen cases data fundet" + exit 1 +fi + +tag_count=$(wc -l < "$OUT_DIR/tag_cases.jsonl" 2>/dev/null || echo "0") +echo "Fundet $tag_count TAG opgaver" + +if [[ $tag_count -eq 0 ]]; then + echo "Ingen TAG opgaver fundet i API data" + exit 1 +fi + +# Generer komplet CSV med alle virkelige data +generate_complete_csv() { + local csv_file="$OUT_DIR/tag_opgaver_komplet_API_data.csv" + + echo "case_number,customer_number,creation_date,description,status,offer_number,main_technician,additional_technicians,yourref,requestor,work_done,remarks,department,no_materials,sub_number,case_type,delivery_address,contact,hours_registered,materials_registered,costprice_total_oere,offer_lines_count" > "$csv_file" + + local total_cases=0 + local cases_with_offers=0 + local cases_with_hours=0 + local cases_with_materials=0 + + echo "Genererer CSV med alle API felter..." + + while IFS= read -r case_line; do + # Hent alle case felter fra API + local case_number=$(echo "$case_line" | jq -r '.case_number // "N/A"') + local customer_number=$(echo "$case_line" | jq -r '.customer_number // "N/A"') + local creation_date=$(echo "$case_line" | jq -r '.creation_date // .created_at // "N/A"') + local description=$(echo "$case_line" | jq -r '.description // ""' | tr '"' "'" | tr '\n\r' ' ') + local status=$(echo "$case_line" | jq -r '.status // "N/A"') + local offer_number=$(echo "$case_line" | jq -r '.offer_number // ""') + local main_technician=$(echo "$case_line" | jq -r '.main_technician // "N/A"') + local additional_technicians=$(echo "$case_line" | jq -r '.additional_technicians // ""' | tr '"' "'" | tr '\n\r' ' ') + local yourref=$(echo "$case_line" | jq -r '.yourref // ""' | tr '"' "'" | tr '\n\r' ' ') + local requestor=$(echo "$case_line" | jq -r '.requestor // ""' | tr '"' "'" | tr '\n\r' ' ') + local work_done=$(echo "$case_line" | jq -r '.work_done // ""' | tr '"' "'" | tr '\n\r' ' ') + local remarks=$(echo "$case_line" | jq -r '.remarks // ""' | tr '"' "'" | tr '\n\r' ' ') + local department=$(echo "$case_line" | jq -r '.department // "N/A"') + local no_materials=$(echo "$case_line" | jq -r '.no_materials // false') + local sub_number=$(echo "$case_line" | jq -r '.sub_number // "N/A"') + local case_type=$(echo "$case_line" | jq -r '.case_type // "N/A"') + local delivery_address=$(echo "$case_line" | jq -r '.delivery_address // "N/A"') + local contact=$(echo "$case_line" | jq -r '.contact // ""' | tr '"' "'" | tr '\n\r' ' ') + + total_cases=$((total_cases + 1)) + + # Konverter dato til læsbar format + local readable_date="N/A" + if [[ "$creation_date" != "N/A" && "$creation_date" != "null" && $creation_date -gt 0 ]]; then + readable_date=$(date -d "@$creation_date" '+%Y-%m-%d %H:%M' 2>/dev/null || echo "$creation_date") + fi + + # Tjek om der er tilbud + local has_offer="Nej" + if [[ -n "$offer_number" && "$offer_number" != "null" && "$offer_number" != "N/A" && "$offer_number" != "" ]]; then + has_offer="Ja" + cases_with_offers=$((cases_with_offers + 1)) + fi + + # Tjek timer fra hours API + local hours_registered=0 + local costprice_total=0 + if [[ -f "$OUT_DIR/hours.jsonl" ]]; then + while IFS= read -r hour_line; do + local hour_case=$(echo "$hour_line" | jq -r '.new_case_number // ""') + if [[ "$hour_case" == "$case_number" ]]; then + local start_time=$(echo "$hour_line" | jq -r '.start_time // 0') + local stop_time=$(echo "$hour_line" | jq -r '.stop_time // 0') + local costprice=$(echo "$hour_line" | jq -r '.costprice // 0') + + if [[ $start_time -gt 0 && $stop_time -gt 0 ]]; then + local duration=$((stop_time - start_time)) + local hours=$((duration / 3600)) + hours_registered=$((hours_registered + hours)) + costprice_total=$((costprice_total + costprice)) + fi + fi + done < "$OUT_DIR/hours.jsonl" + fi + + if [[ $hours_registered -gt 0 ]]; then + cases_with_hours=$((cases_with_hours + 1)) + fi + + # Tjek materialer fra case-materials API (hvis tilgængeligt) + local materials_registered=0 + if [[ -f "$OUT_DIR/materials.jsonl" ]]; then + materials_registered=$(grep "\"case_number\":\"$case_number\"" "$OUT_DIR/materials.jsonl" 2>/dev/null | wc -l) + if [[ $materials_registered -gt 0 ]]; then + cases_with_materials=$((cases_with_materials + 1)) + fi + fi + + # Tjek offer lines (hvis tilgængeligt) + local offer_lines_count=0 + if [[ -n "$offer_number" && "$offer_number" != "null" && -f "$OUT_DIR/offer_${offer_number}_lines.json" ]]; then + offer_lines_count=$(jq '. | length' "$OUT_DIR/offer_${offer_number}_lines.json" 2>/dev/null || echo "0") + fi + + # Skriv til CSV (alle felter fra API) + echo "$case_number,$customer_number,\"$readable_date\",\"$description\",$status,\"$offer_number\",$main_technician,\"$additional_technicians\",\"$yourref\",\"$requestor\",\"$work_done\",\"$remarks\",$department,$no_materials,$sub_number,$case_type,$delivery_address,\"$contact\",$hours_registered,$materials_registered,$costprice_total,$offer_lines_count" >> "$csv_file" + + done < "$OUT_DIR/tag_cases.jsonl" + + echo + echo "==========================================" + echo "TAG OPGAVER STATISTIK (API DATA)" + echo "==========================================" + printf "Total TAG opgaver: %d\n" $total_cases + printf "Cases med tilbud: %d\n" $cases_with_offers + printf "Cases med timer: %d\n" $cases_with_hours + printf "Cases med materialer: %d\n" $cases_with_materials + + if [[ $total_cases -gt 0 ]]; then + local offer_pct=$(echo "scale=1; $cases_with_offers * 100 / $total_cases" | bc -l 2>/dev/null || echo "0") + local hours_pct=$(echo "scale=1; $cases_with_hours * 100 / $total_cases" | bc -l 2>/dev/null || echo "0") + local materials_pct=$(echo "scale=1; $cases_with_materials * 100 / $total_cases" | bc -l 2>/dev/null || echo "0") + + printf "Tilbuds rate: %s%%\n" "$offer_pct" + printf "Timer rate: %s%%\n" "$hours_pct" + printf "Materialer rate: %s%%\n" "$materials_pct" + fi + echo + echo "CSV fil genereret: $csv_file" + echo "Åbn i Excel for komplet oversigt af alle TAG opgaver" +} + +# Generer også en detaljeret timer rapport +generate_hours_details() { + local hours_file="$OUT_DIR/tag_timer_detaljer_API.csv" + + echo "case_number,emp_id,start_time,stop_time,hours_worked,remark,costprice_oere,costprice_dkk,hour_type,customer_internal_number" > "$hours_file" + + if [[ ! -f "$OUT_DIR/hours.jsonl" ]]; then + echo "Ingen timer data tilgængeligt" + return + fi + + echo "Genererer detaljeret timer rapport..." + local total_tag_hours=0 + local total_tag_costprice=0 + + # Find timer for TAG cases + while IFS= read -r case_line; do + local case_number=$(echo "$case_line" | jq -r '.case_number // "N/A"') + + # Find timer for denne case + while IFS= read -r hour_line; do + local hour_case=$(echo "$hour_line" | jq -r '.new_case_number // ""') + if [[ "$hour_case" == "$case_number" ]]; then + local emp_id=$(echo "$hour_line" | jq -r '.emp_id // "N/A"') + local start_time=$(echo "$hour_line" | jq -r '.start_time // 0') + local stop_time=$(echo "$hour_line" | jq -r '.stop_time // 0') + local remark=$(echo "$hour_line" | jq -r '.remark // ""' | tr '"' "'" | tr '\n\r' ' ') + local costprice=$(echo "$hour_line" | jq -r '.costprice // 0') + local hour_type=$(echo "$hour_line" | jq -r '.hour_type // "N/A"') + local customer_internal_number=$(echo "$hour_line" | jq -r '.customer_internal_number // ""') + + if [[ $start_time -gt 0 && $stop_time -gt 0 ]]; then + local duration=$((stop_time - start_time)) + local hours_worked=$(echo "scale=2; $duration / 3600" | bc -l 2>/dev/null || echo "0") + local costprice_dkk=$(echo "scale=2; $costprice / 100" | bc -l 2>/dev/null || echo "0") + + # Konverter timestamps + local start_readable=$(date -d "@$start_time" '+%Y-%m-%d %H:%M' 2>/dev/null || echo "$start_time") + local stop_readable=$(date -d "@$stop_time" '+%Y-%m-%d %H:%M' 2>/dev/null || echo "$stop_time") + + total_tag_hours=$(echo "$total_tag_hours + $hours_worked" | bc -l 2>/dev/null || echo "$total_tag_hours") + total_tag_costprice=$((total_tag_costprice + costprice)) + + echo "$case_number,$emp_id,\"$start_readable\",\"$stop_readable\",$hours_worked,\"$remark\",$costprice,$costprice_dkk,$hour_type,\"$customer_internal_number\"" >> "$hours_file" + fi + fi + done < "$OUT_DIR/hours.jsonl" + + done < "$OUT_DIR/tag_cases.jsonl" + + local total_costprice_dkk=$(echo "scale=2; $total_tag_costprice / 100" | bc -l 2>/dev/null || echo "0") + + echo + echo "==========================================" + echo "TAG TIMER STATISTIK (API DATA)" + echo "==========================================" + echo "Total timer på TAG opgaver: $total_tag_hours timer" + echo "Total kostpris: $total_tag_costprice øre ($total_costprice_dkk DKK)" + echo + echo "Timer detaljer CSV: $hours_file" +} + +# Kør alle rapporter +generate_complete_csv +echo +generate_hours_details + +echo +echo "==========================================" +echo "ALLE FILER GENERERET - KUN API DATA" +echo "==========================================" +echo "1. $OUT_DIR/tag_opgaver_komplet_API_data.csv - Komplet oversigt" +echo "2. $OUT_DIR/tag_timer_detaljer_API.csv - Timer detaljer" +echo +echo "VIGTIGE KOLONNER I CSV:" +echo "• case_number - API case nummer" +echo "• customer_number - API kunde nummer" +echo "• creation_date - faktisk oprettelsesdato" +echo "• description - opgave beskrivelse fra API" +echo "• status - API status kode" +echo "• offer_number - tilbudsnummer (tom hvis intet)" +echo "• hours_registered - faktiske timer fra hours API" +echo "• costprice_total_oere - faktisk kostpris fra hours API" +echo "• materials_registered - antal materialer fra API" +echo +echo "BEMÆRK: Kun faktiske data fra API - ingen estimater!" +echo "Åbn CSV filerne i Excel for komplet analyse" diff --git a/backend/scripts/oekonomi_analyser.sh b/backend/scripts/oekonomi_analyser.sh new file mode 100644 index 0000000..6cc2b0c --- /dev/null +++ b/backend/scripts/oekonomi_analyser.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Økonomi Analyser - Server version + +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/../functions/api_client.sh" +source "$SCRIPT_DIR/../functions/analyzer.sh" + +usage() { + echo "Økonomi Analyser - Tilbudsgivern Server" + echo "Usage: $0 [OPTIONS]" + echo "" + echo "OPTIONS:" + echo " --key API_KEY API nøgle (påkrævet)" + echo " --year YEAR År til analyse (default: 2025)" + echo " --update Hent nye data fra API" + echo " --help Vis denne hjælp" + echo "" + echo "EKSEMPLER:" + echo " $0 --key ABC123 --year 2025" + echo " $0 --key ABC123 --year 2024 --update" +} + +main() { + local api_key="" + local year="2025" + local update_data=false + + # Parse argumenter + while [[ $# -gt 0 ]]; do + case $1 in + --key) + api_key="$2" + shift 2 + ;; + --year) + year="$2" + shift 2 + ;; + --update) + update_data=true + shift + ;; + --help) + usage + exit 0 + ;; + *) + echo "Ukendt option: $1" + usage + exit 1 + ;; + esac + done + + if [[ -z "$api_key" ]]; then + echo "API nøgle mangler" + usage + exit 1 + fi + + # Opret mapper + mkdir -p "$DATA_DIR" "$REPORTS_DIR" + + # Hent data hvis requested + if [[ "$update_data" == true ]]; then + echo "=== HENTER DATA FRA API ===" + fetch_all_cases "$api_key" + fetch_hours_data "$api_key" + echo "" + fi + + echo "=== ANALYSERER ØKONOMI FOR $year ===" + generate_monthly_economics "$year" + echo "" + + echo "=== ØKONOMI ANALYSE FULDFØRT ===" + echo "Data dir: $DATA_DIR" + echo "Rapporter dir: $REPORTS_DIR" +} + +main "$@" diff --git a/backend/scripts/tag_analyser.sh b/backend/scripts/tag_analyser.sh new file mode 100644 index 0000000..d99c9e8 --- /dev/null +++ b/backend/scripts/tag_analyser.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +# TAG Opgaver Analyser - Server version + +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/../functions/api_client.sh" +source "$SCRIPT_DIR/../functions/analyzer.sh" + +usage() { + echo "TAG Analyser - Tilbudsgivern Server" + echo "Usage: $0 [OPTIONS]" + echo "" + echo "OPTIONS:" + echo " --key API_KEY API nøgle (påkrævet)" + echo " --update Hent nye data fra API" + echo " --task-type TYPE Analyser specifik opgave type" + echo " --help Vis denne hjælp" + echo "" + echo "EKSEMPLER:" + echo " $0 --key ABC123 --update" + echo " $0 --key ABC123 --task-type tag" + echo " $0 --key ABC123 --task-type b7" +} + +main() { + local api_key="" + local update_data=false + local task_type="" + + # Parse argumenter + while [[ $# -gt 0 ]]; do + case $1 in + --key) + api_key="$2" + shift 2 + ;; + --update) + update_data=true + shift + ;; + --task-type) + task_type="$2" + shift 2 + ;; + --help) + usage + exit 0 + ;; + *) + echo "Ukendt option: $1" + usage + exit 1 + ;; + esac + done + + if [[ -z "$api_key" ]]; then + echo "API nøgle mangler" + usage + exit 1 + fi + + # Opret mapper + mkdir -p "$DATA_DIR" "$REPORTS_DIR" + + # Hent data hvis requested + if [[ "$update_data" == true ]]; then + echo "=== HENTER DATA FRA API ===" + fetch_all_cases "$api_key" + fetch_hours_data "$api_key" + echo "" + fi + + # Analyser opgave type + if [[ -n "$task_type" ]]; then + echo "=== ANALYSERER $task_type OPGAVER ===" + search_task_type "$task_type" + analyze_task_type "$task_type" + echo "" + fi + + echo "=== TAG ANALYSER FULDFØRT ===" + echo "Data dir: $DATA_DIR" + echo "Rapporter dir: $REPORTS_DIR" +} + +main "$@" diff --git a/build-and-test.sh b/build-and-test.sh index 7f0eefc..1a0972b 100755 --- a/build-and-test.sh +++ b/build-and-test.sh @@ -35,6 +35,11 @@ else error "Database connection failed" fi +# Step 1.5: Flush PM2 logs +info "Step 1.5: Flushing old logs..." +pm2 flush tilbudgivern-unified > /dev/null 2>&1 +success "Logs flushed" + # Step 2: Backend API Test info "Step 2: Testing backend APIs..." if curl -s https://tilbudsgiveren.alw.dk/api/categories/list | jq -e '.success' > /dev/null 2>&1; then @@ -101,3 +106,9 @@ echo "🌐 Access your application at: https://tilbudsgiveren.alw.dk" echo "🔍 Monitor with: pm2 monit" echo "📋 View logs with: pm2 logs tilbudgivern-unified" echo "" + +# Step 7: Show recent logs for review +echo "📋 Recent Logs (last 10 lines):" +echo "================================" +pm2 logs tilbudgivern-unified --lines 10 --nostream +echo "" diff --git a/frontend/src/App.js b/frontend/src/App.js index a62cc12..a4cfc37 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -5,13 +5,12 @@ import ProjectFlow from './components/ProjectFlow'; import ProjectReview from './components/ProjectReview'; import CompletedQuotes from './components/CompletedQuotes'; import MaterialsList from './MaterialsList'; -import BygmaProducts from './BygmaProducts'; import './components/ProjectReview.css'; const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:4030'; function App() { - const [currentView, setCurrentView] = useState('projects'); // 'projects', 'project-review', 'completed-quotes', 'materials', 'bygma-products', 'openai-usage' + const [currentView, setCurrentView] = useState('projects'); // 'projects', 'project-review', 'completed-quotes', 'materials', 'openai-usage' // Authentication state const [isAuthenticated, setIsAuthenticated] = useState(false); @@ -150,14 +149,6 @@ function App() { > 🧱 Materialer - + + + + + + +
+ + + +
+ + + - - - - - - - + + + + + + + {sortedMaterials.map((material) => ( {editingMaterial === material.id ? ( - // Edit mode + // Edit mode - matcher CSV struktur: Produktnavn, Kategori, Leverandør, Enhedspris, Enhed, Beskrivelse, Handlinger <> ) : ( - // View mode + // View mode - matcher CSV struktur: Produktnavn, Kategori, Leverandør, Enhedspris, Enhed, Beskrivelse, Handlinger <> - - - - - - - + +
MaterialeKategoriEnhedPrisLeverandørBeskrivelseHandlingerProduktnavnKategoriLeverandørEnhedsprisEnhedBeskrivelseHandlinger
{ value={editMaterialForm.name} onChange={(e) => setEditMaterialForm(prev => ({...prev, name: e.target.value}))} className="edit-input" + placeholder="Produktnavn" /> @@ -512,16 +605,19 @@ const MaterialsList = ({ apiBaseUrl }) => { > {categories.map(cat => ( - + ))} setEditMaterialForm(prev => ({...prev, unit: e.target.value}))} + value={editMaterialForm.supplier_name} + onChange={(e) => setEditMaterialForm(prev => ({...prev, supplier_name: e.target.value}))} className="edit-input" + placeholder="Leverandør" /> @@ -530,14 +626,16 @@ const MaterialsList = ({ apiBaseUrl }) => { value={editMaterialForm.unit_price} onChange={(e) => setEditMaterialForm(prev => ({...prev, unit_price: e.target.value}))} className="edit-input" + placeholder="Enhedspris" /> setEditMaterialForm(prev => ({...prev, supplier_name: e.target.value}))} + value={editMaterialForm.unit} + onChange={(e) => setEditMaterialForm(prev => ({...prev, unit: e.target.value}))} className="edit-input" + placeholder="Enhed (m², stk, kg)" /> @@ -567,34 +665,35 @@ const MaterialsList = ({ apiBaseUrl }) => { + {material.name || material.product_name} - - {material.category || material.subcategory || '-'} + + + {getCategoryDisplayName(material.category || material.subcategory)} - {material.unit || material.sales_unit || '-'} - - {formatCurrency(material.unit_price || material.price)} - + {material.supplier_name || (material.source === 'bygma' ? 'Bygma' : '-')} - {material.description ? - (material.description.length > 40 ? - material.description.substring(0, 40) + '...' : - material.description - ) : '-' - } + + {formatCurrency(material.unit_price || material.price)} + + {material.unit || material.sales_unit || '-'} + + {material.description || '-'} + {material.source !== 'bygma' && ( <>