From f2177cef92c6c7c995e0cea667045342e129d5a7 Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Thu, 10 Jun 2021 16:03:01 +0200
Subject: [PATCH] Start on search style

---
 ui/src/Pages/LoginPage/LoginPage.tsx   |   6 +-
 ui/src/Pages/PlacesPage/PlacesPage.tsx |   7 +-
 ui/src/components/header/Searchbar.tsx | 136 +++++++++++-------------
 ui/src/components/layout/Layout.tsx    |   4 +-
 ui/src/components/sidebar/Sharing.tsx  | 139 -------------------------
 ui/src/primitives/form/Input.tsx       |   2 +-
 6 files changed, 73 insertions(+), 221 deletions(-)

diff --git a/ui/src/Pages/LoginPage/LoginPage.tsx b/ui/src/Pages/LoginPage/LoginPage.tsx
index 6a96eba..0cf4e39 100644
--- a/ui/src/Pages/LoginPage/LoginPage.tsx
+++ b/ui/src/Pages/LoginPage/LoginPage.tsx
@@ -78,7 +78,7 @@ const LoginForm = () => {
       // loading={loading || (data && data.authorizeUser.success)}
     >
       <TextField
-        className="w-full"
+        className="w-full my-4"
         label={t('login_page.field.username', 'Username')}
         {...register('username', { required: true })}
         error={
@@ -88,7 +88,7 @@ const LoginForm = () => {
         }
       />
       <TextField
-        className="w-full"
+        className="w-full my-4"
         type="password"
         label={t('login_page.field.password', 'Password')}
         {...register('password', { required: true })}
@@ -102,7 +102,7 @@ const LoginForm = () => {
         type="submit"
         disabled={loading}
         value={t('login_page.field.submit', 'Sign in') as string}
-        className="rounded-md px-8 py-2 focus:outline-none hover:cursor-pointer bg-gradient-to-bl from-[#FF8246] to-[#D6264D] text-white font-semibold focus:ring-2 focus:ring-red-200"
+        className="rounded-md px-8 py-2 mt-1 focus:outline-none cursor-pointer bg-gradient-to-bl from-[#FF8246] to-[#D6264D] text-white font-semibold focus:ring-2 focus:ring-red-200 disabled:cursor-default disabled:opacity-80"
       />
       <MessageBox
         message={errorMessage}
diff --git a/ui/src/Pages/PlacesPage/PlacesPage.tsx b/ui/src/Pages/PlacesPage/PlacesPage.tsx
index a4d083d..db3e681 100644
--- a/ui/src/Pages/PlacesPage/PlacesPage.tsx
+++ b/ui/src/Pages/PlacesPage/PlacesPage.tsx
@@ -10,9 +10,11 @@ import MapPresentMarker from './MapPresentMarker'
 import { urlPresentModeSetupHook } from '../../components/photoGallery/photoGalleryReducer'
 import { placesReducer } from './placesReducer'
 
+import mapboxStyles from 'mapbox-gl/dist/mapbox-gl.css'
+
 const MapWrapper = styled.div`
   width: 100%;
-  height: calc(100% - 24px);
+  height: calc(100vh - 120px);
 `
 
 const MapContainer = styled.div`
@@ -145,7 +147,8 @@ const MapPage = () => {
   return (
     <Layout title="Places">
       <Helmet>
-        <link rel="stylesheet" href="/mapbox-gl.css" />
+        {/* <link rel="stylesheet" href="/mapbox-gl.css" /> */}
+        <style type="text/css">{mapboxStyles}</style>
       </Helmet>
       <MapWrapper>
         <MapContainer ref={mapContainer}></MapContainer>
diff --git a/ui/src/components/header/Searchbar.tsx b/ui/src/components/header/Searchbar.tsx
index 94f96c4..fa9e16a 100644
--- a/ui/src/components/header/Searchbar.tsx
+++ b/ui/src/components/header/Searchbar.tsx
@@ -11,40 +11,40 @@ import {
   searchQuery_search_media,
 } from './__generated__/searchQuery'
 
-const SearchField = styled.input`
-  height: 100%;
-  width: 100%;
-  border: 1px solid #eee;
-  border-radius: 4px;
-  padding: 0 8px;
-  font-size: 1rem;
-  font-family: Lato, 'Helvetica Neue', Arial, Helvetica, sans-serif;
+// const SearchField = styled.input`
+//   height: 100%;
+//   width: 100%;
+//   border: 1px solid #eee;
+//   border-radius: 4px;
+//   padding: 0 8px;
+//   font-size: 1rem;
+//   font-family: Lato, 'Helvetica Neue', Arial, Helvetica, sans-serif;
 
-  &:focus {
-    box-shadow: 0 0 4px #eee;
-    border-color: #3d82c6;
-  }
-`
+//   &:focus {
+//     box-shadow: 0 0 4px #eee;
+//     border-color: #3d82c6;
+//   }
+// `
 
-const Results = styled.div<{ show: boolean }>`
-  display: ${({ show }) => (show ? 'block' : 'none')};
-  position: absolute;
-  width: 100%;
-  min-height: 40px;
-  max-height: calc(100vh - 100px);
-  overflow-y: scroll;
-  padding: 28px 4px 32px;
-  background-color: white;
-  box-shadow: 0 0 4px #eee;
-  border: 1px solid #ccc;
-  border-radius: 4px;
-  top: 50%;
-  z-index: -1;
+// const Results = styled.div<{ show: boolean }>`
+//   display: ${({ show }) => (show ? 'block' : 'none')};
+//   position: absolute;
+//   width: 100%;
+//   min-height: 40px;
+//   max-height: calc(100vh - 100px);
+//   overflow-y: scroll;
+//   padding: 28px 4px 32px;
+//   background-color: white;
+//   box-shadow: 0 0 4px #eee;
+//   border: 1px solid #ccc;
+//   border-radius: 4px;
+//   top: 50%;
+//   z-index: -1;
 
-  ${SearchField}:not(:focus) ~ & {
-    display: none;
-  }
-`
+//   input:not(:focus) ~ & {
+//     display: none;
+//   }
+// `
 
 const SEARCH_QUERY = gql`
   query searchQuery($query: String!) {
@@ -117,7 +117,7 @@ const SearchBar = () => {
   return (
     <div className="w-full max-w-xs">
       <input
-        className="w-full py-2 px-3 rounded-md bg-gray-50"
+        className="w-full py-2 px-3 rounded-md bg-gray-50 focus:bg-white border border-gray-50 focus:border-blue-400 outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-50"
         type="search"
         placeholder={t('header.search.placeholder', 'Search')}
         onChange={fetchEvent}
@@ -127,10 +127,9 @@ const SearchBar = () => {
   )
 }
 
-const ResultTitle = styled.h1`
-  font-size: 1.25rem;
-  margin: 12px 0 0.25rem;
-`
+const ResultTitle = styled.h1.attrs({
+  className: 'uppercase text-gray-700 font-semibold mt-4 mb-2 mx-1',
+})``
 
 type SearchResultsProps = {
   searchData?: searchQuery
@@ -149,21 +148,24 @@ const SearchResults = ({ searchData, loading }: SearchResultsProps) => {
   else if (searchData && media.length == 0 && albums.length == 0)
     message = t('header.search.no_results', 'No results found')
 
-  const albumElements = albums.map(album => (
-    <AlbumRow key={album.id} query={query} album={album} />
-  ))
+  if (message) message = <div className="mt-8 text-center">{message}</div>
 
-  const mediaElements = media.map(media => (
-    <PhotoRow key={media.id} query={query} media={media} />
-  ))
+  const albumElements = albums
+    .slice(0, 5)
+    .map(album => <AlbumRow key={album.id} query={query} album={album} />)
+
+  const mediaElements = media
+    .slice(0, 5)
+    .map(media => <PhotoRow key={media.id} query={query} media={media} />)
 
   return (
-    <Results
+    <div
+      className="absolute bg-white left-0 right-0 top-[72px] overflow-y-auto h-[calc(100vh-152px)] border px-4"
       onMouseDown={e => {
         // Prevent input blur event
         e.preventDefault()
       }}
-      show={!!searchData}
+      // show={!!searchData}
     >
       {message}
       {albumElements.length > 0 && (
@@ -174,40 +176,20 @@ const SearchResults = ({ searchData, loading }: SearchResultsProps) => {
       {albumElements}
       {mediaElements.length > 0 && (
         <ResultTitle>
-          {t('header.search.result_type.photos', 'Photos')}
+          {t('header.search.result_type.media', 'Media')}
         </ResultTitle>
       )}
       {mediaElements}
-    </Results>
+    </div>
   )
 }
 
-const RowLink = styled(NavLink)`
-  display: flex;
-  align-items: center;
-  color: black;
-`
+const RowLink = styled(NavLink).attrs({
+  className:
+    'focus:bg-gray-100 hover:bg-gray-100 focus:ring-1 outline-none rounded p-1 mt-1 flex items-center',
+})``
 
-const PhotoSearchThumbnail = styled(ProtectedImage)`
-  width: 50px;
-  height: 50px;
-  margin: 2px 0;
-  object-fit: contain;
-`
-
-const AlbumSearchThumbnail = styled(ProtectedImage)`
-  width: 50px;
-  height: 50px;
-  margin: 4px 0;
-  border-radius: 4px;
-  /* border: 1px solid #888; */
-  object-fit: cover;
-`
-
-const RowTitle = styled.span`
-  flex-grow: 1;
-  padding-left: 8px;
-`
+const RowTitle = styled.span.attrs({ className: 'flex-grow pl-2' })``
 
 type PhotoRowArgs = {
   query: string
@@ -216,7 +198,10 @@ type PhotoRowArgs = {
 
 const PhotoRow = ({ query, media }: PhotoRowArgs) => (
   <RowLink to={`/album/${media.album.id}`}>
-    <PhotoSearchThumbnail src={media?.thumbnail?.url} />
+    <ProtectedImage
+      src={media?.thumbnail?.url}
+      className="w-16 h-16 object-cover"
+    />
     <RowTitle>{searchHighlighted(query, media.title)}</RowTitle>
   </RowLink>
 )
@@ -228,7 +213,10 @@ type AlbumRowArgs = {
 
 const AlbumRow = ({ query, album }: AlbumRowArgs) => (
   <RowLink to={`/album/${album.id}`}>
-    <AlbumSearchThumbnail src={album?.thumbnail?.thumbnail?.url} />
+    <ProtectedImage
+      src={album?.thumbnail?.thumbnail?.url}
+      className="w-16 h-16 rounded object-cover"
+    />
     <RowTitle>{searchHighlighted(query, album.title)}</RowTitle>
   </RowLink>
 )
@@ -247,7 +235,7 @@ const searchHighlighted = (query: string, text: string) => {
   return (
     <>
       {start}
-      <b>{middle}</b>
+      <strong className="font-semibold">{middle}</strong>
       {end}
     </>
   )
diff --git a/ui/src/components/layout/Layout.tsx b/ui/src/components/layout/Layout.tsx
index f4e09b0..a0be653 100644
--- a/ui/src/components/layout/Layout.tsx
+++ b/ui/src/components/layout/Layout.tsx
@@ -35,13 +35,13 @@ const Layout = ({ children, title, ...otherProps }: LayoutProps) => {
             <MainMenu />
           </Authorized>
           <div
-            className={`px-3 py-3 lg:pt-5 lg:pr-8 lg:pl-[292px] ${
+            className={`mx-3 my-3 lg:mt-5 lg:mr-8 lg:ml-[292px] ${
               pinned && sidebarContent ? 'lg:pr-[420px]' : ''
             }`}
             id="layout-content"
           >
             {children}
-            <div className="h-6"></div>
+            {/* <div className="h-6"></div> */}
           </div>
         </div>
         <Sidebar />
diff --git a/ui/src/components/sidebar/Sharing.tsx b/ui/src/components/sidebar/Sharing.tsx
index 319668c..4b12bed 100644
--- a/ui/src/components/sidebar/Sharing.tsx
+++ b/ui/src/components/sidebar/Sharing.tsx
@@ -106,145 +106,6 @@ const DELETE_SHARE_MUTATION = gql`
   }
 `
 
-// const ShareItemMoreDropdown = ({
-//   id,
-//   share,
-//   query,
-// }: ShareItemMoreDropdownProps) => {
-//   const { t } = useTranslation()
-
-//   const [addingPassword, setAddingPassword] = useState(false)
-//   const showPasswordInput = addingPassword || share.hasPassword
-
-//   const [passwordInputValue, setPasswordInputValue] = useState(
-//     share.hasPassword ? '**********' : ''
-//   )
-//   const [passwordHidden, setPasswordHidden] = useState(share.hasPassword)
-
-//   const hidePassword = (hide: boolean) => {
-//     setPasswordHidden(hide)
-//     if (hide) {
-//       setPasswordInputValue('**********')
-//     }
-//   }
-
-//   const [setPassword, { loading: setPasswordLoading }] = useMutation<
-//     sidebarProtectShare,
-//     sidebarProtectShareVariables
-//   >(PROTECT_SHARE_MUTATION, {
-//     refetchQueries: [{ query: query, variables: { id } }],
-//     onCompleted: data => {
-//       hidePassword(data.protectShareToken.hasPassword)
-//     },
-//     // refetchQueries: [{ query: query, variables: { id } }],
-//     variables: {
-//       token: share.token,
-//     },
-//   })
-
-//   let addPasswordInput = null
-//   if (showPasswordInput) {
-//     const setPasswordEvent = (event: React.KeyboardEvent<HTMLInputElement>) => {
-//       if (!passwordHidden && passwordInputValue != '' && event.key == 'Enter') {
-//         event.preventDefault()
-//         setPassword({
-//           variables: {
-//             token: share.token,
-//             password: (event.target as HTMLInputElement).value,
-//           },
-//         })
-//       }
-//     }
-
-//     addPasswordInput = (
-//       <Input
-//         disabled={setPasswordLoading}
-//         loading={setPasswordLoading}
-//         style={{ marginTop: 8, marginRight: 0, display: 'block' }}
-//         onClick={(e: MouseEvent) => e.stopPropagation()}
-//         value={passwordInputValue}
-//         type={passwordHidden ? 'password' : 'text'}
-//         onKeyUp={setPasswordEvent}
-//         onChange={event => {
-//           hidePassword(false)
-//           setPasswordInputValue(event.target.value)
-//         }}
-//         placeholder="Password"
-//         icon={
-//           <Icon
-//             name={passwordHidden ? 'lock' : 'arrow right'}
-//             link={!passwordHidden}
-//             onClick={setPasswordEvent}
-//           />
-//         }
-//       />
-//     )
-//   }
-
-//   const checkboxClick = () => {
-//     const enable = !showPasswordInput
-//     setAddingPassword(enable)
-//     if (!enable) {
-//       setPassword({
-//         variables: {
-//           token: share.token,
-//           password: null,
-//         },
-//       })
-//       setPasswordInputValue('')
-//     }
-//   }
-
-//   // const [dropdownOpen, setDropdownOpen] = useState(false)
-
-//   return (
-//     <Dropdown
-//       // onBlur={event => {
-//       //   console.log('Blur')
-//       // }}
-//       // onClick={() => setDropdownOpen(state => !state)}
-//       // onClose={() => setDropdownOpen(false)}
-//       // open={dropdownOpen}
-//       button
-//       text={t('general.action.more', 'More')}
-//       closeOnChange={false}
-//       closeOnBlur={false}
-//     >
-//       <Dropdown.Menu>
-//         <Dropdown.Item
-//           onKeyDown={(e: KeyboardEvent) => e.stopPropagation()}
-//           onClick={e => {
-//             e.stopPropagation()
-//             checkboxClick()
-//           }}
-//         >
-//           <Checkbox
-//             label={t('login_page.field.password', 'Password')}
-//             onClick={e => e.stopPropagation()}
-//             checked={showPasswordInput}
-//             onChange={() => {
-//               checkboxClick()
-//             }}
-//           />
-//           {addPasswordInput}
-//         </Dropdown.Item>
-//         {/* <Dropdown.Item
-//           text={t('general.action.delete', 'Delete')}
-//           icon="delete"
-//           disabled={deleteShareLoading}
-//           onClick={() => {
-//             deleteShare({
-//               variables: {
-//                 token: share.token,
-//               },
-//             })
-//           }}
-//         /> */}
-//       </Dropdown.Menu>
-//     </Dropdown>
-//   )
-// }
-
 const ArrowPopoverPanel = styled.div.attrs({
   className:
     'absolute right-6 -top-3 bg-white rounded shadow-md border border-gray-200 w-[260px]',
diff --git a/ui/src/primitives/form/Input.tsx b/ui/src/primitives/form/Input.tsx
index d16b33d..7acd89e 100644
--- a/ui/src/primitives/form/Input.tsx
+++ b/ui/src/primitives/form/Input.tsx
@@ -100,7 +100,7 @@ export const TextField = forwardRef(
 
     if (label) {
       return (
-        <label className={wrapperClasses}>
+        <label className={classNames(wrapperClasses, 'block')}>
           <span className="block text-xs uppercase font-semibold mb-1">
             {label}
           </span>
