forked from cccb-website-team/www
		
	newly added club status, currently disabled until spaceapi is set public
This commit is contained in:
		
							parent
							
								
									6281666093
								
							
						
					
					
						commit
						1e245cf6cd
					
				
					 4 changed files with 161 additions and 0 deletions
				
			
		
							
								
								
									
										67
									
								
								assets/js/clubstatus.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								assets/js/clubstatus.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,67 @@ | |||
| const spaceapiUrl = "https://spaceapi.hamburg.ccc.de" | ||||
| const interval_ms = 60000 | ||||
| 
 | ||||
| console.log("clubstatus.js geladen!"); /* TODO: ENTFERNEN */ | ||||
| 
 | ||||
| function timeDistanceDE(pastDate) { | ||||
|   const seconds = Math.floor((Date.now() - pastDate.getTime()) / 1000) | ||||
|   const minutes = Math.floor(seconds / 60) | ||||
|   const hours = Math.floor(minutes / 60) | ||||
|   const days = Math.floor(hours / 24) | ||||
| 
 | ||||
|   if (days = 1) return `since ${days}d` | ||||
|   if (days > 1) return `since ${days}d` | ||||
|   if (hours = 1) return `since ${hours}h` | ||||
|   if (hours > 1) return `since ${hours}h` | ||||
|   if (minutes = 1) return `since ${minutes}min` | ||||
|   if (minutes > 1) return `since ${minutes}min` | ||||
|   return `gerade eben` | ||||
| } | ||||
| 
 | ||||
