@@ -434,65 +434,80 @@ <h2 class="card-title text-2xl sm:text-3xl border-b border-base-300 pb-3 mb-4">
434434 </ div >
435435 </ footer >
436436 < dialog id ="add_manual_rule_modal " class ="modal ">
437- < div class ="modal-box w-11/12 max-w-3xl ">
437+ < div class ="modal-box w-11/12 max-w-3xl ">
438438 < form method ="dialog ">
439439 < button class ="btn btn-sm btn-circle btn-ghost absolute right-2 top-2 "> ✕</ button >
440440 </ form >
441- < h3 class ="font-bold text-lg mb-4 "> Add New Manual Ingress Rule</ h3 >
442- < form action ="{{ url_for('web.ui_add_manual_rule_route') }} " method ="POST " class ="space-y-4 protocol-aware-form ">
441+ < h3 class ="font-bold text-lg mb-6 "> Add New Manual Ingress Rule</ h3 >
442+ < form action ="{{ url_for('web.ui_add_manual_rule_route') }} " method ="POST " class ="space-y-6 protocol-aware-form ">
443443 < div >
444- < label class ="label " for ="manual_subdomain "> < span class ="label-text "> Subdomain (Optional, e.g., mydevice)</ span > </ label >
445- < input type ="text " id ="manual_subdomain " name ="manual_subdomain " placeholder ="subdomain " class ="input input-bordered w-full " />
446- </ div >
447- < div >
448- < label class ="label " for ="manual_domain_name "> < span class ="label-text "> Domain Name (Required, e.g., example.com)</ span > </ label >
449- < input type ="text " id ="manual_domain_name " name ="manual_domain_name " placeholder ="yourdomain.com " class ="input input-bordered w-full " required />
450- < div class ="text-xs opacity-60 mt-1 "> This will be combined with the subdomain to form the full hostname.</ div >
451- </ div >
452- < div >
453- < label class ="label " for ="manual_path "> < span class ="label-text "> Path (Optional, e.g., /app or /api/v1)</ span > </ label >
454- < input type ="text " id ="manual_path " name ="manual_path " placeholder ="/optional-service-path " class ="input input-bordered w-full " />
455- < div class ="text-xs opacity-60 mt-1 "> If blank, rule applies to the root. Must start with '/' if specified.</ div >
456- </ div >
457- < div >
458- < label class ="label " for ="manual_service_type "> < span class ="label-text "> Service Type (Required)</ span > </ label >
459- < select name ="manual_service_type " id ="manual_service_type " class ="select select-bordered w-full " required >
460- < option value ="" disabled selected > Select type...</ option >
461- < option value ="http "> HTTP</ option >
462- < option value ="https "> HTTPS</ option >
463- < option value ="tcp "> TCP</ option >
464- < option value ="ssh "> SSH</ option >
465- < option value ="rdp "> RDP</ option >
466- < option value ="http_status "> HTTP Status Code</ option >
467- </ select >
468- </ div >
469- < div >
470- < label class ="label " for ="manual_service_address ">
471- < span class ="label-text " id ="manual_service_address_label "> Service Address (Required for most types)</ span >
472- </ label >
473- < div class ="join w-full ">
474- < span id ="manual_service_prefix_span " class ="join-item btn btn-disabled normal-case pointer-events-none hidden bg-base-200 border-base-300 "> </ span >
475- < input type ="text " id ="manual_service_address " name ="manual_service_address " placeholder ="host:port or status code " class ="input input-bordered join-item w-full " />
444+ < h4 class ="text-md font-semibold mb-2 "> Public Hostname</ h4 >
445+ < div class ="grid grid-cols-1 md:grid-cols-12 gap-4 items-end ">
446+ < div class ="md:col-span-4 ">
447+ < label class ="label " for ="manual_subdomain "> < span class ="label-text "> Subdomain</ span > </ label >
448+ < input type ="text " id ="manual_subdomain " name ="manual_subdomain " placeholder ="(optional) subdomain " class ="input input-bordered w-full " />
449+ </ div >
450+ < div class ="md:col-span-5 ">
451+ < label class ="label " for ="manual_domain_name "> < span class ="label-text "> Domain (Required)</ span > </ label >
452+ < input type ="text " id ="manual_domain_name " name ="manual_domain_name " placeholder ="example.com " class ="input input-bordered w-full " required />
453+ < div class ="text-xs opacity-60 mt-1 "> This will be combined with the subdomain to form the full hostname.</ div >
454+ </ div >
455+ < div class ="md:col-span-3 ">
456+ < label class ="label " for ="manual_path "> < span class ="label-text "> Path</ span > </ label >
457+ < div class ="join w-full ">
458+ < span class ="join-item btn btn-disabled normal-case pointer-events-none bg-base-200 border-base-300 !min-h-[3rem] !h-[3rem] px-3 "> /</ span >
459+ < input type ="text " id ="manual_path " name ="manual_path " placeholder ="(optional) path " class ="input input-bordered join-item w-full " />
460+ </ div >
461+ < div class ="text-xs opacity-60 mt-1 "> If blank, rule applies to the root. Must start with '/' if specified.</ div >
462+ </ div >
476463 </ div >
477- < div id ="manual_service_help " class ="text-xs opacity-60 mt-1 "> e.g., 192.168.1.10:8000 or my-service.local:3000 for HTTP/S/TCP etc.</ div >
478464 </ div >
479465 < div >
480- < label class ="label " for ="manual_zone_name_override "> < span class ="label-text "> Cloudflare Zone Name (Override/Specific)</ span > </ label >
481- < input type ="text " id ="manual_zone_name_override " name ="manual_zone_name_override " placeholder ="yourdomain.com (if different from Domain Name or CF_ZONE_ID) " class ="input input-bordered w-full " />
482- {% if CF_ZONE_ID_CONFIGURED and CF_ZONE_ID %}
483- < div class ="text-xs opacity-60 mt-1 "> If blank, DockFlare will attempt to use "Domain Name" to find the zone, or fall back to default CF_ZONE_ID ({{ CF_ZONE_ID[:12] }}...). Use this to explicitly target a different Zone.</ div >
484- {% else %}
485- < div class ="text-xs opacity-60 mt-1 "> If blank, DockFlare will attempt to use "Domain Name" to find the zone. Use this to explicitly target a specific Zone if "Domain Name" is ambiguous or if CF_ZONE_ID is not set.</ div >
486- {% endif %}
466+ < h4 class ="text-md font-semibold mb-2 "> Service</ h4 >
467+ < div class ="grid grid-cols-1 md:grid-cols-2 gap-4 items-end ">
468+ < div >
469+ < label class ="label " for ="manual_service_type "> < span class ="label-text "> Type (Required)</ span > </ label >
470+ < select name ="manual_service_type " id ="manual_service_type " class ="select select-bordered w-full " required >
471+ < option value ="" disabled selected > Select...</ option >
472+ < option value ="http "> HTTP</ option >
473+ < option value ="https "> HTTPS</ option >
474+ < option value ="tcp "> TCP</ option >
475+ < option value ="ssh "> SSH</ option >
476+ < option value ="rdp "> RDP</ option >
477+ < option value ="http_status "> HTTP Status Code</ option >
478+ </ select >
479+ </ div >
480+ < div >
481+ < label class ="label " for ="manual_service_address ">
482+ < span class ="label-text " id ="manual_service_address_label "> URL (Required for most types)</ span >
483+ </ label >
484+ < div class ="join w-full ">
485+ < span id ="manual_service_prefix_span " class ="join-item btn btn-disabled normal-case pointer-events-none hidden bg-base-200 border-base-300 !min-h-[3rem] !h-[3rem] px-3 "> ://</ span >
486+ < input type ="text " id ="manual_service_address " name ="manual_service_address " placeholder ="host:port or status code " class ="input input-bordered join-item w-full " />
487+ </ div >
488+ < div id ="manual_service_help " class ="text-xs opacity-60 mt-1 "> e.g., 192.168.1.10:8000 or my-service.local:3000 for HTTP/S/TCP etc.</ div >
489+ </ div >
490+ </ div >
487491 </ div >
488- < div id ="manual_no_tls_verify_div " class ="form-control ">
489- < label class ="label cursor-pointer ">
490- < span class ="label-text "> Disable TLS Verification (No TLS Verify)</ span >
491- < input type ="checkbox " name ="manual_no_tls_verify " id ="manual_no_tls_verify " class ="checkbox checkbox-sm " />
492- </ label >
493- < div class ="text-xs opacity-60 "> Check if the origin service uses self-signed SSL or is HTTP. (Only applies to HTTP/HTTPS services).</ div >
492+ < div class ="space-y-4 pt-4 border-t border-base-300 ">
493+ < div >
494+ < label class ="label " for ="manual_zone_name_override "> < span class ="label-text "> Cloudflare Zone Name (Override/Specific)</ span > </ label >
495+ < input type ="text " id ="manual_zone_name_override " name ="manual_zone_name_override " placeholder ="yourdomain.com (if different from Domain Name or CF_ZONE_ID) " class ="input input-bordered w-full " />
496+ {% if CF_ZONE_ID_CONFIGURED and CF_ZONE_ID %}
497+ < div class ="text-xs opacity-60 mt-1 "> If blank, DockFlare will use "Domain Name" or default CF_ZONE_ID ({{ CF_ZONE_ID[:12] }}...). Target a different Zone if needed.</ div >
498+ {% else %}
499+ < div class ="text-xs opacity-60 mt-1 "> If blank, DockFlare will use "Domain Name". Target a specific Zone if "Domain Name" is ambiguous or CF_ZONE_ID is not set.</ div >
500+ {% endif %}
501+ </ div >
502+ < div id ="manual_no_tls_verify_div " class ="form-control ">
503+ < label class ="label cursor-pointer justify-start gap-2 ">
504+ < input type ="checkbox " name ="manual_no_tls_verify " id ="manual_no_tls_verify " class ="checkbox checkbox-sm " />
505+ < span class ="label-text "> Disable TLS Verification (No TLS Verify)</ span >
506+ </ label >
507+ < div class ="text-xs opacity-60 ml-8 "> Check if the origin service uses self-signed SSL or is HTTP. (Only applies to HTTP/HTTPS services).</ div >
508+ </ div >
494509 </ div >
495- < div class ="modal-action ">
510+ < div class ="modal-action mt-6 ">
496511 < button type ="submit " class ="btn btn-primary "> Add Rule</ button >
497512 </ div >
498513 </ form >
0 commit comments