formatting tailwind classes with prettier

This commit is contained in:
spencerwooo
2022-02-04 16:05:28 +08:00
parent d8ef0733bf
commit e4f3ea7b05
22 changed files with 252 additions and 149 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"extends": ["next", "next/core-web-vitals"] "extends": ["next", "next/core-web-vitals", "prettier"]
} }
+36
View File
@@ -35,3 +35,39 @@ yarn-error.log*
# redis dump # redis dump
dump.rdb dump.rdb
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
.vscode/*
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
+9
View File
@@ -0,0 +1,9 @@
module.exports = {
printWidth: 120,
arrowParens: "avoid",
singleQuote: true,
semi: false,
plugins: [
require('prettier-plugin-tailwindcss')
]
}
+22 -6
View File
@@ -41,7 +41,9 @@ import type { OdFileObject, OdFolderObject } from '../types'
// Disabling SSR for some previews (image gallery view, and PDF view) // Disabling SSR for some previews (image gallery view, and PDF view)
const ReactViewer = dynamic(() => import('react-viewer'), { ssr: false }) const ReactViewer = dynamic(() => import('react-viewer'), { ssr: false })
const EPUBPreview = dynamic(() => import('./previews/EPUBPreview'), { ssr: false }) const EPUBPreview = dynamic(() => import('./previews/EPUBPreview'), {
ssr: false,
})
/** /**
* Convert url query into path string * Convert url query into path string
@@ -151,7 +153,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
const [selected, setSelected] = useState<{ [key: string]: boolean }>({}) const [selected, setSelected] = useState<{ [key: string]: boolean }>({})
const [totalSelected, setTotalSelected] = useState<0 | 1 | 2>(0) const [totalSelected, setTotalSelected] = useState<0 | 1 | 2>(0)
const [totalGenerating, setTotalGenerating] = useState<boolean>(false) const [totalGenerating, setTotalGenerating] = useState<boolean>(false)
const [folderGenerating, setFolderGenerating] = useState<{ [key: string]: boolean }>({}) const [folderGenerating, setFolderGenerating] = useState<{
[key: string]: boolean
}>({})
const router = useRouter() const router = useRouter()
const clipboard = useClipboard() const clipboard = useClipboard()
@@ -283,7 +287,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
downloadMultipleFiles({ toastId, router, files, folder }) downloadMultipleFiles({ toastId, router, files, folder })
.then(() => { .then(() => {
setTotalGenerating(false) setTotalGenerating(false)
toast.success('Finished downloading selected files.', { id: toastId }) toast.success('Finished downloading selected files.', {
id: toastId,
})
}) })
.catch(() => { .catch(() => {
setTotalGenerating(false) setTotalGenerating(false)
@@ -312,7 +318,13 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
setFolderGenerating({ ...folderGenerating, [id]: true }) setFolderGenerating({ ...folderGenerating, [id]: true })
const toastId = toast.loading(DownloadingToast(router)) const toastId = toast.loading(DownloadingToast(router))
downloadTreelikeMultipleFiles({ toastId, router, files, basePath: path, folder: name }) downloadTreelikeMultipleFiles({
toastId,
router,
files,
basePath: path,
folder: name,
})
.then(() => { .then(() => {
setFolderGenerating({ ...folderGenerating, [id]: false }) setFolderGenerating({ ...folderGenerating, [id]: false })
toast.success('Finished downloading folder.', { id: toastId }) toast.success('Finished downloading folder.', { id: toastId })
@@ -394,7 +406,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
render: <FontAwesomeIcon icon={['fas', 'copy']} />, render: <FontAwesomeIcon icon={['fas', 'copy']} />,
onClick: i => { onClick: i => {
clipboard.copy(i.alt ? `${getBaseUrl()}/api?path=${path + '/' + i.alt}&raw=true` : '') clipboard.copy(i.alt ? `${getBaseUrl()}/api?path=${path + '/' + i.alt}&raw=true` : '')
toast('Copied image permanent link to clipboard.', { icon: '👌' }) toast('Copied image permanent link to clipboard.', {
icon: '👌',
})
}, },
}, },
]) ])
@@ -544,7 +558,9 @@ const FileListing: FC<{ query?: ParsedUrlQuery }> = ({ query }) => {
const fileName = file.name const fileName = file.name
const fileExtension = fileName.slice(((fileName.lastIndexOf('.') - 1) >>> 0) + 2).toLowerCase() const fileExtension = fileName.slice(((fileName.lastIndexOf('.') - 1) >>> 0) + 2).toLowerCase()
const previewType = getPreviewType(fileExtension, { video: Boolean(file.video) }) const previewType = getPreviewType(fileExtension, {
video: Boolean(file.video),
})
if (previewType) { if (previewType) {
switch (previewType) { switch (previewType) {
case preview.image: case preview.image:
+1 -1
View File
@@ -4,7 +4,7 @@ const FourOhFour: React.FC<{ errorMsg: string }> = ({ errorMsg }) => {
return ( return (
<div className="my-12"> <div className="my-12">
<div className="w-1/3 mx-auto"> <div className="w-1/3 mx-auto">
<Image src='/images/fabulous-rip-2.png' alt="404" width={912} height={912} priority /> <Image src="/images/fabulous-rip-2.png" alt="404" width={912} height={912} priority />
</div> </div>
<div className="mt-6 text-gray-500 max-w-xl mx-auto"> <div className="mt-6 text-gray-500 max-w-xl mx-auto">
<div className="text-xl font-bold mb-8"> <div className="text-xl font-bold mb-8">
+6 -2
View File
@@ -81,7 +81,9 @@ export async function downloadMultipleFiles({
// Create zip file and download it // Create zip file and download it
const b = await zip.generateAsync({ type: 'blob' }, metadata => { const b = await zip.generateAsync({ type: 'blob' }, metadata => {
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), { id: toastId }) toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), {
id: toastId,
})
}) })
downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' }) downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' })
} }
@@ -147,7 +149,9 @@ export async function downloadTreelikeMultipleFiles({
// Create zip file and download it // Create zip file and download it
const b = await zip.generateAsync({ type: 'blob' }, metadata => { const b = await zip.generateAsync({ type: 'blob' }, metadata => {
toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), { id: toastId }) toast.loading(DownloadingToast(router, metadata.percent.toFixed(0)), {
id: toastId,
})
}) })
downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' }) downloadBlob({ blob: b, name: folder ? folder + '.zip' : 'download.zip' })
} }
+5 -5
View File
@@ -21,10 +21,10 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return ( return (
<> <>
<PreviewContainer> <PreviewContainer>
<div className="md:flex-row md:space-x-4 flex flex-col space-y-4"> <div className="flex flex-col space-y-4 md:flex-row md:space-x-4">
<div className="dark:bg-gray-700 aspect-square flex items-center justify-center w-full md:w-40 transition-all duration-75 bg-gray-100 rounded"> <div className="flex aspect-square w-full items-center justify-center rounded bg-gray-100 transition-all duration-75 dark:bg-gray-700 md:w-40">
{playerStatus === PlayerState.Loading ? ( {playerStatus === PlayerState.Loading ? (
<LoadingIcon className="animate-spin w-5 h-5 inline-block" /> <LoadingIcon className="inline-block h-5 w-5 animate-spin" />
) : ( ) : (
<FontAwesomeIcon <FontAwesomeIcon
className={`h-5 w-5 ${playerStatus === PlayerState.Playing ? 'animate-spin' : ''}`} className={`h-5 w-5 ${playerStatus === PlayerState.Playing ? 'animate-spin' : ''}`}
@@ -33,7 +33,7 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
/> />
)} )}
</div> </div>
<div className="flex flex-col w-full space-y-2"> <div className="flex w-full flex-col space-y-2">
<div>{file.name}</div> <div>{file.name}</div>
<div className="pb-4 text-sm text-gray-500"> <div className="pb-4 text-sm text-gray-500">
Last modified:{' '} Last modified:{' '}
@@ -44,7 +44,7 @@ const AudioPreview: FC<{ file: OdFileObject }> = ({ file }) => {
</div> </div>
<ReactAudioPlayer <ReactAudioPlayer
className="w-full h-11" className="h-11 w-full"
src={file['@microsoft.graph.downloadUrl']} src={file['@microsoft.graph.downloadUrl']}
controls controls
onCanPlay={() => setPlayerStatus(PlayerState.Ready)} onCanPlay={() => setPlayerStatus(PlayerState.Ready)}
+2 -2
View File
@@ -1,10 +1,10 @@
export function PreviewContainer({ children }): JSX.Element { export function PreviewContainer({ children }): JSX.Element {
return <div className="dark:bg-gray-900 p-3 bg-white rounded dark:text-white">{children}</div> return <div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-white">{children}</div>
} }
export function DownloadBtnContainer({ children }): JSX.Element { export function DownloadBtnContainer({ children }): JSX.Element {
return ( return (
<div className="border-t rounded border-gray-900/10 dark:border-gray-500/30 p-2 sticky bottom-0 left-0 right-0 z-10 bg-white bg-opacity-80 backdrop-blur-md dark:bg-gray-900"> <div className="sticky bottom-0 left-0 right-0 z-10 rounded border-t border-gray-900/10 bg-white bg-opacity-80 p-2 backdrop-blur-md dark:border-gray-500/30 dark:bg-gray-900">
{children} {children}
</div> </div>
) )
+18 -18
View File
@@ -13,53 +13,53 @@ const DefaultPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return ( return (
<div> <div>
<PreviewContainer> <PreviewContainer>
<div className="md:flex px-5 py-4 md:space-x-8 items-center"> <div className="items-center px-5 py-4 md:flex md:space-x-8">
<div className="text-center border rounded-lg px-10 py-20 border-gray-900/10 dark:border-gray-500/30"> <div className="rounded-lg border border-gray-900/10 px-10 py-20 text-center dark:border-gray-500/30">
<FontAwesomeIcon icon={getFileIcon(file.name, { video: Boolean(file.video) })} /> <FontAwesomeIcon icon={getFileIcon(file.name, { video: Boolean(file.video) })} />
<div className="font-medium text-sm mt-6 md:w-20 overflow-hidden truncate">{file.name}</div> <div className="mt-6 overflow-hidden truncate text-sm font-medium md:w-20">{file.name}</div>
</div> </div>
<div className="md:flex-1 flex flex-col py-4 space-y-2"> <div className="flex flex-col space-y-2 py-4 md:flex-1">
<div> <div>
<div className="font-medium text-xs opacity-80 uppercase py-2">Last modified</div> <div className="py-2 text-xs font-medium uppercase opacity-80">Last modified</div>
<div>{formatModifiedDateTime(file.lastModifiedDateTime)}</div> <div>{formatModifiedDateTime(file.lastModifiedDateTime)}</div>
</div> </div>
<div> <div>
<div className="font-medium text-xs opacity-80 uppercase py-2">File size</div> <div className="py-2 text-xs font-medium uppercase opacity-80">File size</div>
<div>{humanFileSize(file.size)}</div> <div>{humanFileSize(file.size)}</div>
</div> </div>
<div> <div>
<div className="font-medium text-xs opacity-80 uppercase py-2">MIME type</div> <div className="py-2 text-xs font-medium uppercase opacity-80">MIME type</div>
<div>{file.file.mimeType}</div> <div>{file.file.mimeType}</div>
</div> </div>
<div> <div>
<div className="font-medium text-xs opacity-80 uppercase py-2">Hashes</div> <div className="py-2 text-xs font-medium uppercase opacity-80">Hashes</div>
<table className="w-full overflow-scroll block md:table whitespace-nowrap text-sm"> <table className="block w-full overflow-scroll whitespace-nowrap text-sm md:table">
<tbody> <tbody>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Quick XOR Quick XOR
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono"> <td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.quickXorHash} {file.file.hashes.quickXorHash}
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
SHA1 SHA1
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono"> <td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha1Hash} {file.file.hashes.sha1Hash}
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
SHA256 SHA256
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400 font-mono"> <td className="whitespace-nowrap py-1 px-3 font-mono text-gray-500 dark:text-gray-400">
{file.file.hashes.sha256Hash} {file.file.hashes.sha256Hash}
</td> </td>
</tr> </tr>
+9 -3
View File
@@ -36,11 +36,17 @@ const EPUBPreview: FC<{ file: OdFileObject }> = ({ file }) => {
return ( return (
<div> <div>
<div <div
className="dark:bg-gray-900 md:p-3 no-scrollbar flex flex-col w-full overflow-scroll bg-white rounded" className="no-scrollbar flex w-full flex-col overflow-scroll rounded bg-white dark:bg-gray-900 md:p-3"
style={{ maxHeight: '90vh' }} style={{ maxHeight: '90vh' }}
> >
<div className="no-scrollbar flex-1 w-full overflow-scroll" ref={epubContainer} style={{ minHeight: '70vh' }}> <div className="no-scrollbar w-full flex-1 overflow-scroll" ref={epubContainer} style={{ minHeight: '70vh' }}>
<div style={{ position: 'absolute', width: epubContainerWidth, height: '70vh' }}> <div
style={{
position: 'absolute',
width: epubContainerWidth,
height: '70vh',
}}
>
<ReactReader <ReactReader
url={file['@microsoft.graph.downloadUrl']} url={file['@microsoft.graph.downloadUrl']}
getRendition={rendition => fixEpub(rendition)} getRendition={rendition => fixEpub(rendition)}
+5 -5
View File
@@ -14,11 +14,11 @@ import DownloadButtonGroup from '../DownloadBtnGtoup'
import useAxiosGet from '../../utils/fetchOnMount' import useAxiosGet from '../../utils/fetchOnMount'
import { DownloadBtnContainer, PreviewContainer } from './Containers' import { DownloadBtnContainer, PreviewContainer } from './Containers'
const MarkdownPreview: FC<{ file: any; path: string; standalone?: boolean }> = ({ const MarkdownPreview: FC<{
file, file: any
path, path: string
standalone = true, standalone?: boolean
}) => { }> = ({ file, path, standalone = true }) => {
const { response: content, error, validating } = useAxiosGet(file['@microsoft.graph.downloadUrl']) const { response: content, error, validating } = useAxiosGet(file['@microsoft.graph.downloadUrl'])
// The parent folder of the markdown file, which is also the relative image folder // The parent folder of the markdown file, which is also the relative image folder
+1 -1
View File
@@ -9,7 +9,7 @@ const PDFEmbedPreview: React.FC<{ file: any }> = ({ file }) => {
return ( return (
<div> <div>
<div className="w-full rounded overflow-hidden" style={{ height: '90vh' }}> <div className="w-full overflow-hidden rounded" style={{ height: '90vh' }}>
<iframe src={url} frameBorder="0" width="100%" height="100%"></iframe> <iframe src={url} frameBorder="0" width="100%" height="100%"></iframe>
</div> </div>
<DownloadBtnContainer> <DownloadBtnContainer>
+1 -1
View File
@@ -33,7 +33,7 @@ const TextPreview = ({ file }) => {
return ( return (
<div> <div>
<PreviewContainer> <PreviewContainer>
<pre className="md:p-3 p-0 overflow-x-scroll text-sm">{content}</pre> <pre className="overflow-x-scroll p-0 text-sm md:p-3">{content}</pre>
</PreviewContainer> </PreviewContainer>
<DownloadBtnContainer> <DownloadBtnContainer>
<DownloadButtonGroup downloadUrl={file['@microsoft.graph.downloadUrl']} /> <DownloadButtonGroup downloadUrl={file['@microsoft.graph.downloadUrl']} />
+1 -1
View File
@@ -40,7 +40,7 @@ const TextPreview = ({ file }) => {
return ( return (
<div> <div>
<PreviewContainer> <PreviewContainer>
<pre className="md:p-3 p-0 overflow-x-scroll text-sm">{content}</pre> <pre className="overflow-x-scroll p-0 text-sm md:p-3">{content}</pre>
</PreviewContainer> </PreviewContainer>
<DownloadBtnContainer> <DownloadBtnContainer>
<div className="flex justify-center"> <div className="flex justify-center">
+4 -1
View File
@@ -27,7 +27,10 @@ const VideoPreview: React.FC<{ file: OdFileObject }> = ({ file }) => {
options={{ options={{
volume: 1.0, volume: 1.0,
lang: 'en', lang: 'en',
video: { url: file['@microsoft.graph.downloadUrl'], pic: thumbnail }, video: {
url: file['@microsoft.graph.downloadUrl'],
pic: thumbnail,
},
subtitle: { url: subtitle }, subtitle: { url: subtitle },
}} }}
/> />
+7 -7
View File
@@ -10,22 +10,22 @@
module.exports = { module.exports = {
// The clientId and clientSecret are used to authenticate the user with Microsoft Graph API using OAuth. You would // The clientId and clientSecret are used to authenticate the user with Microsoft Graph API using OAuth. You would
// not need to change anything here if you can authenticate with your personal Microsoft account with OneDrive International. // not need to change anything here if you can authenticate with your personal Microsoft account with OneDrive International.
clientId: "d87bcc39-1750-4ca0-ad54-f8d0efbb2735", clientId: 'd87bcc39-1750-4ca0-ad54-f8d0efbb2735',
obfuscatedClientSecret: "U2FsdGVkX1830zo3/pFDqaBCVBb37iLw3WnBDWGF9GIB2f4apzv0roemp8Y+iIxI3Ih5ecyukqELQEGzZlYiWg==", obfuscatedClientSecret: 'U2FsdGVkX1830zo3/pFDqaBCVBb37iLw3WnBDWGF9GIB2f4apzv0roemp8Y+iIxI3Ih5ecyukqELQEGzZlYiWg==',
// The redirectUri is the URL that the user will be redirected to after they have authenticated with Microsoft Graph API. // The redirectUri is the URL that the user will be redirected to after they have authenticated with Microsoft Graph API.
// Likewise, you would not need to change redirectUri if you are using your personal Microsoft account with OneDrive International. // Likewise, you would not need to change redirectUri if you are using your personal Microsoft account with OneDrive International.
redirectUri: "http://localhost", redirectUri: 'http://localhost',
// These are the URLs of the OneDrive API endpoints. You would not need to change anything here if you are using OneDrive International // These are the URLs of the OneDrive API endpoints. You would not need to change anything here if you are using OneDrive International
// or E5 Subscription OneDrive for Business. You may need to change these if you are using OneDrive 世纪互联. // or E5 Subscription OneDrive for Business. You may need to change these if you are using OneDrive 世纪互联.
authApi: "https://login.microsoftonline.com/common/oauth2/v2.0/token", authApi: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
driveApi: "https://graph.microsoft.com/v1.0/me/drive", driveApi: 'https://graph.microsoft.com/v1.0/me/drive',
// The scope we require are listed here, in most cases you would not need to change this as well. // The scope we require are listed here, in most cases you would not need to change this as well.
scope: "user.read files.read.all offline_access", scope: 'user.read files.read.all offline_access',
// The directLinkRegex is used to match the direct link of the file from the response of the API. We originally use this to prevent // The directLinkRegex is used to match the direct link of the file from the response of the API. We originally use this to prevent
// unauthorised use of the proxied download feature - but that is disabled for now. So you can safely ignore this settings. // unauthorised use of the proxied download feature - but that is disabled for now. So you can safely ignore this settings.
directLinkRegex: "public[.].*[.]files[.]1drv[.]com" directLinkRegex: 'public[.].*[.]files[.]1drv[.]com',
} }
+16 -20
View File
@@ -7,17 +7,17 @@ module.exports = {
// Make sure this is exactly the same as the email address you use to sign into your Microsoft account. // Make sure this is exactly the same as the email address you use to sign into your Microsoft account.
// You can also put this in your Vercel's environment variable 'NEXT_PUBLIC_USER_PRINCIPLE_NAME' if you worry about // You can also put this in your Vercel's environment variable 'NEXT_PUBLIC_USER_PRINCIPLE_NAME' if you worry about
// your email being exposed in public. // your email being exposed in public.
userPrincipalName: process.env.NEXT_PUBLIC_USER_PRINCIPLE_NAME || "spencer@spwoo.onmicrosoft.com", userPrincipalName: process.env.NEXT_PUBLIC_USER_PRINCIPLE_NAME || 'spencer@spwoo.onmicrosoft.com',
// [OPTIONAL] This is the website icon to the left of the title inside the navigation bar. It should be placed under the // [OPTIONAL] This is the website icon to the left of the title inside the navigation bar. It should be placed under the
// /public directory of your GitHub project (not your OneDrive folder!), and referenced here by its relative path to /public. // /public directory of your GitHub project (not your OneDrive folder!), and referenced here by its relative path to /public.
icon: "/icons/128.png", icon: '/icons/128.png',
// The name of your website. Present alongside your icon. // The name of your website. Present alongside your icon.
title: "Spencer's OneDrive", title: "Spencer's OneDrive",
// The folder that you are to share publicly with onedrive-vercel-index. Use '/' if you want to share your root folder. // The folder that you are to share publicly with onedrive-vercel-index. Use '/' if you want to share your root folder.
baseDirectory: "/", baseDirectory: '/',
// [OPTIONAL] This represents the maximum number of items that one directory lists, pagination supported. // [OPTIONAL] This represents the maximum number of items that one directory lists, pagination supported.
// Do note that this is limited up to 200 items by the upstream OneDrive API. // Do note that this is limited up to 200 items by the upstream OneDrive API.
@@ -26,39 +26,35 @@ module.exports = {
// [OPTIONAL] We use Google Fonts natively for font customisations. // [OPTIONAL] We use Google Fonts natively for font customisations.
// You can check and generate the required links and names at https://fonts.google.com. // You can check and generate the required links and names at https://fonts.google.com.
// googleFontSans - the sans serif font used in onedrive-vercel-index. // googleFontSans - the sans serif font used in onedrive-vercel-index.
googleFontSans: "Inter", googleFontSans: 'Inter',
// googleFontMono - the monospace font used in onedrive-vercel-index. // googleFontMono - the monospace font used in onedrive-vercel-index.
googleFontMono: "Fira Mono", googleFontMono: 'Fira Mono',
// googleFontLinks - an array of links for referencing the google font assets. // googleFontLinks - an array of links for referencing the google font assets.
googleFontLinks: [ googleFontLinks: ['https://fonts.googleapis.com/css2?family=Fira+Mono&family=Inter:wght@400;500;700&display=swap'],
"https://fonts.googleapis.com/css2?family=Fira+Mono&family=Inter:wght@400;500;700&display=swap"
],
// [OPTIONAL] The footer component of your website. You can write HTML here, but you need to escape double // [OPTIONAL] The footer component of your website. You can write HTML here, but you need to escape double
// quotes - changing " to \". You can write anything here, and if you like badges, generate some with https://shields.io // quotes - changing " to \". You can write anything here, and if you like badges, generate some with https://shields.io
footer: "Powered by <a href=\"https://github.com/spencerwooo/onedrive-vercel-index\" target=\"_blank\" rel=\"noopener noreferrer\">onedrive-vercel-index</a>. Made with ❤ by SpencerWoo.", footer:
'Powered by <a href="https://github.com/spencerwooo/onedrive-vercel-index" target="_blank" rel="noopener noreferrer">onedrive-vercel-index</a>. Made with ❤ by SpencerWoo.',
// [OPTIONAL] This is where you specify the folders that are password protected. It is an array of paths pointing to all // [OPTIONAL] This is where you specify the folders that are password protected. It is an array of paths pointing to all
// the directories in which you have .password set. Check the documentation for details. // the directories in which you have .password set. Check the documentation for details.
protectedRoutes: [ protectedRoutes: ['/🌞 Private folder/u-need-a-password', '/🥟 Some test files/Protected route'],
"/🌞 Private folder/u-need-a-password",
"/🥟 Some test files/Protected route"
],
// [OPTIONAL] Use "" here if you want to remove this email address from the nav bar. // [OPTIONAL] Use "" here if you want to remove this email address from the nav bar.
email: "mailto:spencer.wushangbo@gmail.com", email: 'mailto:spencer.wushangbo@gmail.com',
// [OPTIONAL] This is an array of names and links for setting your social information and links. // [OPTIONAL] This is an array of names and links for setting your social information and links.
// In the latest update, all brand icons inside font awesome is supported and the icon to render is based on the name // In the latest update, all brand icons inside font awesome is supported and the icon to render is based on the name
// you provide. See the documentation for details. // you provide. See the documentation for details.
links: [ links: [
{ {
"name": "GitHub", name: 'GitHub',
"link": "https://github.com/spencerwooo/onedrive-vercel-index" link: 'https://github.com/spencerwooo/onedrive-vercel-index',
}, },
{ {
"name": "Telegram", name: 'Telegram',
"link": "https://t.me/realSpencerWoo" link: 'https://t.me/realSpencerWoo',
} },
] ],
} }
+5 -1
View File
@@ -6,7 +6,8 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint",
"format": "prettier components/**/*.tsx config/*.js pages/**/*.tsx {types,utils}/**/*.ts --write"
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/fontawesome-svg-core": "^1.2.35",
@@ -58,7 +59,10 @@
"autoprefixer": "^10.4.0", "autoprefixer": "^10.4.0",
"eslint": "8.8.0", "eslint": "8.8.0",
"eslint-config-next": "12.0.10", "eslint-config-next": "12.0.10",
"eslint-config-prettier": "^8.3.0",
"postcss": "^8.4.5", "postcss": "^8.4.5",
"prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.4",
"tailwindcss": "^3.0.18", "tailwindcss": "^3.0.18",
"typescript": "4.5.5" "typescript": "4.5.5"
} }
+39 -39
View File
@@ -12,24 +12,24 @@ export default function OAuthStep1() {
const router = useRouter() const router = useRouter()
return ( return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white"> <div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head> <Head>
<title>{`OAuth Step 1 - ${siteConfig.title}`}</title> <title>{`OAuth Step 1 - ${siteConfig.title}`}</title>
</Head> </Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full"> <main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar /> <Navbar />
<div className="w-full max-w-5xl p-4 mx-auto"> <div className="mx-auto w-full max-w-5xl p-4">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3"> <div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52"> <div className="mx-auto w-52">
<Image src="/images/fabulous-fireworks.png" width={912} height={912} alt="fabulous fireworks" priority /> <Image src="/images/fabulous-fireworks.png" width={912} height={912} alt="fabulous fireworks" priority />
</div> </div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3> <h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 1/3: Preparations</h3> <h3 className="mt-4 mb-2 text-lg font-medium">Step 1/3: Preparations</h3>
<p className="py-1 text-yellow-400 font-medium text-sm"> <p className="py-1 text-sm font-medium text-yellow-400">
<FontAwesomeIcon icon="exclamation-triangle" className="mr-1" /> If you have not specified a REDIS_URL <FontAwesomeIcon icon="exclamation-triangle" className="mr-1" /> If you have not specified a REDIS_URL
inside your Vercel env variable, go initialise one at{' '} inside your Vercel env variable, go initialise one at{' '}
<a href="https://upstash.com/" target="_blank" rel="noopener noreferrer" className="underline"> <a href="https://upstash.com/" target="_blank" rel="noopener noreferrer" className="underline">
@@ -49,76 +49,76 @@ export default function OAuthStep1() {
<p className="py-1"> <p className="py-1">
Authorisation is required as no valid{' '} Authorisation is required as no valid{' '}
<code className="text-sm font-mono underline decoration-wavy decoration-pink-600">access_token</code> or{' '} <code className="font-mono text-sm underline decoration-pink-600 decoration-wavy">access_token</code> or{' '}
<code className="text-sm font-mono underline decoration-wavy decoration-green-600">refresh_token</code> is <code className="font-mono text-sm underline decoration-green-600 decoration-wavy">refresh_token</code> is
present on this deployed instance. Check the following configurations before proceeding with authorising present on this deployed instance. Check the following configurations before proceeding with authorising
onedrive-vercel-index with your own Microsoft account. onedrive-vercel-index with your own Microsoft account.
</p> </p>
<div className="overflow-hidden my-4"> <div className="my-4 overflow-hidden">
<table className="table-auto min-w-full"> <table className="min-w-full table-auto">
<tbody> <tbody>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
CLIENT_ID CLIENT_ID
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.clientId}</code> <code className="font-mono text-sm">{apiConfig.clientId}</code>
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
CLIENT_SECRET* CLIENT_SECRET*
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.obfuscatedClientSecret}</code> <code className="font-mono text-sm">{apiConfig.obfuscatedClientSecret}</code>
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
REDIRECT_URI REDIRECT_URI
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.redirectUri}</code> <code className="font-mono text-sm">{apiConfig.redirectUri}</code>
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Auth API URL Auth API URL
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.authApi}</code> <code className="font-mono text-sm">{apiConfig.authApi}</code>
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
Drive API URL Drive API URL
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.driveApi}</code> <code className="font-mono text-sm">{apiConfig.driveApi}</code>
</td> </td>
</tr> </tr>
<tr className="bg-white border-y dark:bg-gray-900 dark:border-gray-700"> <tr className="border-y bg-white dark:border-gray-700 dark:bg-gray-900">
<td className="bg-gray-50 dark:bg-gray-800 py-1 px-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> <td className="bg-gray-50 py-1 px-3 text-left text-xs font-medium uppercase tracking-wider text-gray-700 dark:bg-gray-800 dark:text-gray-400">
API Scope API Scope
</td> </td>
<td className="py-1 px-3 text-gray-500 whitespace-nowrap dark:text-gray-400"> <td className="whitespace-nowrap py-1 px-3 text-gray-500 dark:text-gray-400">
<code className="text-sm font-mono">{apiConfig.scope}</code> <code className="font-mono text-sm">{apiConfig.scope}</code>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<p className="py-1 font-medium text-sm"> <p className="py-1 text-sm font-medium">
<FontAwesomeIcon icon="exclamation-triangle" className="mr-1 text-yellow-400" /> If you see anything <FontAwesomeIcon icon="exclamation-triangle" className="mr-1 text-yellow-400" /> If you see anything
missing or incorrect, you need to reconfigure <code className="text-xs font-mono">/config/api.json</code>{' '} missing or incorrect, you need to reconfigure <code className="font-mono text-xs">/config/api.json</code>{' '}
and redeploy this instance. and redeploy this instance.
</p> </p>
<div className="text-right mb-2 mt-6"> <div className="mb-2 mt-6 text-right">
<button <button
className="text-white bg-gradient-to-r from-cyan-500 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center" className="rounded-lg bg-gradient-to-r from-cyan-500 to-blue-500 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800"
onClick={() => { onClick={() => {
router.push('/onedrive-vercel-index-oauth/step-2') router.push('/onedrive-vercel-index-oauth/step-2')
}} }}
+17 -17
View File
@@ -20,16 +20,16 @@ export default function OAuthStep2() {
const oAuthUrl = generateAuthorisationUrl() const oAuthUrl = generateAuthorisationUrl()
return ( return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white"> <div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head> <Head>
<title>{`OAuth Step 2 - ${siteConfig.title}`}</title> <title>{`OAuth Step 2 - ${siteConfig.title}`}</title>
</Head> </Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full"> <main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar /> <Navbar />
<div className="w-full max-w-5xl p-4 mx-auto"> <div className="mx-auto w-full max-w-5xl p-4">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3"> <div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52"> <div className="mx-auto w-52">
<Image <Image
src="/images/fabulous-come-back-later.png" src="/images/fabulous-come-back-later.png"
@@ -39,17 +39,17 @@ export default function OAuthStep2() {
priority priority
/> />
</div> </div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3> <h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 2/3: Get authorisation code</h3> <h3 className="mt-4 mb-2 text-lg font-medium">Step 2/3: Get authorisation code</h3>
<p className="py-1 text-red-400 font-medium text-sm"> <p className="py-1 text-sm font-medium text-red-400">
<FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> If you are not the owner of this website, <FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> If you are not the owner of this website,
stop now, as continuing with this process may expose your personal files in OneDrive. stop now, as continuing with this process may expose your personal files in OneDrive.
</p> </p>
<div <div
className="relative my-2 font-mono border border-gray-500/50 rounded text-sm bg-gray-50 dark:bg-gray-800 cursor-pointer hover:opacity-80" className="relative my-2 cursor-pointer rounded border border-gray-500/50 bg-gray-50 font-mono text-sm hover:opacity-80 dark:bg-gray-800"
onClick={() => { onClick={() => {
window.open(oAuthUrl) window.open(oAuthUrl)
}} }}
@@ -57,25 +57,25 @@ export default function OAuthStep2() {
<div className="absolute top-0 right-0 p-1 opacity-60"> <div className="absolute top-0 right-0 p-1 opacity-60">
<FontAwesomeIcon icon="external-link-alt" /> <FontAwesomeIcon icon="external-link-alt" />
</div> </div>
<pre className="p-2 whitespace-pre-wrap overflow-x-auto"> <pre className="overflow-x-auto whitespace-pre-wrap p-2">
<code>{oAuthUrl}</code> <code>{oAuthUrl}</code>
</pre> </pre>
</div> </div>
<p className="py-1"> <p className="py-1">
The OAuth link for getting the authorisation code has been created. Click on the link above to get the{' '} The OAuth link for getting the authorisation code has been created. Click on the link above to get the{' '}
<b className="underline decoration-wavy decoration-yellow-400">authorisation code</b>. Your browser will <b className="underline decoration-yellow-400 decoration-wavy">authorisation code</b>. Your browser will
open a new tab to Microsoft&apos;s account login page. After logging in and authenticating with your open a new tab to Microsoft&apos;s account login page. After logging in and authenticating with your
Microsoft account, you will be redirected to a blank page on localhost. Paste{' '} Microsoft account, you will be redirected to a blank page on localhost. Paste{' '}
<b className="underline decoration-wavy decoration-teal-500">the entire redirected URL</b> down below. <b className="underline decoration-teal-500 decoration-wavy">the entire redirected URL</b> down below.
</p> </p>
<div className="my-4 rounded overflow-hidden w-2/3 mx-auto"> <div className="my-4 mx-auto w-2/3 overflow-hidden rounded">
<Image src="/images/step-2-screenshot.png" width={1466} height={607} alt="step 2 screenshot" /> <Image src="/images/step-2-screenshot.png" width={1466} height={607} alt="step 2 screenshot" />
</div> </div>
<input <input
className={`w-full flex-1 border bg-gray-50 dark:bg-gray-800 dark:text-white focus:ring focus:outline-none p-2 font-mono rounded my-2 font-medium text-sm ${ className={`my-2 w-full flex-1 rounded border bg-gray-50 p-2 font-mono text-sm font-medium focus:outline-none focus:ring dark:bg-gray-800 dark:text-white ${
authCode authCode
? 'border-green-500/50 focus:ring-green-500/30 dark:focus:ring-green-500/40' ? 'border-green-500/50 focus:ring-green-500/30 dark:focus:ring-green-500/40'
: 'border-red-500/50 focus:ring-red-500/30 dark:focus:ring-red-500/40' : 'border-red-500/50 focus:ring-red-500/30 dark:focus:ring-red-500/40'
@@ -91,7 +91,7 @@ export default function OAuthStep2() {
/> />
<p className="py-1">The authorisation code extracted is:</p> <p className="py-1">The authorisation code extracted is:</p>
<p className="my-2 font-mono border border-gray-400/20 rounded text-sm bg-gray-50 dark:bg-gray-800 p-2 opacity-80 truncate overflow-hidden"> <p className="my-2 overflow-hidden truncate rounded border border-gray-400/20 bg-gray-50 p-2 font-mono text-sm opacity-80 dark:bg-gray-800">
{authCode || <span className="animate-pulse">Waiting for code...</span>} {authCode || <span className="animate-pulse">Waiting for code...</span>}
</p> </p>
@@ -101,9 +101,9 @@ export default function OAuthStep2() {
: '❌ No valid code extracted.'} : '❌ No valid code extracted.'}
</p> </p>
<div className="text-right mb-2 mt-6"> <div className="mb-2 mt-6 text-right">
<button <button
className="text-white bg-gradient-to-br from-green-500 to-cyan-400 hover:bg-gradient-to-bl focus:ring-4 focus:ring-green-200 dark:focus:ring-green-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center disabled:cursor-not-allowed disabled:grayscale" className="rounded-lg bg-gradient-to-br from-green-500 to-cyan-400 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-green-200 disabled:cursor-not-allowed disabled:grayscale dark:focus:ring-green-800"
disabled={authCode === ''} disabled={authCode === ''}
onClick={() => { onClick={() => {
setButtonLoading(true) setButtonLoading(true)
@@ -112,7 +112,7 @@ export default function OAuthStep2() {
> >
{buttonLoading ? ( {buttonLoading ? (
<> <>
<span>Requesting tokens</span> <LoadingIcon className="animate-spin w-4 h-4 ml-1 inline" /> <span>Requesting tokens</span> <LoadingIcon className="ml-1 inline h-4 w-4 animate-spin" />
</> </>
) : ( ) : (
<> <>
+17 -17
View File
@@ -36,7 +36,7 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
setButtonError(false) setButtonError(false)
setButtonContent( setButtonContent(
<div> <div>
<span>Storing tokens</span> <LoadingIcon className="animate-spin w-4 h-4 ml-1 inline" /> <span>Storing tokens</span> <LoadingIcon className="ml-1 inline h-4 w-4 animate-spin" />
</div> </div>
) )
@@ -84,16 +84,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
} }
return ( return (
<div className="dark:bg-gray-900 flex flex-col items-center justify-center min-h-screen bg-white"> <div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
<Head> <Head>
<title>{`OAuth Step 3 - ${siteConfig.title}`}</title> <title>{`OAuth Step 3 - ${siteConfig.title}`}</title>
</Head> </Head>
<main className="bg-gray-50 dark:bg-gray-800 flex flex-col flex-1 w-full"> <main className="flex w-full flex-1 flex-col bg-gray-50 dark:bg-gray-800">
<Navbar /> <Navbar />
<div className="w-full max-w-5xl p-4 mx-auto"> <div className="mx-auto w-full max-w-5xl p-4">
<div className="dark:bg-gray-900 dark:text-gray-100 bg-white rounded p-3"> <div className="rounded bg-white p-3 dark:bg-gray-900 dark:text-gray-100">
<div className="mx-auto w-52"> <div className="mx-auto w-52">
<Image <Image
src="/images/fabulous-celebration.png" src="/images/fabulous-celebration.png"
@@ -103,16 +103,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
priority priority
/> />
</div> </div>
<h3 className="font-medium text-xl mb-4 text-center">Welcome to your new onedrive-vercel-index 🎉</h3> <h3 className="mb-4 text-center text-xl font-medium">Welcome to your new onedrive-vercel-index 🎉</h3>
<h3 className="font-medium text-lg mt-4 mb-2">Step 3/3: Get access and refresh tokens</h3> <h3 className="mt-4 mb-2 text-lg font-medium">Step 3/3: Get access and refresh tokens</h3>
{error ? ( {error ? (
<div> <div>
<p className="text-red-500 py-1 font-medium"> <p className="py-1 font-medium text-red-500">
<FontAwesomeIcon icon="exclamation-circle" className="mr-2" /> <FontAwesomeIcon icon="exclamation-circle" className="mr-2" />
<span>Whoops, looks like we got a problem: {error}.</span> <span>Whoops, looks like we got a problem: {error}.</span>
</p> </p>
<p className="my-2 font-mono border border-gray-400/20 rounded text-sm bg-gray-50 dark:bg-gray-800 p-2 opacity-80 whitespace-pre-line"> <p className="my-2 whitespace-pre-line rounded border border-gray-400/20 bg-gray-50 p-2 font-mono text-sm opacity-80 dark:bg-gray-800">
{description} {description}
</p> </p>
{errorUri && ( {errorUri && (
@@ -122,16 +122,16 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
href={errorUri} href={errorUri}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="hover:underline text-blue-600 dark:text-blue-500" className="text-blue-600 hover:underline dark:text-blue-500"
> >
Microsoft&apos;s official explanation Microsoft&apos;s official explanation
</a>{' '} </a>{' '}
on the error message. on the error message.
</p> </p>
)} )}
<div className="text-right mb-2 mt-6"> <div className="mb-2 mt-6 text-right">
<button <button
className="text-white bg-gradient-to-br from-red-500 to-orange-400 hover:bg-gradient-to-bl focus:ring-4 focus:ring-red-200 dark:focus:ring-red-800 font-medium rounded-lg text-sm px-4 py-2.5 text-center disabled:cursor-not-allowed disabled:grayscale" className="rounded-lg bg-gradient-to-br from-red-500 to-orange-400 px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 focus:ring-red-200 disabled:cursor-not-allowed disabled:grayscale dark:focus:ring-red-800"
onClick={() => { onClick={() => {
router.push('/onedrive-vercel-index-oauth/step-1') router.push('/onedrive-vercel-index-oauth/step-1')
}} }}
@@ -149,7 +149,7 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
<FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '} <FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '}
<span> <span>
Acquired access_token:{' '} Acquired access_token:{' '}
<code className="text-sm font-mono opacity-80">{`${accessToken.substring(0, 60)}...`}</code> <code className="font-mono text-sm opacity-80">{`${accessToken.substring(0, 60)}...`}</code>
</span> </span>
</li> </li>
)} )}
@@ -158,13 +158,13 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
<FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '} <FontAwesomeIcon icon={['far', 'check-circle']} className="text-green-500" />{' '}
<span> <span>
Acquired refresh_token:{' '} Acquired refresh_token:{' '}
<code className="text-sm font-mono opacity-80">{`${refreshToken.substring(0, 60)}...`}</code> <code className="font-mono text-sm opacity-80">{`${refreshToken.substring(0, 60)}...`}</code>
</span> </span>
</li> </li>
)} )}
</ol> </ol>
<p className="py-1 font-medium text-sm text-teal-500"> <p className="py-1 text-sm font-medium text-teal-500">
<FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> These tokens may take a few seconds to <FontAwesomeIcon icon="exclamation-circle" className="mr-1" /> These tokens may take a few seconds to
populate after you click the button below. If you go back home and still see the welcome page telling populate after you click the button below. If you go back home and still see the welcome page telling
you to re-authenticate, revisit home and do a hard refresh. you to re-authenticate, revisit home and do a hard refresh.
@@ -176,9 +176,9 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
and updates after your site goes live. and updates after your site goes live.
</p> </p>
<div className="text-right mb-2 mt-6"> <div className="mb-2 mt-6 text-right">
<button <button
className={`text-white bg-gradient-to-br hover:bg-gradient-to-bl focus:ring-4 font-medium rounded-lg text-sm px-4 py-2.5 text-center ${ className={`rounded-lg bg-gradient-to-br px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 ${
buttonError buttonError
? 'from-red-500 to-orange-400 focus:ring-red-200 dark:focus:ring-red-800' ? 'from-red-500 to-orange-400 focus:ring-red-200 dark:focus:ring-red-800'
: 'from-green-500 to-teal-300 focus:ring-green-200 dark:focus:ring-green-800' : 'from-green-500 to-teal-300 focus:ring-green-200 dark:focus:ring-green-800'
+29
View File
@@ -24,11 +24,14 @@ specifiers:
emoji-regex: ^10.0.0 emoji-regex: ^10.0.0
eslint: 8.8.0 eslint: 8.8.0
eslint-config-next: 12.0.10 eslint-config-next: 12.0.10
eslint-config-prettier: ^8.3.0
ioredis: ^4.28.2 ioredis: ^4.28.2
jszip: ^3.7.1 jszip: ^3.7.1
next: ^12.0.10 next: ^12.0.10
nextjs-progressbar: ^0.0.13 nextjs-progressbar: ^0.0.13
postcss: ^8.4.5 postcss: ^8.4.5
prettier: ^2.5.1
prettier-plugin-tailwindcss: ^0.1.4
preview-office-docs: ^1.0.2 preview-office-docs: ^1.0.2
prismjs: ^1.23.0 prismjs: ^1.23.0
react: ^17.0.2 react: ^17.0.2
@@ -102,7 +105,10 @@ devDependencies:
autoprefixer: 10.4.2_postcss@8.4.6 autoprefixer: 10.4.2_postcss@8.4.6
eslint: 8.8.0 eslint: 8.8.0
eslint-config-next: 12.0.10_9534215cc73b6f260bf33f1b86e3ae0e eslint-config-next: 12.0.10_9534215cc73b6f260bf33f1b86e3ae0e
eslint-config-prettier: 8.3.0_eslint@8.8.0
postcss: 8.4.6 postcss: 8.4.6
prettier: 2.5.1
prettier-plugin-tailwindcss: 0.1.4_prettier@2.5.1
tailwindcss: 3.0.18_833e1018ad0d7954aa80c53675939269 tailwindcss: 3.0.18_833e1018ad0d7954aa80c53675939269
typescript: 4.5.5 typescript: 4.5.5
@@ -1228,6 +1234,15 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-config-prettier/8.3.0_eslint@8.8.0:
resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.8.0
dev: true
/eslint-import-resolver-node/0.3.6: /eslint-import-resolver-node/0.3.6:
resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
dependencies: dependencies:
@@ -2875,6 +2890,20 @@ packages:
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
dev: true dev: true
/prettier-plugin-tailwindcss/0.1.4_prettier@2.5.1:
resolution: {integrity: sha512-kt3YFWqxcG9+bilBI0hPF7RjQZNtgBRvjJZGw6B2MNAjPqlfcYIiZnNaIEnq4XimKLTzZYxz6jQnUXmSQ/5njg==}
peerDependencies:
prettier: '>=2.2.0'
dependencies:
prettier: 2.5.1
dev: true
/prettier/2.5.1:
resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==}
engines: {node: '>=10.13.0'}
hasBin: true
dev: true
/preview-office-docs/1.0.2_react@17.0.2: /preview-office-docs/1.0.2_react@17.0.2:
resolution: {integrity: sha512-dVss4jWfVgZJcVskbOPV5ifpFokRYY1ZW54Z6DvwCg/HzNqq8rZw8yVM+nJAFmcFz6Zy7aY9n1/KhPDkm+Ky6Q==} resolution: {integrity: sha512-dVss4jWfVgZJcVskbOPV5ifpFokRYY1ZW54Z6DvwCg/HzNqq8rZw8yVM+nJAFmcFz6Zy7aY9n1/KhPDkm+Ky6Q==}
engines: {node: '>=10'} engines: {node: '>=10'}