| function updateRoomState(openState, lastChangeTimestamp) { | ||||
|   const roomstate = document.querySelector('#clubstatus-badge') | ||||
|   const statusItem = roomstate.querySelector(".state") | ||||
|   const durationItem = roomstate.querySelector(".duration") | ||||
| 
 | ||||
|   if (!statusItem || !durationItem) return | ||||
| 
 | ||||
|   roomstate.classList.remove("open", "closed", "unknown") | ||||
|   statusItem.classList.remove("open", "closed", "unknown") | ||||
| 
 | ||||
|   if (openState === null || lastChangeTimestamp === null) { | ||||
|     statusItem.textContent = "unbekannt" | ||||
|     statusItem.classList.add("unknown") | ||||
|     durationItem.textContent = "(since unbekannt)" | ||||
|   } else { | ||||
|     const changeDate = new Date(lastChangeTimestamp * 1000) | ||||
|     const sinceText = timeDistanceDE(changeDate) | ||||
| 
 | ||||
|     if (openState) { | ||||
|       statusItem.textContent = "open" | ||||
|       statusItem.classList.add("open") | ||||
|     } else { | ||||
|       statusItem.textContent = "closed" | ||||
|       statusItem.classList.add("closed") | ||||
|     } | ||||
| 
 | ||||
|     durationItem.textContent = `(${sinceText})` | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function fetchRoomState() { | ||||
|   fetch(spaceapiUrl) | ||||
|     .then(response => response.json()) | ||||
|     .then(data => { | ||||
|       const openState = data?.state?.open ?? null | ||||
|       const lastChange = data?.state?.lastchange ?? null | ||||
|       updateRoomState(openState, lastChange) | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       console.error("Fehler beim Laden der SpaceAPI:", err) | ||||
|       updateRoomState(null, null) | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| // Initialer Abruf + dann regelmäßig
 | ||||
| fetchRoomState() | ||||
| setInterval(fetchRoomState, interval_ms) | ||||
|  | @ -1,6 +1,27 @@ | |||
| --- | ||||
| description: "Startseite CCCB mit Kurzkalender" | ||||
| --- | ||||
| /* this section will be enabled when the cccb spaceapi is public | ||||
| 
 | ||||
| <div style="display: flex; justify-content: center;"> | ||||
|   <div id="clubstatus-badge">spacestatus unknown</div> | ||||
| </div> | ||||
| 
 | ||||
| <style> | ||||
|     #clubstatus-badge { | ||||
|         position: relative; | ||||
|         background-color: #2ecc71; | ||||
|         flex: initial; | ||||
|         color: white; | ||||
|         padding: 0.25em 0.6em; | ||||
|         font-size: 0.75rem; | ||||
|         border-radius: 1em; | ||||
|         box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); | ||||
|         font-weight: bold; | ||||
|       } | ||||
| </style> | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| ### Nächste Veranstaltungen: | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								layouts/partials/clubstatus.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								layouts/partials/clubstatus.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| {{ $js := resources.Get "js/clubstatus.js" | resources.Minify | resources.Fingerprint }} | ||||
| <script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}"></script> | ||||
| 
 | ||||
							
								
								
									
										70
									
								
								layouts/partials/footer.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								layouts/partials/footer.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| <footer id="site-footer" class="py-10 print:hidden"> | ||||
|   {{/* Footer menu */}} | ||||
|   {{ if .Site.Params.footer.showMenu | default true }} | ||||
|     {{ if .Site.Menus.footer }} | ||||
|     <nav class="flex flex-row pb-4 text-base font-medium text-neutral-500 dark:text-neutral-400"> | ||||
|       <ul class="flex flex-col list-none sm:flex-row"> | ||||
|         {{ range .Site.Menus.footer }} | ||||
|         <li class="flex mb-1 ltr:text-right rtl:text-left sm:mb-0 ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0"> | ||||
|           <a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href="{{ .URL }}" | ||||
|             title="{{ .Title }}"> | ||||
|             {{ if .Pre }} | ||||
|             <span {{ if and .Pre .Name}} class="mr-1" {{ end }}> | ||||
|                 {{ partial "icon.html" .Pre }} | ||||
|             </span> | ||||
|             {{ end }} | ||||
|             {{ .Name | markdownify }} | ||||
|           </a> | ||||
|         </li> | ||||
|         {{ end }} | ||||
|       </ul> | ||||
|     </nav> | ||||
|     {{ end }} | ||||
|   {{ end }} | ||||
|   <div class="flex items-center justify-between"> | ||||
| 
 | ||||
|     {{/* Copyright */}} | ||||
|     {{ if .Site.Params.footer.showCopyright | default true }} | ||||
|     <p class="text-sm text-neutral-500 dark:text-neutral-400"> | ||||
|       {{- with replace .Site.Params.copyright "{ year }" now.Year  }} | ||||
|       {{ . | markdownify }} | ||||
|       {{- else }} | ||||
|       © | ||||
|       {{ now.Format "2006" }} | ||||
|       {{ .Site.Params.Author.name | markdownify }} | ||||
|       {{- end }} | ||||
|     </p> | ||||
|     {{ end }} | ||||
| 
 | ||||
|     {{/* Theme attribution */}} | ||||
|     {{ if .Site.Params.footer.showThemeAttribution | default true }} | ||||
|     <p class="text-xs text-neutral-500 dark:text-neutral-400"> | ||||
|       {{ $hugo := printf `<a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" | ||||
|         href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">Hugo</a>` | ||||
|       }} | ||||
|       {{ $blowfish := printf `<a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" | ||||
|         href="https://blowfish.page/" target="_blank" rel="noopener noreferrer">Blowfish</a>` }} | ||||
|       {{ i18n "footer.powered_by" (dict "Hugo" $hugo "Theme" $blowfish) | safeHTML }} | ||||
|       (<a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" | ||||
|       href="https://git.berlin.ccc.de/cccb-website-team/www">Git-Repo</a>) | ||||
|     </p> | ||||
|     {{ end }} | ||||
| 
 | ||||
|   </div> | ||||
|   <script> | ||||
|     {{ if not .Site.Params.disableImageZoom | default true }} | ||||
|     mediumZoom(document.querySelectorAll("img:not(.nozoom)"), { | ||||
|       margin: 24, | ||||
|       background: 'rgba(0,0,0,0.5)', | ||||
|       scrollOffset: 0, | ||||
|     }) | ||||
|     {{ end }} | ||||
|   </script> | ||||
|   {{ $jsProcess := resources.Get "js/process.js" }} | ||||
|   {{ $jsProcess = $jsProcess | resources.Minify | resources.Fingerprint "sha512" }} | ||||
|   <script type="text/javascript" src="{{ $jsProcess.RelPermalink }}" integrity="{{ $jsProcess.Data.Integrity }}"></script> | ||||
|   {{/* Extend footer - eg. for extra scripts, etc. */}} | ||||
|   {{ if templates.Exists "partials/extend-footer.html" }} | ||||
|   {{ partialCached "extend-footer.html" . }} | ||||
|   {{ end }} | ||||
| </footer> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 murmeldin
						murmeldin