-
-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(frontend): initial Settings design
- Loading branch information
Showing
8 changed files
with
216 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React, { useEffect } from 'react'; | ||
import useClipboard from 'react-use-clipboard'; | ||
import { useToasts } from 'react-toast-notifications'; | ||
|
||
const CopyButton: React.FC<{ textToCopy: string }> = ({ textToCopy }) => { | ||
const [isCopied, setCopied] = useClipboard(textToCopy, { | ||
successDuration: 1000, | ||
}); | ||
const { addToast } = useToasts(); | ||
|
||
useEffect(() => { | ||
if (isCopied) { | ||
addToast('Copied API key to clipboard', { | ||
appearance: 'info', | ||
autoDismiss: true, | ||
}); | ||
} | ||
}, [isCopied, addToast]); | ||
|
||
return ( | ||
<button | ||
onClick={setCopied} | ||
className="-ml-px relative inline-flex items-center px-4 py-2 border border-cool-gray-500 text-sm leading-5 font-medium text-white bg-indigo-500 hover:bg-indigo-400 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" | ||
> | ||
<svg | ||
className="w-5 h-5 text-white" | ||
fill="currentColor" | ||
viewBox="0 0 20 20" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path d="M8 2a1 1 0 000 2h2a1 1 0 100-2H8z" /> | ||
<path d="M3 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v6h-4.586l1.293-1.293a1 1 0 00-1.414-1.414l-3 3a1 1 0 000 1.414l3 3a1 1 0 001.414-1.414L10.414 13H15v3a2 2 0 01-2 2H5a2 2 0 01-2-2V5zM15 11h2a1 1 0 110 2h-2v-2z" /> | ||
</svg> | ||
</button> | ||
); | ||
}; | ||
|
||
export default CopyButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import React from 'react'; | ||
import Link from 'next/link'; | ||
import { useRouter } from 'next/router'; | ||
|
||
const SettingsLayout: React.FC = ({ children }) => { | ||
const router = useRouter(); | ||
const activeLinkColor = | ||
'border-indigo-600 text-indigo-500 focus:outline-none focus:text-indigo-500 focus:border-indigo-500'; | ||
|
||
const inactiveLinkColor = | ||
'border-transparent text-cool-gray-500 hover:text-cool-gray-400 hover:border-cool-gray-300 focus:outline-none focus:text-cool-gray-4700 focus:border-cool-gray-300'; | ||
|
||
const settingsLink = ({ | ||
text, | ||
route, | ||
regex, | ||
}: { | ||
text: string; | ||
route: string; | ||
regex: RegExp; | ||
}) => { | ||
return ( | ||
<Link href={route}> | ||
<a | ||
className={`whitespace-no-wrap pb-4 px-1 border-b-2 font-medium text-sm leading-5 ${ | ||
!!router.pathname.match(regex) ? activeLinkColor : inactiveLinkColor | ||
}`} | ||
aria-current="page" | ||
> | ||
{text} | ||
</a> | ||
</Link> | ||
); | ||
}; | ||
return ( | ||
<> | ||
<div className="border-b border-cool-gray-600 mt-10"> | ||
<div className="space-y-4 sm:flex sm:items-baseline sm:space-y-0 sm:space-x-10"> | ||
<h3 className="text-lg leading-6 font-medium text-white">Settings</h3> | ||
<div> | ||
<nav className="-mb-px flex space-x-8"> | ||
{settingsLink({ | ||
text: 'General Settings', | ||
route: '/settings/main', | ||
regex: /^\/settings(\/main)?$/, | ||
})} | ||
{settingsLink({ | ||
text: 'Plex Settings', | ||
route: '/settings/plex', | ||
regex: /^\/settings\/plex/, | ||
})} | ||
{settingsLink({ | ||
text: 'Services', | ||
route: '/settings/services', | ||
regex: /^\/settings\/services/, | ||
})} | ||
</nav> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="mt-10 text-white">{children}</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default SettingsLayout; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import React from 'react'; | ||
import useSWR from 'swr'; | ||
import LoadingSpinner from '../Common/LoadingSpinner'; | ||
import type { MainSettings } from '../../../server/lib/settings'; | ||
import CopyButton from './CopyButton'; | ||
|
||
const SettingsMain: React.FC = () => { | ||
const { data, error } = useSWR<MainSettings>('/api/v1/settings/main'); | ||
|
||
if (!data && !error) { | ||
return <LoadingSpinner />; | ||
} | ||
|
||
return ( | ||
<> | ||
<div> | ||
<h3 className="text-lg leading-6 font-medium text-cool-gray-200"> | ||
General Settings | ||
</h3> | ||
<p className="mt-1 max-w-2xl text-sm leading-5 text-cool-gray-500"> | ||
These are settings related to general Overseerr configuration. | ||
</p> | ||
</div> | ||
<div className="mt-6 sm:mt-5"> | ||
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> | ||
<label | ||
htmlFor="username" | ||
className="block text-sm font-medium leading-5 text-cool-gray-400 sm:mt-px sm:pt-2" | ||
> | ||
API Key | ||
</label> | ||
<div className="mt-1 sm:mt-0 sm:col-span-2"> | ||
<div className="max-w-lg flex rounded-md shadow-sm"> | ||
<input | ||
id="username" | ||
className="flex-1 form-input block w-full min-w-0 rounded-none rounded-l-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-cool-gray-700 border border-cool-gray-500" | ||
value={data?.apiKey} | ||
readOnly | ||
/> | ||
<CopyButton textToCopy={data?.apiKey ?? ''} /> | ||
<button className="-ml-px relative inline-flex items-center px-4 py-2 border border-cool-gray-500 text-sm leading-5 font-medium rounded-r-md text-white bg-indigo-500 hover:bg-indigo-400 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150"> | ||
<svg | ||
className="w-5 h-5" | ||
fill="currentColor" | ||
viewBox="0 0 20 20" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
fillRule="evenodd" | ||
d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" | ||
clipRule="evenodd" | ||
/> | ||
</svg> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default SettingsMain; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
import { NextPage } from 'next'; | ||
import SettingsLayout from '../../components/Settings/SettingsLayout'; | ||
import SettingsMain from '../../components/Settings/SettingsMain'; | ||
|
||
const SettingsPage: NextPage = () => { | ||
return ( | ||
<SettingsLayout> | ||
<SettingsMain /> | ||
</SettingsLayout> | ||
); | ||
}; | ||
|
||
export default SettingsPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
import { NextPage } from 'next'; | ||
import SettingsLayout from '../../components/Settings/SettingsLayout'; | ||
import SettingsMain from '../../components/Settings/SettingsMain'; | ||
|
||
const SettingsMainPage: NextPage = () => { | ||
return ( | ||
<SettingsLayout> | ||
<SettingsMain /> | ||
</SettingsLayout> | ||
); | ||
}; | ||
|
||
export default SettingsMainPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters