Compare commits
	
		
			5 Commits
		
	
	
		
			main
			...
			dca72234ff
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dca72234ff | |||
| 7b056454ab | |||
| d6dab34e11 | |||
| 3f1c8cb6aa | |||
| 52e4477422 | 
| @@ -9,14 +9,15 @@ jobs: | |||||||
|   build: |   build: | ||||||
|     name: Build |     name: Build | ||||||
|     runs-on: k8s |     runs-on: k8s | ||||||
|  |     container: ubuntu:latest | ||||||
|     steps: |     steps: | ||||||
|  |  | ||||||
|     - name: Install prerequisites |     # - name: Install prerequisites | ||||||
|       run: | |     #   run: | | ||||||
|         sudo apt-get update |     #     apt update | ||||||
|         sudo apt-get install -y xz-utils unzip |     #     apt install -y docker | ||||||
|  |  | ||||||
|     - uses: https://gitea.com/actions/checkout@v4 |     # - uses: https://gitea.com/actions/checkout@v4 | ||||||
|  |  | ||||||
|     - name: Docker login |     - name: Docker login | ||||||
|       uses: docker/login-action@v3 |       uses: docker/login-action@v3 | ||||||
| @@ -25,6 +26,8 @@ jobs: | |||||||
|         username: ${{ secrets.docker_username }} |         username: ${{ secrets.docker_username }} | ||||||
|         password: ${{ secrets.docker_password }} |         password: ${{ secrets.docker_password }} | ||||||
|  |  | ||||||
|  |     - name: Set up Docker Buildx | ||||||
|  |       uses: https://github.com/docker/setup-buildx-action@v3 | ||||||
|  |  | ||||||
|     - name: Build |     - name: Build | ||||||
|       uses: https://github.com/docker/build-push-action@v2 |       uses: https://github.com/docker/build-push-action@v2 | ||||||
|   | |||||||
| @@ -544,18 +544,214 @@ video { | |||||||
|   --tw-backdrop-sepia:  ; |   --tw-backdrop-sepia:  ; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .container { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 640px) { | ||||||
|  |   .container { | ||||||
|  |     max-width: 640px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 768px) { | ||||||
|  |   .container { | ||||||
|  |     max-width: 768px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 1024px) { | ||||||
|  |   .container { | ||||||
|  |     max-width: 1024px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 1280px) { | ||||||
|  |   .container { | ||||||
|  |     max-width: 1280px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 1536px) { | ||||||
|  |   .container { | ||||||
|  |     max-width: 1536px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .static { | ||||||
|  |   position: static; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .fixed { | ||||||
|  |   position: fixed; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .absolute { | ||||||
|  |   position: absolute; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .relative { | ||||||
|  |   position: relative; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sticky { | ||||||
|  |   position: sticky; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .-start-3 { | ||||||
|  |   inset-inline-start: -0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .my-4 { | ||||||
|  |   margin-top: 1rem; | ||||||
|  |   margin-bottom: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mx-2 { | ||||||
|  |   margin-left: 0.5rem; | ||||||
|  |   margin-right: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mb-1 { | ||||||
|  |   margin-bottom: 0.25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mb-10 { | ||||||
|  |   margin-bottom: 2.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mb-2 { | ||||||
|  |   margin-bottom: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mb-4 { | ||||||
|  |   margin-bottom: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .me-2 { | ||||||
|  |   margin-inline-end: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .me-2\.5 { | ||||||
|  |   margin-inline-end: 0.625rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ms-3 { | ||||||
|  |   margin-inline-start: 0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ms-6 { | ||||||
|  |   margin-inline-start: 1.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mt-4 { | ||||||
|  |   margin-top: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .mr-3 { | ||||||
|  |   margin-right: 0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .block { | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .inline-block { | ||||||
|  |   display: inline-block; | ||||||
|  | } | ||||||
|  |  | ||||||
| .flex { | .flex { | ||||||
|   display: flex; |   display: flex; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .inline-flex { | ||||||
|  |   display: inline-flex; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-2 { | ||||||
|  |   height: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-2\.5 { | ||||||
|  |   height: 0.625rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-3 { | ||||||
|  |   height: 0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-3\.5 { | ||||||
|  |   height: 0.875rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-6 { | ||||||
|  |   height: 1.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .h-full { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
| .h-screen { | .h-screen { | ||||||
|   height: 100vh; |   height: 100vh; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .h-32 { | ||||||
|  |   height: 8rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .w-2 { | ||||||
|  |   width: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .w-2\.5 { | ||||||
|  |   width: 0.625rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .w-3 { | ||||||
|  |   width: 0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .w-3\.5 { | ||||||
|  |   width: 0.875rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .w-6 { | ||||||
|  |   width: 1.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .w-screen { | .w-screen { | ||||||
|   width: 100vw; |   width: 100vw; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .w-full { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @keyframes bounce { | ||||||
|  |   0%, 100% { | ||||||
|  |     transform: translateY(-25%); | ||||||
|  |     animation-timing-function: cubic-bezier(0.8,0,1,1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   50% { | ||||||
|  |     transform: none; | ||||||
|  |     animation-timing-function: cubic-bezier(0,0,0.2,1); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .animate-bounce { | ||||||
|  |   animation: bounce 1s infinite; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cursor-not-allowed { | ||||||
|  |   cursor: not-allowed; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .flex-row { | ||||||
|  |   flex-direction: row; | ||||||
|  | } | ||||||
|  |  | ||||||
| .flex-col { | .flex-col { | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| } | } | ||||||
| @@ -572,35 +768,366 @@ video { | |||||||
|   gap: 0.75rem; |   gap: 0.75rem; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .gap-4 { | ||||||
|  |   gap: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .rounded { | .rounded { | ||||||
|   border-radius: 0.25rem; |   border-radius: 0.25rem; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .rounded-full { | ||||||
|  |   border-radius: 9999px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .rounded-lg { | ||||||
|  |   border-radius: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .border { | ||||||
|  |   border-width: 1px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .border-s { | ||||||
|  |   border-inline-start-width: 1px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .border-gray-200 { | ||||||
|  |   --tw-border-opacity: 1; | ||||||
|  |   border-color: rgb(229 231 235 / var(--tw-border-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .border-blue-500 { | ||||||
|  |   --tw-border-opacity: 1; | ||||||
|  |   border-color: rgb(59 130 246 / var(--tw-border-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .border-white { | ||||||
|  |   --tw-border-opacity: 1; | ||||||
|  |   border-color: rgb(255 255 255 / var(--tw-border-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .bg-blue-100 { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(219 234 254 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
| .bg-blue-500 { | .bg-blue-500 { | ||||||
|   --tw-bg-opacity: 1; |   --tw-bg-opacity: 1; | ||||||
|   background-color: rgb(59 130 246 / var(--tw-bg-opacity)); |   background-color: rgb(59 130 246 / var(--tw-bg-opacity)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .bg-white { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(255 255 255 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .bg-gray-200 { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(229 231 235 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .bg-gray-800 { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(31 41 55 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .bg-gradient-to-r { | ||||||
|  |   background-image: linear-gradient(to right, var(--tw-gradient-stops)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .from-purple-700 { | ||||||
|  |   --tw-gradient-from: #7e22ce var(--tw-gradient-from-position); | ||||||
|  |   --tw-gradient-to: rgb(126 34 206 / 0) var(--tw-gradient-to-position); | ||||||
|  |   --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .via-blue-900 { | ||||||
|  |   --tw-gradient-to: rgb(30 58 138 / 0)  var(--tw-gradient-to-position); | ||||||
|  |   --tw-gradient-stops: var(--tw-gradient-from), #1e3a8a var(--tw-gradient-via-position), var(--tw-gradient-to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .to-red-500 { | ||||||
|  |   --tw-gradient-to: #ef4444 var(--tw-gradient-to-position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .p-4 { | ||||||
|  |   padding: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .p-1 { | ||||||
|  |   padding: 0.25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .p-5 { | ||||||
|  |   padding: 1.25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .px-2 { | ||||||
|  |   padding-left: 0.5rem; | ||||||
|  |   padding-right: 0.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .px-2\.5 { | ||||||
|  |   padding-left: 0.625rem; | ||||||
|  |   padding-right: 0.625rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .px-4 { | .px-4 { | ||||||
|   padding-left: 1rem; |   padding-left: 1rem; | ||||||
|   padding-right: 1rem; |   padding-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .py-0 { | ||||||
|  |   padding-top: 0px; | ||||||
|  |   padding-bottom: 0px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .py-0\.5 { | ||||||
|  |   padding-top: 0.125rem; | ||||||
|  |   padding-bottom: 0.125rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .py-2 { | .py-2 { | ||||||
|   padding-top: 0.5rem; |   padding-top: 0.5rem; | ||||||
|   padding-bottom: 0.5rem; |   padding-bottom: 0.5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .px-3 { | ||||||
|  |   padding-left: 0.75rem; | ||||||
|  |   padding-right: 0.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .py-1 { | ||||||
|  |   padding-top: 0.25rem; | ||||||
|  |   padding-bottom: 0.25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .font-mono { | ||||||
|  |   font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-2xl { | ||||||
|  |   font-size: 1.5rem; | ||||||
|  |   line-height: 2rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-6xl { | ||||||
|  |   font-size: 3.75rem; | ||||||
|  |   line-height: 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-base { | ||||||
|  |   font-size: 1rem; | ||||||
|  |   line-height: 1.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-lg { | ||||||
|  |   font-size: 1.125rem; | ||||||
|  |   line-height: 1.75rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-sm { | ||||||
|  |   font-size: 0.875rem; | ||||||
|  |   line-height: 1.25rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .font-bold { | .font-bold { | ||||||
|   font-weight: 700; |   font-weight: 700; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .font-medium { | ||||||
|  |   font-weight: 500; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .font-normal { | ||||||
|  |   font-weight: 400; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .font-semibold { | ||||||
|  |   font-weight: 600; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .leading-none { | ||||||
|  |   line-height: 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-black { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(0 0 0 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-blue-800 { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(30 64 175 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-gray-400 { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(156 163 175 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-gray-500 { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(107 114 128 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .text-gray-900 { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(17 24 39 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
| .text-white { | .text-white { | ||||||
|   --tw-text-opacity: 1; |   --tw-text-opacity: 1; | ||||||
|   color: rgb(255 255 255 / var(--tw-text-opacity)); |   color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
| } | } | ||||||
|  |  | ||||||
| .hover\:bg-blue-700:hover { | .text-blue-500 { | ||||||
|   --tw-bg-opacity: 1; |   --tw-text-opacity: 1; | ||||||
|   background-color: rgb(29 78 216 / var(--tw-bg-opacity)); |   color: rgb(59 130 246 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .shadow-md { | ||||||
|  |   --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); | ||||||
|  |   --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); | ||||||
|  |   box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .shadow-black\/5 { | ||||||
|  |   --tw-shadow-color: rgb(0 0 0 / 0.05); | ||||||
|  |   --tw-shadow: var(--tw-shadow-colored); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ring-8 { | ||||||
|  |   --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | ||||||
|  |   --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color); | ||||||
|  |   box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .ring-white { | ||||||
|  |   --tw-ring-opacity: 1; | ||||||
|  |   --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:border-gray-200:hover { | ||||||
|  |   --tw-border-opacity: 1; | ||||||
|  |   border-color: rgb(229 231 235 / var(--tw-border-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:bg-blue-600:hover { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(37 99 235 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:bg-gray-100:hover { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(243 244 246 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:bg-gray-200:hover { | ||||||
|  |   --tw-bg-opacity: 1; | ||||||
|  |   background-color: rgb(229 231 235 / var(--tw-bg-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:text-blue-700:hover { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(29 78 216 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hover\:text-gray-200:hover { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(229 231 235 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .focus\:z-10:focus { | ||||||
|  |   z-index: 10; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .focus\:text-blue-700:focus { | ||||||
|  |   --tw-text-opacity: 1; | ||||||
|  |   color: rgb(29 78 216 / var(--tw-text-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .focus\:outline-none:focus { | ||||||
|  |   outline: 2px solid transparent; | ||||||
|  |   outline-offset: 2px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .focus\:ring-4:focus { | ||||||
|  |   --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | ||||||
|  |   --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color); | ||||||
|  |   box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .focus\:ring-gray-100:focus { | ||||||
|  |   --tw-ring-opacity: 1; | ||||||
|  |   --tw-ring-color: rgb(243 244 246 / var(--tw-ring-opacity)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (min-width: 768px) { | ||||||
|  |   .md\:p-3 { | ||||||
|  |     padding: 0.75rem; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media (prefers-color-scheme: dark) { | ||||||
|  |   .dark\:border-gray-600 { | ||||||
|  |     --tw-border-opacity: 1; | ||||||
|  |     border-color: rgb(75 85 99 / var(--tw-border-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:border-gray-700 { | ||||||
|  |     --tw-border-opacity: 1; | ||||||
|  |     border-color: rgb(55 65 81 / var(--tw-border-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:bg-blue-900 { | ||||||
|  |     --tw-bg-opacity: 1; | ||||||
|  |     background-color: rgb(30 58 138 / var(--tw-bg-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:bg-gray-800 { | ||||||
|  |     --tw-bg-opacity: 1; | ||||||
|  |     background-color: rgb(31 41 55 / var(--tw-bg-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:text-blue-300 { | ||||||
|  |     --tw-text-opacity: 1; | ||||||
|  |     color: rgb(147 197 253 / var(--tw-text-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:text-gray-400 { | ||||||
|  |     --tw-text-opacity: 1; | ||||||
|  |     color: rgb(156 163 175 / var(--tw-text-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:text-gray-500 { | ||||||
|  |     --tw-text-opacity: 1; | ||||||
|  |     color: rgb(107 114 128 / var(--tw-text-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:text-white { | ||||||
|  |     --tw-text-opacity: 1; | ||||||
|  |     color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:ring-gray-900 { | ||||||
|  |     --tw-ring-opacity: 1; | ||||||
|  |     --tw-ring-color: rgb(17 24 39 / var(--tw-ring-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:hover\:bg-gray-700:hover { | ||||||
|  |     --tw-bg-opacity: 1; | ||||||
|  |     background-color: rgb(55 65 81 / var(--tw-bg-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:hover\:text-white:hover { | ||||||
|  |     --tw-text-opacity: 1; | ||||||
|  |     color: rgb(255 255 255 / var(--tw-text-opacity)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .dark\:focus\:ring-gray-700:focus { | ||||||
|  |     --tw-ring-opacity: 1; | ||||||
|  |     --tw-ring-color: rgb(55 65 81 / var(--tw-ring-opacity)); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,15 +1,15 @@ | |||||||
| import * as elements from "typed-html"; | import * as elements from "typed-html"; | ||||||
| 
 | 
 | ||||||
| const HomeLayout = ({ children }: elements.Children) => ` | const BaseHTML = ({ children }: elements.Children) => ` | ||||||
|     <head> |     <head> | ||||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |         <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||||
|         <script src="https://unpkg.com/htmx.org@1.9.5"></script> |         <script src="https://unpkg.com/htmx.org@1.9.5"></script> | ||||||
|         <link href="/public/style.css" rel="stylesheet" type="text/css" /> |         <link href="/public/style.css" rel="stylesheet" type="text/css" /> | ||||||
|         <title>BETH STACK</title> |         <title>Welcome!</title> | ||||||
|     </head> |     </head> | ||||||
|     <body class="h-screen w-screen flex flex-col gap-3 items-center justify-center"> |     <body class="h-screen w-screen flex flex-col gap-3 items-center justify-center"> | ||||||
|         ${children} |         ${children} | ||||||
|     </body> |     </body> | ||||||
| `;
 | `;
 | ||||||
| 
 | 
 | ||||||
| export { HomeLayout } | export { BaseHTML } | ||||||
							
								
								
									
										20
									
								
								frontend/src/components/footer.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/src/components/footer.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import { FooterLink } from "../structs/footer_link"; | ||||||
|  |  | ||||||
|  | const Footer = ({ footer_links }: {footer_links: FooterLink[]}) => { | ||||||
|  |     return ( | ||||||
|  |         <footer class={'w-full h-32 bg-gray-800 flex items-center justify-center'}> | ||||||
|  |             {footer_links.map((link) => { | ||||||
|  |                 return ( | ||||||
|  |                     <a href={link.url} class={'mx-2'}> | ||||||
|  |                         <i class={`fas fa-${ | ||||||
|  |                             link.icon_name | ||||||
|  |                         } text-white`}></i> | ||||||
|  |                     </a> | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             )} | ||||||
|  |         </footer> | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { Footer } | ||||||
							
								
								
									
										20
									
								
								frontend/src/components/hero.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/src/components/hero.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | const Hero = () => { | ||||||
|  |     return ( | ||||||
|  |         <div class="bg-gradient-to-r from-purple-700 via-blue-900 to-red-500 w-screen h-screen" id="hero"> | ||||||
|  |             <div class="flex flex-col items-center justify-center h-full"> | ||||||
|  |                 <div class="text-6xl font-bold text-white">Welcome to <span class="font-mono">moll.re</span></div> | ||||||
|  |                 <div class="text-2xl text-white">An exciting journey!</div> | ||||||
|  |                 <button class="px-4 py-2 my-4 text-lg font-semibold text-white bg-blue-500 rounded hover:bg-blue-600"> | ||||||
|  |                     Explore | ||||||
|  |                 </button> | ||||||
|  |                 <div class="mt-4 animate-bounce"> | ||||||
|  |                     <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-white animate-bounce" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | ||||||
|  |                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path> | ||||||
|  |                     </svg> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export { Hero} | ||||||
							
								
								
									
										20
									
								
								frontend/src/components/navigation.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/src/components/navigation.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  |  | ||||||
|  | const Navigation = () => { | ||||||
|  |     return( | ||||||
|  |         <nav id={'header'} class={'flex-no-wrap sticky w-screen py-2 shadow-black/5'}> | ||||||
|  |         <ul class="flex"> | ||||||
|  |             <li class="mr-3"> | ||||||
|  |                 <a class="inline-block border border-blue-500 rounded py-1 px-3 bg-blue-500 text-white" href="#">Active Pill</a> | ||||||
|  |             </li> | ||||||
|  |             <li class="mr-3"> | ||||||
|  |                 <a class="inline-block border border-white rounded hover:border-gray-200 text-blue-500 hover:bg-gray-200 py-1 px-3" href="#">Pill</a> | ||||||
|  |             </li> | ||||||
|  |             <li class="mr-3"> | ||||||
|  |                 <a class="inline-block py-1 px-3 text-gray-400 cursor-not-allowed" href="#">Disabled Pill</a> | ||||||
|  |             </li> | ||||||
|  |         </ul> | ||||||
|  |         </nav> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export { Navigation } | ||||||
							
								
								
									
										24
									
								
								frontend/src/components/timeline.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								frontend/src/components/timeline.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import * as elements from "typed-html"; | ||||||
|  | import { TimelineCard } from "./timeline_card"; | ||||||
|  | import { TimelineItem } from "../structs/timeline_item"; | ||||||
|  |  | ||||||
|  | const Timeline = ({ timeline_items }: {timeline_items: TimelineItem[]}) => { | ||||||
|  |     return ( | ||||||
|  |         <div class={'container md:p-3'}> | ||||||
|  |             <div class="flex flex-col items-center justify-center"> | ||||||
|  |                 <div class="text-6xl font-bold text-black">Timeline</div> | ||||||
|  |                 <div class="text-2xl text-black">A little about us</div> | ||||||
|  |                 <ol class="relative border-s border-gray-200 dark:border-gray-700"> | ||||||
|  |                     {timeline_items.map((item, index) => ( | ||||||
|  |                         // <div class={`card ${index % 2 === 0 ? 'left' : 'right'}`}> | ||||||
|  |                         <li class={`mb-10 ms-6 p-4 rounded-lg shadow-md ${index % 2 === 0 ? 'bg-white' : 'bg-gray-200'}`}> | ||||||
|  |                             <TimelineCard {...item}/> | ||||||
|  |                         </li> | ||||||
|  |                     ))} | ||||||
|  |                 </ol> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export { Timeline } | ||||||
							
								
								
									
										22
									
								
								frontend/src/components/timeline_card.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								frontend/src/components/timeline_card.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | import * as elements from "typed-html"; | ||||||
|  |  | ||||||
|  | import { TimelineItem } from "../structs/timeline_item"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const TimelineCard = ({ date_start, date_end, title, description, icon_name}: TimelineItem) => { | ||||||
|  |     return ( | ||||||
|  |         <div> | ||||||
|  |             <span class="absolute flex items-center justify-center w-6 h-6 bg-blue-100 rounded-full -start-3 ring-8 ring-white dark:ring-gray-900 dark:bg-blue-900"> | ||||||
|  |             <svg class="w-2.5 h-2.5 text-blue-800 dark:text-blue-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"> | ||||||
|  |                 <path d="M20 4a2 2 0 0 0-2-2h-2V1a1 1 0 0 0-2 0v1h-3V1a1 1 0 0 0-2 0v1H6V1a1 1 0 0 0-2 0v1H2a2 2 0 0 0-2 2v2h20V4ZM0 18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8H0v10Zm5-8h10a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2Z"/> | ||||||
|  |             </svg> | ||||||
|  |             </span> | ||||||
|  |             <h3 class="mb-1 text-lg font-semibold text-gray-900">{ title }</h3> | ||||||
|  |             <time class="block mb-2 text-sm font-normal leading-none text-gray-400 dark:text-gray-500">{ date_start.toLocaleDateString() } - { date_end.toLocaleDateString() }</time> | ||||||
|  |             <p class="text-base font-normal text-gray-500 dark:text-gray-400">{ description }</p> | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export { TimelineCard } | ||||||
| @@ -2,26 +2,112 @@ import { Elysia } from "elysia"; | |||||||
| import { html } from "@elysiajs/html"; | import { html } from "@elysiajs/html"; | ||||||
| import { staticPlugin } from "@elysiajs/static"; | import { staticPlugin } from "@elysiajs/static"; | ||||||
|  |  | ||||||
| // import { autoroutes } from "elysia-autoroutes"; | import { BaseHTML } from "./base"; | ||||||
| // import { Store } from "./store"; | import { LandingPage } from "./pages/landing"; | ||||||
| // // @ts-ignore |  | ||||||
| // import data from "../package.json"; |  | ||||||
|  |  | ||||||
| import { HomeLayout } from "./layout"; | import { TimelineItem } from "./structs/timeline_item"; | ||||||
| import { Landing } from "./landing"; | import { FooterLink } from "./structs/footer_link"; | ||||||
|  |  | ||||||
|  | const timeline_items: TimelineItem[] = [ | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "First", | ||||||
|  |     description: "Description number 1", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Description number 2", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Longer description number 3", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Very looooooooooong description number 4", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Description number 5", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Description number 6", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Description number 7", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     date_start: new Date(), | ||||||
|  |     date_end: new Date(), | ||||||
|  |     title: "Hello", | ||||||
|  |     description: "Description number 8", | ||||||
|  |     icon_name: "world", | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const footer_links: FooterLink[] = [ | ||||||
|  |   { | ||||||
|  |     icon_name: "github", | ||||||
|  |     title: "Github", | ||||||
|  |     url: "https://github.com", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     icon_name: "twitter", | ||||||
|  |     title: "Twitter", | ||||||
|  |     url: "https://twitter.com", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     icon_name: "linkedin", | ||||||
|  |     title: "LinkedIn", | ||||||
|  |     url: "https://linkedin.com", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     icon_name: "instagram", | ||||||
|  |     title: "Instagram", | ||||||
|  |     url: "https://instagram.com", | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     icon_name: "facebook", | ||||||
|  |     title: "Facebook", | ||||||
|  |     url: "https://facebook.com", | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | const content = { | ||||||
|  |   'timeline_items': timeline_items, | ||||||
|  |   'footer_links': footer_links, | ||||||
|  | }; | ||||||
|  |  | ||||||
| export const server = new Elysia() | export const server = new Elysia() | ||||||
|   .use(html()) |   .use(html()) | ||||||
|   .use(staticPlugin()) |   .use(staticPlugin()) | ||||||
|   // .get("/public/htmx.js", () => |  | ||||||
|   //   Bun.file("node_modules/htmx.org/dist/htmx.min.js"), |  | ||||||
|   // ) |  | ||||||
|   // .state("store", new Store()) |  | ||||||
|   // .state("version", data.version) |  | ||||||
|   .onError(({ code, error }) => { |   .onError(({ code, error }) => { | ||||||
|     console.error(code, error); |     console.error(code, error); | ||||||
|   }) |   }) | ||||||
|   .get("/", ({html}) => html(<HomeLayout><Landing></Landing></HomeLayout>)) |   .get("/", ({html}) => html(<BaseHTML><LandingPage{content}/></BaseHTML>)) | ||||||
|   .post("/clicked", ()=> <div>Hello?</div>) |   .post("/clicked", ()=> <div>Hello?</div>) | ||||||
|  |  | ||||||
|   .listen(Bun.env["PORT"] ?? 3000); |   .listen(Bun.env["PORT"] ?? 3000); | ||||||
|   | |||||||
| @@ -1,10 +0,0 @@ | |||||||
| import * as elements from "typed-html"; |  | ||||||
|  |  | ||||||
| const Landing = ({ children }: elements.Children) => ` |  | ||||||
|     <button hx-post="/clicked" hx-swap="outerHTML" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> |  | ||||||
|         Click me |  | ||||||
|     </button> |  | ||||||
|     ${children} |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| export { Landing } |  | ||||||
							
								
								
									
										20
									
								
								frontend/src/pages/landing.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/src/pages/landing.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import * as elements from "typed-html"; | ||||||
|  | import { Timeline } from "../components/timeline"; | ||||||
|  | import { Navigation } from "../components/navigation"; | ||||||
|  | import { Hero } from "../components/hero"; | ||||||
|  | import { Footer } from "../components/footer"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const LandingPage = ({ content }: Dict) => { | ||||||
|  |     return ( | ||||||
|  |         <div class={'w-full h-full'}> | ||||||
|  |             <Hero /> | ||||||
|  |             <Navigation /> | ||||||
|  |             <Timeline {content['timeline_items']}/> | ||||||
|  |             <Footer {content['footer_links']}/> | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export { LandingPage } | ||||||
							
								
								
									
										0
									
								
								frontend/src/pages/portfolio.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								frontend/src/pages/portfolio.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										7
									
								
								frontend/src/structs/footer_link.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								frontend/src/structs/footer_link.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | type FooterLink = { | ||||||
|  |     icon_name: string; | ||||||
|  |     title: string; | ||||||
|  |     url: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { FooterLink } | ||||||
							
								
								
									
										9
									
								
								frontend/src/structs/timeline_item.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								frontend/src/structs/timeline_item.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | type TimelineItem = { | ||||||
|  |     date_start: Date; | ||||||
|  |     date_end: Date; | ||||||
|  |     title: string; | ||||||
|  |     description: string; | ||||||
|  |     icon_name: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { TimelineItem } | ||||||
		Reference in New Issue
	
	Block a user