summaryrefslogtreecommitdiff
path: root/packages/web-util/src/components/Header.tsx
blob: 0ffc57417b7d125ab2e979fbabe849bef2f14bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { useState } from "preact/hooks";
import { LangSelector, useTranslationContext } from "../index.browser.js";
import { ComponentChildren, Fragment, VNode, h } from "preact";
import logo from "../assets/logo-2021.svg";

export function Header({ title, iconLinkURL, sites, supportedLangs, onLogout, children }: 
  { title: string, iconLinkURL: string, children?: ComponentChildren, onLogout: (() => void) | undefined, sites: Array<Array<string>>, supportedLangs: string[] }): VNode {
  const { i18n } = useTranslationContext();
  const [open, setOpen] = useState(false)
  return <Fragment>
    <header class="bg-indigo-600 w-full mx-auto px-2 border-b border-opacity-25 border-indigo-400">
      <div class="flex flex-row h-16 items-center ">
        <div class="flex px-2 justify-start">
          <div class="flex-shrink-0 bg-white rounded-lg">
            <a href={iconLinkURL ?? "#"}>
              <img
                class="h-8 w-auto"
                src={logo}
                alt="GNU Taler"
                style={{ height: "1.5rem", margin: ".5rem" }}
              />
            </a>
          </div>
          <span class="flex items-center text-white text-lg font-bold ml-4">
            {title}
          </span>
        </div>
        <div class="block flex-1 ml-6 ">
          {sites.length !== 0 &&
            <div class="flex flex-1 space-x-4">
              {/* <!-- Current: "bg-indigo-700 text-white", Default: "text-white hover:bg-indigo-500 hover:bg-opacity-75" --> */}
              {sites.map((site) => {
                if (site.length !== 2) return;
                const [name, url] = site
                return <a href={url} class="text-white hover:bg-indigo-500 hover:bg-opacity-75 rounded-md py-2 px-3 text-sm font-medium">{name}</a>
              })}
            </div>
          }
        </div>
        <div class="flex justify-end">
          <button type="button" class="relative inline-flex items-center justify-center rounded-md bg-indigo-600 p-1 text-indigo-200 hover:bg-indigo-500 hover:bg-opacity-75 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-indigo-600" aria-controls="mobile-menu" aria-expanded="false"
            onClick={(e) => {
              setOpen(!open)
            }}>
            <span class="absolute -inset-0.5"></span>
            <span class="sr-only"><i18n.Translate>Open settings</i18n.Translate></span>
            <svg class="block h-10 w-10" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
              <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
            </svg>
          </button>
        </div>
      </div>
    </header>

    {open &&
      <div class="relative z-10" aria-labelledby="slide-over-title" role="dialog" aria-modal="true"
        onClick={() => {
          setOpen(false)
        }}>
        <div class="fixed inset-0"></div>

        <div class="fixed inset-0 overflow-hidden">
          <div class="absolute inset-0 overflow-hidden">
            <div class="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10">
              <div class="pointer-events-auto w-screen max-w-md" >
                <div class="flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl" onClick={(e) => {
                  //do not trigger close if clicking inside the sidebar
                  e.stopPropagation();
                }}>
                  <div class="px-4 sm:px-6" >
                    <div class="flex items-start justify-between" >
                      <h2 class="text-base font-semibold leading-6 text-gray-900" id="slide-over-title">
                        <i18n.Translate>Menu</i18n.Translate>
                      </h2>
                      <div class="ml-3 flex h-7 items-center">
                        <button type="button" class="relative rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                          onClick={(e) => {
                            setOpen(false)
                          }}

                        >
                          <span class="absolute -inset-2.5"></span>
                          <span class="sr-only">
                            <i18n.Translate>Close panel</i18n.Translate>
                          </span>
                          <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                          </svg>
                        </button>
                      </div>
                    </div>
                  </div>
                  <div class="relative mt-6 flex-1 px-4 sm:px-6">
                    <nav class="flex flex-1 flex-col" aria-label="Sidebar">
                      <ul role="list" class="flex flex-1 flex-col gap-y-7">
                        {onLogout ?
                          <li>
                            <a href="#"
                              class="text-gray-700 hover:text-indigo-600 hover:bg-gray-100 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold"
                              onClick={() => {
                                onLogout();
                                setOpen(false)
                              }}
                            >
                              <svg class="h-6 w-6 shrink-0 text-indigo-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
                              </svg>
                              <i18n.Translate>Log out</i18n.Translate>
                            </a>
                          </li>
                          : undefined}
                        <li>
                          <LangSelector supportedLangs={supportedLangs} />
                        </li>
                        {/* CHILDREN */}
                        {children}
                        {/* /CHILDREN */}
                        {sites.length !== 0 &&
                          <li class="sm:hidden">
                            <div class="text-xs font-semibold leading-6 text-gray-400">
                              <i18n.Translate>Sites</i18n.Translate>
                            </div>
                            <ul role="list" class="space-y-1">
                              {sites.map(([name, url]) => {
                                return <li>
                                  <a href={url} target="_blank" rel="noopener noreferrer" class="text-gray-700 hover:text-indigo-600 hover:bg-gray-100 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
                                    <span class="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg border text-[0.625rem] font-medium bg-white text-gray-400 border-gray-200 group-hover:border-indigo-600 group-hover:text-indigo-600">&gt;</span>
                                    <span class="truncate">{name}</span>
                                  </a>
                                </li>
                              })}
                            </ul>
                          </li>
                        }
                      </ul>
                    </nav>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    }
  </Fragment>
}