88
99 @vite ([' resources/css/app.css' , ' resources/js/app.js' ] )
1010
11+ <script >
12+ // Add Livewire hook to preserve Web Component attributes
13+ Livewire .hook (' morph.updating' , ({ el, component, toEl }) => {
14+ // Check if element is a custom element
15+ if (! el .tagName .includes (' -' )) {
16+ return ;
17+ }
18+
19+ // Store the original attributes
20+ let oldAttributes = Array .from (el .attributes )
21+ .reduce ((attrs , attr ) => {
22+ attrs[attr .name ] = attr .value ;
23+ return attrs;
24+ }, {});
25+
26+ // Restore all attributes that might have been removed by Livewire
27+ let currentAttributes = Array .from (toEl .attributes ).map (attr => attr .name );
28+ Object .entries (oldAttributes).forEach (([name , value ]) => {
29+ if (! name .startsWith (' !' ) && ! currentAttributes .includes (name)) {
30+ toEl .setAttribute (name, value);
31+ }
32+ });
33+
34+ // Remove attributes starting with '!' from the toEl
35+ Array .from (toEl .attributes ).forEach (attr => {
36+ if (attr .name .startsWith (' !' )) {
37+ toEl .removeAttribute (attr .name .substring (1 )); // Remove the corresponding actual attribute
38+ toEl .removeAttribute (attr .name ); // Remove the attribute with the '!' prefix
39+ }
40+ });
41+ });
42+ </script >
43+
1144 </head >
1245 <body class =" relative min-h-screen font-sans antialiased bg-base-200/50 dark:bg-base-200" >
1346 <!-- QR Dialog -->
2356 <sl-button slot =" footer" class =" w-full" >Close</sl-button >
2457 </sl-dialog >
2558
59+ <!-- Global Error Alert -->
60+ <div class =" fixed right-4 bottom-4 z-50" >
61+ <sl-alert id =" global-error-alert-component" variant =" danger" duration =" 5000" countdown =" rtl" closable >
62+ <sl-icon slot =" icon" name =" exclamation-octagon" ></sl-icon >
63+ <strong class =" alert-component-head" ></strong ><br >
64+ <span class =" alert-component-content" ></span >
65+ </sl-alert >
66+ </div >
67+
68+ <!-- Global Success Alert -->
69+ <div class =" fixed right-4 bottom-4 z-50" >
70+ <sl-alert id =" global-success-alert-component" variant =" success" duration =" 5000" countdown =" rtl" closable >
71+ <sl-icon slot =" icon" name =" check-circle" ></sl-icon >
72+ <strong class =" alert-component-head" ></strong ><br >
73+ <span class =" alert-component-content" ></span >
74+ </sl-alert >
75+ </div >
76+
2677 <script >
2778 document .addEventListener (' DOMContentLoaded' , () => {
2879 const dialog = document .querySelector (' #global-qr-dialog' );
@@ -52,6 +103,62 @@ function updateQRSize() {
52103 closeButton .addEventListener (' click' , () => {
53104 dialog .hide ();
54105 });
106+
107+ const errorComponent = document .querySelector (' #global-error-alert-component' );
108+ const successComponent = document .querySelector (' #global-success-alert-component' );
109+
110+ function getAlertContent (data ) {
111+ let head = ' Error' ;
112+ let message = ' An error occurred' ;
113+
114+ if (data .detail ) {
115+ head = data .detail .head || head;
116+ message = data .detail .message || message;
117+ } else if (typeof data === ' object' ) {
118+ // Try other possible structures
119+ if (data .head ) head = data .head ;
120+ if (data .message ) message = data .message ;
121+ // Check if it's an array
122+ if (Array .isArray (data) && data .length > 0 ) {
123+ if (data[0 ].detail ) {
124+ head = data[0 ].detail .head || head;
125+ message = data[0 ].detail .message || message;
126+ } else {
127+ if (data[0 ].head ) head = data[0 ].head ;
128+ if (data[0 ].message ) message = data[0 ].message ;
129+ }
130+ }
131+ }
132+
133+ return {
134+ head,
135+ message
136+ }
137+ }
138+
139+ Livewire .on (' show-error-alert' , (data ) => {
140+ console .log (' Error alert event received:' , data);
141+
142+ const componentHead = errorComponent .querySelector (' .alert-component-head' );
143+ const componentContent = errorComponent .querySelector (' .alert-component-content' );
144+
145+ const { head , message } = getAlertContent (data);
146+ componentHead .textContent = head;
147+ componentContent .textContent = message;
148+ errorComponent .show ();
149+ });
150+
151+ Livewire .on (' show-success-alert' , (data ) => {
152+ console .log (' Success alert event received:' , data);
153+
154+ const componentHead = successComponent .querySelector (' .alert-component-head' );
155+ const componentContent = successComponent .querySelector (' .alert-component-content' );
156+
157+ const { head , message } = getAlertContent (data);
158+ componentHead .textContent = head;
159+ componentContent .textContent = message;
160+ successComponent .show ();
161+ });
55162 });
56163 </script >
57164
@@ -111,6 +218,16 @@ function updateQRSize() {
111218 background : rgba (0 , 0 , 0 , 0.5 );
112219 visibility : visible ;
113220 }
221+
222+ sl-alert ::part(base ) {
223+ width : auto ;
224+ min-width : max-content ;
225+ overflow-wrap : break-word ;
226+ }
227+
228+ sl-alert ::part(message) {
229+ overflow-wrap : break-word ;
230+ }
114231 </style >
115232
116233 <header class =" sticky top-0 z-50" >
@@ -121,7 +238,7 @@ function updateQRSize() {
121238 @endif
122239 </header >
123240
124- <main class =" min-h-screen px-8 pb-4" >
241+ <main class =" px-8 pb-4 min-h-screen " >
125242 @if (request ()-> path () !== ' /' &&
126243 request ()-> path () !== ' create-monitor' &&
127244 request ()-> path () !== ' create-open-source-monitor' &&
0 commit comments