<?php
declare(strict_types=1);
require_once __DIR__.'/app/Helpers/bootstrap.php';
require_once __DIR__.'/app/Helpers/note-images.php';
ob_start(static function (string $html): string {
    return language() !== 'de' ? str_replace('Noch keine Notizen vorhanden.', t('notes.empty'), $html) : $html;
});
ob_start(static function (string $html): string {
    if (language() === 'de') { return $html; }
    $script = '<script>(function(){const q=s=>document.querySelector(s),qa=s=>[...document.querySelectorAll(s)];const p=new URLSearchParams(location.search),view=p.get("view")||"all",scope=p.has("item")?"item":p.has("day")?"day":view;const labels={trip:"About this trip",day:"Note for day",item:"Note for program item",notesTrip:"Notes for trip",notesDay:"Notes for day",notesItem:"Notes for program item",images:"Images",hint:"(maximum 3, 10 MB each)",note:"Note",title:"Title",optional:"(optional)"};const form=q("#note-form");if(form){const title=form.querySelector("input[name=title]"),image=form.querySelector("#images"),plain=qa("#note-form label");if(title){const label=title.closest("label");if(label&&label.firstChild)label.firstChild.nodeValue=labels.title+" ";const muted=label&&label.querySelector(".muted");if(muted)muted.textContent=labels.optional;}if(plain[1])plain[1].textContent=labels.note;if(image){const label=image.closest("label");if(label&&label.firstChild)label.firstChild.nodeValue=labels.images+" ";const muted=label&&label.querySelector(".muted");if(muted)muted.textContent=labels.hint;}}const h2=qa("main>.section h2");if(h2[0]&&form)h2[0].textContent=scope==="item"?labels.item:scope==="day"?labels.day:"Note for trip";if(h2.length){const last=h2[h2.length-1];last.textContent=scope==="item"?labels.notesItem:scope==="day"?labels.notesDay:view==="trip"?labels.trip:view==="days"?"For days":view==="items"?"For program items":"All notes";}qa(".trip-notes h3").forEach(e=>e.textContent=labels.trip);})();</script>';
    return str_replace('</body>', $script . '</body>', $html);
});
$noteUi = [
    'back' => t('common.back_to_trip'), 'title' => t('notes.title'), 'all' => t('trip.all_notes'), 'trip' => t('trip.to_trip'), 'days' => t('trip.to_days'), 'items' => t('trip.to_items'),
    'add_trip' => t('notes.add_trip'), 'add_day' => t('notes.add_day'), 'add_item' => t('notes.add_item'), 'for_trip' => t('trip.to_trip'), 'for_day' => t('notes.for_day'), 'for_item' => t('notes.for_item'),
    'saved' => t('notes.saved'), 'empty' => t('notes.empty'), 'title_field' => t('notes.field_title'), 'note_field' => t('notes.field_note'), 'optional' => '(' . t('common.optional') . ')',
    'images' => t('common.images'), 'images_hint' => t('common.images_hint'), 'save' => t('common.save'), 'edit' => t('common.edit'), 'delete' => t('common.delete'), 'updated' => t('notes.updated'), 'untitled' => t('notes.untitled'),
    'bold' => t('editor.bold'), 'italic' => t('editor.italic'), 'list' => t('editor.list'), 'numbered' => t('editor.numbered_list'), 'link' => t('editor.link'), 'style' => t('editor.style'), 'normal' => t('editor.normal'), 'heading' => t('editor.heading'), 'small_heading' => t('editor.small_heading'),
    'note_singular' => t('notes.singular'), 'note_plural' => t('notes.plural'), 'close' => t('common.close'), 'previous' => t('common.previous_image'), 'next' => t('common.next_image'), 'image_alt' => t('notes.image_alt'),
];
register_shutdown_function(static function () use ($noteUi): void {
    $json = json_encode($noteUi, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
    echo '<script>(function(){const x=' . $json . ';document.documentElement.lang=' . tjs('language.en') . '===' . tjs('language.en') . '&&document.documentElement.lang||document.documentElement.lang;const p=new URLSearchParams(location.search),v=p.get("view")||"all",scope=p.has("item")?"item":p.has("day")?"day":v;document.title=x.title+" · TripTale";const back=document.querySelector("a.back");if(back)back.textContent=x.back;const h1=document.querySelector("main>h1");if(h1)h1.textContent=x.title;const summary=document.querySelector(".notes-filter summary");const label=scope==="item"?x.add_item:scope==="day"?x.add_day:v==="trip"?x.trip:v==="days"?x.days:v==="items"?x.items:x.all;if(summary)summary.textContent=label+" ▾";document.querySelectorAll(".notes-filter nav a").forEach((a,i)=>a.textContent=[x.all,x.trip,x.days,x.items][i]);document.querySelectorAll(".success").forEach(e=>{if(e.textContent.trim()==="Notiz gespeichert.")e.textContent=x.saved});const sections=document.querySelectorAll("main>.section");if(sections[0]&&document.getElementById("note-form")){sections[0].querySelector("h2").textContent=scope==="item"?x.add_item:scope==="day"?x.add_day:x.add_trip;}if(sections[sections.length-1]){const h=sections[sections.length-1].querySelector("h2");if(h)h.textContent=scope==="item"?x.for_item:scope==="day"?x.for_day:v==="trip"?x.trip:v==="days"?x.days:v==="items"?x.items:x.all;}const titleInput=document.querySelector("#note-form input[name=title]");if(titleInput){const l=titleInput.closest("label");if(l&&l.firstChild)l.firstChild.nodeValue=x.title_field+" ";const m=l&&l.querySelector(".muted");if(m)m.textContent=x.optional;}const editor=document.getElementById("editor");if(editor){const labels={bold:x.bold,italic:x.italic,insertUnorderedList:x.list,insertOrderedList:x.numbered};document.querySelectorAll("[data-command]").forEach(b=>b.textContent=labels[b.dataset.command]||b.textContent);const link=document.getElementById("link");if(link)link.textContent=x.link;const s=document.getElementById("style");if(s){s.options[0].text=x.style;s.options[1].text=x.normal;s.options[2].text=x.heading;s.options[3].text=x.small_heading;}}const img=document.getElementById("images");if(img){const l=img.closest("label");if(l&&l.firstChild)l.firstChild.nodeValue=x.images+" ";const m=l&&l.querySelector(".muted");if(m)m.textContent=x.images_hint;}document.querySelectorAll("#note-form button:not([type])").forEach(b=>b.textContent=x.save);document.querySelectorAll("article.note").forEach(n=>{const strong=n.querySelector("strong");if(strong&&strong.textContent.trim()==="Ohne Titel")strong.textContent=x.untitled;const date=n.querySelector(".date");if(date)date.innerHTML=date.innerHTML.replace("Zuletzt geändert:",x.updated);const edit=n.querySelector("a.button");if(edit)edit.textContent=x.edit;const del=n.querySelector("button.delete");if(del)del.textContent=x.delete;});document.querySelectorAll(".note-count").forEach(e=>e.textContent=e.textContent.replace(/(\d+)\s+Notiz(en)?/,(m,n,plural)=>n+" "+(plural?x.note_plural:x.note_singular)));document.querySelectorAll(".note-subheading").forEach(e=>{if(e.textContent.includes("Programmpunkt"))e.textContent=x.for_item;else e.textContent=x.for_day;});document.querySelectorAll(".note-gallery-image").forEach(i=>i.alt=x.image_alt);document.querySelectorAll(".image-lightbox .lightbox-close").forEach(b=>b.setAttribute("aria-label",x.close));document.querySelectorAll(".image-lightbox .lightbox-prev").forEach(b=>b.setAttribute("aria-label",x.previous));document.querySelectorAll(".image-lightbox .lightbox-next").forEach(b=>b.setAttribute("aria-label",x.next));})();</script>';
});
register_shutdown_function(static function (): void {
    echo '<script>setTimeout(function(){var label=' . tjs('trip.day') . ';document.querySelectorAll(".notes-overview > details.day:not(.trip-notes) h3").forEach(function(el){var text=el.textContent.trim(),m=text.match(/^(?:Tag|Day)\\s+(\\d+)(?:\\s+·\\s+(?:Tag|Day)\\s+\\1)?$/i);if(m)el.textContent=label+" "+m[1];});},0);</script>';
});
$user=require_login();$tripId=filter_input(INPUT_GET,'id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);if(!$tripId){exit('Reise nicht gefunden.');}
if($user['role']==='main_admin'){$q=db()->prepare('SELECT id,title FROM '.table('trips').' WHERE id=:id');$q->execute([':id'=>$tripId]);}else{$q=db()->prepare('SELECT t.id,t.title FROM '.table('trips').' t WHERE t.id=:id AND (t.created_by=:creator OR EXISTS(SELECT 1 FROM '.table('trip_admins').' a WHERE a.trip_id=t.id AND a.user_id=:admin) OR EXISTS(SELECT 1 FROM '.table('trip_participants').' p WHERE p.trip_id=t.id AND p.user_id=:participant))');$q->execute([':id'=>$tripId,':creator'=>$user['id'],':admin'=>$user['id'],':participant'=>$user['id']]);}$trip=$q->fetch();if(!$trip){http_response_code(403);exit('Kein Zugriff.');}
$dayId=filter_input(INPUT_GET,'day',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$itemId=filter_input(INPUT_GET,'item',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$view=(string)($_GET['view']??'all');if(!in_array($view,['all','trip','days','items'],true)){$view='all';}if($itemId){$dayId=null;if($view==='all')$view='item';$q=db()->prepare('SELECT i.id,d.id AS context_day_id,d.day_number,d.title AS day_title,COALESCE(i.title,a.name,ac.name,r.name,cp.name,\'Programmpunkt\') AS title FROM '.table('trip_day_items').' i JOIN '.table('trip_days').' d ON d.id=i.trip_day_id LEFT JOIN '.table('attractions').' a ON i.item_type=\'attraction\' AND a.id=i.reference_id LEFT JOIN '.table('accommodations').' ac ON i.item_type=\'accommodation\' AND ac.id=i.reference_id LEFT JOIN '.table('restaurants').' r ON i.item_type=\'restaurant\' AND r.id=i.reference_id LEFT JOIN '.table('custom_points').' cp ON i.item_type=\'catalog_custom\' AND cp.id=i.reference_id WHERE i.id=:item AND d.trip_id=:trip');$q->execute([':item'=>$itemId,':trip'=>$tripId]);$context=$q->fetch();if(!$context){exit('Programmpunkt nicht gefunden.');}$dayId=(int)$context['context_day_id'];}elseif($dayId){if($view==='all')$view='day';$q=db()->prepare('SELECT id,day_number,title FROM '.table('trip_days').' WHERE id=:day AND trip_id=:trip');$q->execute([':day'=>$dayId,':trip'=>$tripId]);$context=$q->fetch();if(!$context){exit('Tag nicht gefunden.');}}else{$context=null;}$returnView=$itemId?'items':($dayId?'days':(in_array($view,['trip','days','items'],true)?$view:'all'));$returnLocation=$_SERVER['PHP_SELF'].'?id='.$tripId.($returnView!=='all'?'&view='.$returnView:'');
$scope='trip_day_id IS NULL AND trip_day_item_id IS NULL';$scopeParams=[];if($dayId){$scope='trip_day_id=:day AND trip_day_item_id IS NULL';$scopeParams=[':day'=>$dayId];}if($itemId){$scope='trip_day_item_id=:item';$scopeParams=[':item'=>$itemId];}
$editId=filter_input(INPUT_GET,'note',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$edit=['title'=>'','body'=>''];$editImages=[];$editLocation=$_SERVER['PHP_SELF'].'?id='.$tripId.($itemId?'&item='.$itemId.'&view=items':($dayId?'&day='.$dayId.'&view=days':'&view=trip'));if($editId){$q=db()->prepare('SELECT id,title,body FROM '.table('trip_private_notes').' WHERE id=:id AND trip_id=:trip AND user_id=:user AND '.$scope);$q->execute([':id'=>$editId,':trip'=>$tripId,':user'=>$user['id']]+$scopeParams);$edit=$q->fetch();if(!$edit){exit('Notiz nicht gefunden.');}$editImages=note_image_paths($editId);}
$error=null;if($_SERVER['REQUEST_METHOD']==='POST'){verify_csrf();$action=(string)($_POST['action']??'save');$id=filter_input(INPUT_POST,'note_id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);$base=[':trip'=>$tripId,':user'=>$user['id']]+$scopeParams;$deleteImageId=filter_input(INPUT_POST,'delete_image_id',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);if($deleteImageId&&$id){$imageId=$deleteImageId;$q=db()->prepare('SELECT ni.id,ni.file_path FROM '.table('trip_private_note_images').' ni JOIN '.table('trip_private_notes').' n ON n.id=ni.note_id WHERE ni.id=:image AND n.id=:id AND n.trip_id=:trip AND n.user_id=:user AND '.$scope);$q->execute([':image'=>$imageId,':id'=>$id]+$base);$image=$q->fetch();if(!$image){exit('Bild nicht gefunden.');}$q=db()->prepare('DELETE FROM '.table('trip_private_note_images').' WHERE id=:image');$q->execute([':image'=>$imageId]);note_remove_image_file((string)$image['file_path']);header('Location: '.$editLocation.'&note='.$id.'&image=deleted');exit;}if($action==='delete'&&$id){$q=db()->prepare('SELECT id FROM '.table('trip_private_notes').' WHERE id=:id AND trip_id=:trip AND user_id=:user');$q->execute([':id'=>$id,':trip'=>$tripId,':user'=>$user['id']]);if(!$q->fetch()){exit('Notiz nicht gefunden.');}$images=note_image_paths($id);$q=db()->prepare('DELETE FROM '.table('trip_private_notes').' WHERE id=:id AND trip_id=:trip AND user_id=:user');$q->execute([':id'=>$id,':trip'=>$tripId,':user'=>$user['id']]);foreach($images as $image){note_remove_image_file((string)$image['file_path']);}header('Location: '.$returnLocation.'&deleted=1');exit;}$title=trim((string)($_POST['title']??''));$body=sanitize_rich_text((string)($_POST['body']??''));if($body===''){$error='Bitte eine Notiz eingeben.';}else{$targetId=0;if($id){$q=db()->prepare('UPDATE '.table('trip_private_notes').' SET title=:title,body=:body WHERE id=:id AND trip_id=:trip AND user_id=:user AND '.$scope);$q->execute([':title'=>$title?:null,':body'=>$body,':id'=>$id]+$base);$targetId=$id;}else{$q=db()->prepare('INSERT INTO '.table('trip_private_notes').' (trip_id,user_id,trip_day_id,trip_day_item_id,title,body) VALUES (:trip,:user,:day,:item,:title,:body)');$q->execute([':trip'=>$tripId,':user'=>$user['id'],':day'=>$dayId?:null,':item'=>$itemId?:null,':title'=>$title?:null,':body'=>$body]);$targetId=(int)db()->lastInsertId();}$uploadError=note_store_uploaded_images($targetId,$_FILES['images']??[]);if($uploadError!==null){$error=$uploadError;$editId=$targetId;$editImages=note_image_paths($targetId);}else{header('Location: '.$returnLocation.'&saved=1');exit;}}}
$q=db()->prepare('SELECT n.*,d.day_number,d.title AS day_title,COALESCE(i.title,a.name,ac.name,r.name,cp.name) AS item_title,COALESCE(i.image_path,a.image_path,ac.image_path,r.image_path,cp.image_path) AS item_image FROM '.table('trip_private_notes').' n LEFT JOIN '.table('trip_days').' d ON d.id=n.trip_day_id LEFT JOIN '.table('trip_day_items').' i ON i.id=n.trip_day_item_id LEFT JOIN '.table('attractions').' a ON i.item_type=\'attraction\' AND a.id=i.reference_id LEFT JOIN '.table('accommodations').' ac ON i.item_type=\'accommodation\' AND ac.id=i.reference_id LEFT JOIN '.table('restaurants').' r ON i.item_type=\'restaurant\' AND r.id=i.reference_id LEFT JOIN '.table('custom_points').' cp ON i.item_type=\'catalog_custom\' AND cp.id=i.reference_id WHERE n.trip_id=:trip AND n.user_id=:user ORDER BY d.day_number,i.sort_order,n.updated_at DESC,n.id DESC');$q->execute([':trip'=>$tripId,':user'=>$user['id']]);$all=$q->fetchAll();$imageMap=[];$q=db()->prepare('SELECT ni.note_id,ni.id,ni.file_path FROM '.table('trip_private_note_images').' ni JOIN '.table('trip_private_notes').' n ON n.id=ni.note_id WHERE n.trip_id=:trip AND n.user_id=:user ORDER BY ni.sort_order,ni.id');$q->execute([':trip'=>$tripId,':user'=>$user['id']]);foreach($q->fetchAll() as $image){$imageMap[(int)$image['note_id']][]=$image;}foreach($all as &$note){$note['images']=$imageMap[(int)$note['id']]??[];}unset($note);
$filtered=array_values(array_filter($all,static function($n)use($view,$dayId,$itemId){if($dayId)return(int)$n['trip_day_id']===$dayId&&!$n['trip_day_item_id'];if($itemId)return(int)$n['trip_day_item_id']===$itemId;if($view==='trip')return !$n['trip_day_id']&&!$n['trip_day_item_id'];if($view==='days')return!!$n['trip_day_id']&&!$n['trip_day_item_id'];if($view==='items')return!!$n['trip_day_item_id'];return true;}));
$tripNotes=[];$dayGroups=[];foreach($filtered as $n){$noteDay=(int)($n['trip_day_id']??0);$noteItem=(int)($n['trip_day_item_id']??0);if(!$noteDay){$tripNotes[]=$n;continue;}if(!isset($dayGroups[$noteDay])){$dayGroups[$noteDay]=['number'=>(int)$n['day_number'],'title'=>(string)$n['day_title'],'notes'=>[],'items'=>[]];}if(!$noteItem){$dayGroups[$noteDay]['notes'][]=$n;continue;}if(!isset($dayGroups[$noteDay]['items'][$noteItem])){$dayGroups[$noteDay]['items'][$noteItem]=['title'=>(string)($n['item_title']?:'Programmpunkt'),'image'=>(string)($n['item_image']??''),'notes'=>[]];}$dayGroups[$noteDay]['items'][$noteItem]['notes'][]=$n;}
$canWrite=$dayId||$itemId||$view==='trip'||$editId;
function render_note_cards(array $notes,int $tripId):void{foreach($notes as $note){note_card($note,$tripId,null,null);}}
function note_card(array $n,int $tripId,?int $dayId,?int $itemId):void{$noteDay=(int)($n['trip_day_id']??0);$noteItem=(int)($n['trip_day_item_id']??0);$url='/trip-notes.php?id='.$tripId.($noteItem?'&item='.$noteItem.'&view=items':($noteDay?'&day='.$noteDay.'&view=days':'&view=trip')).'&note='.(int)$n['id'];?><article class="note"><strong><?=htmlspecialchars($n['title']?:'Ohne Titel',ENT_QUOTES,'UTF-8')?></strong><div class="date">Zuletzt geändert: <?=htmlspecialchars(date('d.m.Y H:i',strtotime($n['updated_at'])),ENT_QUOTES,'UTF-8')?></div><div><?=render_rich_text($n['body'])?></div><?php if(!empty($n['images'])):?><div class="note-gallery"><?php foreach($n['images'] as $image):?><img class="note-gallery-image" src="/<?=htmlspecialchars($image['file_path'],ENT_QUOTES,'UTF-8')?>" alt="Bild zur Notiz"><?php endforeach;?></div><?php endif;?><a class="button" href="<?=htmlspecialchars($url,ENT_QUOTES,'UTF-8')?>">Bearbeiten</a><form method="post" class="inline" onsubmit="return confirm('Diese Notiz wirklich löschen?');"><input type="hidden" name="csrf_token" value="<?=htmlspecialchars(csrf_token(),ENT_QUOTES,'UTF-8')?>"><input type="hidden" name="action" value="delete"><input type="hidden" name="note_id" value="<?=(int)$n['id']?>"><button class="delete">Löschen</button></form></article><?php }
?>

<!doctype html><html lang="de"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Meine Notizen · TripTale</title><style>body{font-family:system-ui,sans-serif;background:#f4f6f8;margin:0;padding:28px;color:#17202a}main{max-width:850px;margin:auto;background:#fff;padding:26px;border-radius:14px}.button,button{display:inline-block;padding:9px 12px;background:#126e82;color:#fff;border:0;border-radius:7px;text-decoration:none;font:inherit;font-weight:700;margin-top:8px}.back{background:#e3ebee;color:#126e82}.notes-filter{position:relative;display:inline-block;margin:14px 0}.notes-filter summary{list-style:none;cursor:pointer;background:#126e82;color:#fff;padding:10px 14px;border-radius:7px;font-weight:700}.notes-filter summary::-webkit-details-marker{display:none}.notes-filter nav{position:absolute;z-index:10;min-width:210px;margin-top:6px;padding:8px;background:#fff;border:1px solid #d6e0e4;border-radius:10px;box-shadow:0 6px 20px #0002}.notes-filter nav a{display:block;padding:10px 12px;color:#17202a;text-decoration:none;border-radius:6px;font-weight:700}.notes-filter nav a:hover{background:#eaf3f4;color:#126e82}.section{margin:22px 0;padding:16px;background:#edf5f6;border-left:4px solid #75aeb9;border-radius:10px}.notes-overview{padding:0;background:#fff;border-left:0}.notes-overview>h2{margin:0 0 14px;padding:0 0 10px;border-bottom:1px solid #d6e0e4}.day{margin:16px 0;padding:14px;background:#eaf2f8;border-left:6px solid #4c7897;border-radius:10px}.day>summary,.item>summary{list-style:none;cursor:pointer}.day>summary::-webkit-details-marker,.item>summary::-webkit-details-marker{display:none}.day>summary{display:flex;align-items:center;justify-content:center;gap:10px}.day h3{margin:0;text-align:center;font-size:1.18rem}.day[open]>summary{margin-bottom:12px}.day-content{min-width:0}.trip-notes{background:#e7f4f1;border-left-color:#126e82}.trip-notes h3{color:#0e5968}.item{margin:12px 0 0 18px;padding:13px;background:#fbf2e5;border-left:6px solid #b77a2d;border-radius:9px}.item>summary{display:flex;justify-content:center;gap:10px;align-items:center;flex-wrap:wrap}.item[open]>summary{margin-bottom:10px}.item-title{font-size:1.18rem;font-weight:700;text-align:center}.note-count{color:#59636d;font-size:.88rem;font-weight:400;white-space:nowrap}.notes-thumb{width:56px;height:48px;object-fit:contain;background:#fff;border-radius:6px}.notes-thumb.empty{display:block}.notes-item-image{display:block;width:100%;max-height:340px;object-fit:contain;background:#fff;border-radius:8px;margin:0 0 12px}.note{margin:10px 0;padding:14px;background:#fff;border:1px solid #d6e0e4;border-radius:8px}.note-gallery,.edit-image-gallery{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}.note-gallery img,.edit-image-gallery img{width:110px;height:90px;object-fit:contain;background:#f4f6f8;border-radius:7px}.note-gallery-image{cursor:zoom-in}.image-lightbox{position:fixed;inset:0;z-index:50;display:none;align-items:center;justify-content:center;background:rgba(10,20,28,.9);padding:20px}.image-lightbox.open{display:flex}.image-lightbox img{max-width:calc(100vw - 80px);max-height:calc(100vh - 80px);object-fit:contain;border-radius:8px}.image-lightbox button{position:absolute;margin:0;background:#fff;color:#17202a}.lightbox-close{top:16px;right:18px}.lightbox-prev{left:14px}.lightbox-next{right:14px}.image-lightbox button[hidden]{display:none}.edit-image-gallery>div{position:relative}.image-delete{position:absolute;right:-7px;top:-8px;width:25px;height:25px;min-width:25px;padding:0;margin:0;border-radius:50%;background:#9d2d2d;color:#fff;line-height:21px;font-size:20px;font-weight:500;border:2px solid #fff}.note-subheading{margin:12px 0 8px;color:#40505a;font-size:.95rem;font-weight:700}.date,.muted{color:#59636d;font-size:.9rem;margin:5px 0}.inline{display:inline;margin-left:8px}.delete{background:#9d2d2d}label{display:block;margin-top:13px;font-weight:700}input,textarea{box-sizing:border-box;width:100%;padding:10px;margin-top:5px;border:1px solid #b9c1c8;border-radius:7px;font:inherit}.toolbar{display:flex;gap:5px;flex-wrap:wrap;margin-top:5px;padding:7px;border:1px solid #b9c1c8;border-bottom:0;border-radius:7px 7px 0 0;background:#edf2f3}.toolbar button{margin:0;padding:6px 9px;background:#fff;color:#17202a;border:1px solid #b9c1c8;border-radius:4px}.editor{min-height:140px;padding:11px;border:1px solid #b9c1c8;border-radius:0 0 7px 7px}.success{background:#e6f5e9;padding:10px;border-radius:7px}@media(max-width:600px){body{padding:12px}main{padding:16px}.notes-overview{margin-left:0;margin-right:0}.day{margin:12px 0;padding:12px}.item{margin:10px 0 0 8px;padding:11px}.day h3,.item-title{font-size:1.08rem}.item>summary{gap:8px}.notes-thumb{width:46px;height:42px}.inline{margin-left:6px}}</style></head><body><main><a class="button back" href="/trip.php?id=<?=$tripId?>">← Zurück zur Reise</a><h1>Meine Notizen</h1><p class="muted"><?=htmlspecialchars($trip['title'],ENT_QUOTES,'UTF-8')?></p><?php $selectedLabel=$view==='trip'?'Zur Reise':($view==='days'?'Zu Tagen':($view==='items'?'Zu Programmpunkten':($itemId?'Zum Programmpunkt':($dayId?'Zum Tag':'Alle Notizen')))); ?><details class="notes-filter"><summary><?=htmlspecialchars($selectedLabel,ENT_QUOTES,'UTF-8')?> ▾</summary><nav><a href="?id=<?=$tripId?>">Alle Notizen</a><a href="?id=<?=$tripId?>&view=trip">Zur Reise</a><a href="?id=<?=$tripId?>&view=days">Zu Tagen</a><a href="?id=<?=$tripId?>&view=items">Zu Programmpunkten</a></nav></details><?php if(isset($_GET['saved'])):?><p class="success">Notiz gespeichert.</p><?php endif;?><?php if($canWrite):?><section class="section"><h2><?= $itemId?'Notiz zum Programmpunkt':($dayId?'Notiz zum Tag':'Notiz zur Reise') ?></h2><?php if($context):?><p><?=htmlspecialchars(($dayId?'Tag '.$context['day_number'].' · ':'Tag '.$context['day_number'].' · ').$context['title'],ENT_QUOTES,'UTF-8')?></p><?php endif;?><form method="post" enctype="multipart/form-data" id="note-form"><input type="hidden" name="csrf_token" value="<?=htmlspecialchars(csrf_token(),ENT_QUOTES,'UTF-8')?>"><input type="hidden" name="note_id" value="<?= (int)$editId?>"><input type="hidden" name="body" id="body-value"><label>Titel <span class="muted">(optional)</span><input name="title" value="<?=htmlspecialchars((string)($_POST['title']??$edit['title']),ENT_QUOTES,'UTF-8')?>"></label><label>Notiz</label><div class="toolbar"><button type="button" data-command="bold"><b>Fett</b></button><button type="button" data-command="italic"><i>Kursiv</i></button><button type="button" data-command="insertUnorderedList">Liste</button><button type="button" data-command="insertOrderedList">1. Liste</button><button type="button" id="link">Link</button><select id="style"><option value="">Textstil…</option><option value="p">Normal</option><option value="h2">Überschrift</option><option value="h3">Kleine Überschrift</option></select></div><div id="editor" class="editor" contenteditable="true"><?=render_rich_text((string)($_POST['body']??$edit['body']))?></div><label>Bilder <span class="muted">(maximal 3, je 10 MB)</span><input type="file" id="images" data-existing="<?=count($editImages)?>" name="images[]" accept="image/jpeg,image/png,image/webp" multiple></label><?php if($editImages):?><div class="edit-image-gallery"><?php foreach($editImages as $image):?><div><img src="/<?=htmlspecialchars($image['file_path'],ENT_QUOTES,'UTF-8')?>" alt=""><button class="image-delete" type="submit" name="delete_image_id" value="<?= (int)$image['id']?>" aria-label="Bild löschen" title="Bild löschen" onclick="return confirm('Dieses Bild wirklich löschen?');">×</button></div><?php endforeach;?></div><?php endif;?><button>Speichern</button></form></section><?php endif;?><section class="section notes-overview"><h2><?= $itemId?'Notizen zum Programmpunkt':($dayId?'Notizen zum Tag':($view==='all'?'Alle Notizen':($view==='trip'?'Zur Reise':($view==='days'?'Zu Tagen':'Zu Programmpunkten')))) ?></h2><?php if(!$filtered):?><p class="muted">Noch keine Notizen vorhanden.</p><?php endif;?><?php if(($view==='all'||$view==='trip')&&$tripNotes):?><details class="day trip-notes"<?= $view==='trip'?' open':'' ?>><summary><h3>Zur Reise</h3><span class="note-count"><?=count($tripNotes)?> Notiz<?=count($tripNotes)===1?'':'en'?></span></summary><div class="day-content"><?php render_note_cards($tripNotes,$tripId);?></div></details><?php endif;?><?php foreach($dayGroups as $group):?><?php $groupCount=count($group['notes']);foreach($group['items'] as $countItem){$groupCount+=count($countItem['notes']);} ?><details class="day"<?= $view==='all'?'':' open' ?>><summary><h3>Tag <?=$group['number']?> · <?=htmlspecialchars($group['title'],ENT_QUOTES,'UTF-8')?></h3><span class="note-count"><?=$groupCount?> Notiz<?=$groupCount===1?'':'en'?></span></summary><div class="day-content"><?php if(($view==='all'||$view==='days'||$dayId)&&!empty($group['notes'])):?><p class="note-subheading">Notizen zum Tag</p><?php render_note_cards($group['notes'],$tripId);?><?php endif;?><?php if($view==='all'||$view==='items'||$itemId):?><?php foreach($group['items'] as $itemGroup):?><details class="item"><summary><?php if($itemGroup['image']):?><img class="notes-thumb" src="/<?=htmlspecialchars($itemGroup['image'],ENT_QUOTES,'UTF-8')?>" alt=""><?php endif;?><span class="item-title"><?=htmlspecialchars($itemGroup['title'],ENT_QUOTES,'UTF-8')?></span><span class="note-count"><?=count($itemGroup['notes'])?> Notiz<?=count($itemGroup['notes'])===1?'':'en'?></span></summary><div class="item-content"><?php if($itemGroup['image']):?><img class="notes-item-image" src="/<?=htmlspecialchars($itemGroup['image'],ENT_QUOTES,'UTF-8')?>" alt=""><?php endif;?><p class="note-subheading">Notizen zum Programmpunkt</p><?php render_note_cards($itemGroup['notes'],$tripId);?></div></details><?php endforeach;?><?php endif;?></div></details><?php endforeach;?></section></main><script>const e=document.getElementById('editor');if(e){document.querySelectorAll('[data-command]').forEach(b=>b.onclick=()=>{e.focus();document.execCommand(b.dataset.command,false);});document.getElementById('style').onchange=function(){if(this.value){e.focus();document.execCommand('formatBlock',false,'<'+this.value+'>');this.value='';}};document.getElementById('link').onclick=()=>{const u=prompt('https://');if(u){e.focus();document.execCommand('createLink',false,u);}};document.getElementById('note-form').onsubmit=()=>document.getElementById('body-value').value=e.innerHTML;};document.querySelectorAll('.notes-overview>details.day:not(.trip-notes)').forEach(day=>day.addEventListener('toggle',()=>{if(day.open)document.querySelectorAll('.notes-overview>details.day:not(.trip-notes)').forEach(other=>{if(other!==day)other.removeAttribute('open');});}));document.querySelectorAll('.notes-overview details.item').forEach(item=>item.addEventListener('toggle',()=>{if(item.open)document.querySelectorAll('.notes-overview details.item').forEach(other=>{if(other!==item)other.removeAttribute('open');});}));;const noteGalleryImages=[...document.querySelectorAll('.note-gallery-image')];if(noteGalleryImages.length){let activeImages=[],activeImageIndex=0;const lightbox=document.createElement('div');lightbox.className='image-lightbox';lightbox.innerHTML='<button type="button" class="lightbox-close" aria-label="Schließen">×</button><button type="button" class="lightbox-prev" aria-label="Vorheriges Bild">‹</button><img alt="Bild zur Notiz"><button type="button" class="lightbox-next" aria-label="Nächstes Bild">›</button>';document.body.append(lightbox);const lightboxImage=lightbox.querySelector('img'),previous=lightbox.querySelector('.lightbox-prev'),next=lightbox.querySelector('.lightbox-next');const showImage=()=>{lightboxImage.src=activeImages[activeImageIndex].src;previous.hidden=next.hidden=activeImages.length<2;};const closeLightbox=()=>lightbox.classList.remove('open');noteGalleryImages.forEach(image=>image.addEventListener('click',()=>{activeImages=[...image.closest('.note-gallery').querySelectorAll('.note-gallery-image')];activeImageIndex=activeImages.indexOf(image);showImage();lightbox.classList.add('open');}));previous.onclick=()=>{activeImageIndex=(activeImageIndex-1+activeImages.length)%activeImages.length;showImage();};next.onclick=()=>{activeImageIndex=(activeImageIndex+1)%activeImages.length;showImage();};lightbox.querySelector('.lightbox-close').onclick=closeLightbox;lightbox.addEventListener('click',event=>{if(event.target===lightbox)closeLightbox();});document.addEventListener('keydown',event=>{if(!lightbox.classList.contains('open'))return;if(event.key==='Escape')closeLightbox();if(event.key==='ArrowLeft')previous.click();if(event.key==='ArrowRight')next.click();});}const imageInput=document.getElementById('images');if(imageInput){imageInput.addEventListener('change',()=>{const existing=Number(imageInput.dataset.existing||0);if(existing+imageInput.files.length>3){alert('Du kannst insgesamt höchstens drei Bilder speichern. Bereits vorhanden: '+existing+'.');imageInput.value='';}});}</script></body></html>
