Skip to content

Commit

Permalink
[dashboard] Implement dark theme
Browse files Browse the repository at this point in the history
Co-authored-by: George Tsiolis <[email protected]>
  • Loading branch information
jankeromnes and gtsiolis committed Apr 16, 2021
1 parent 83d8c0a commit ce05f58
Show file tree
Hide file tree
Showing 38 changed files with 815 additions and 206 deletions.
2 changes: 1 addition & 1 deletion components/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function App() {
return <div className="mt-48 text-center">
<img src={gitpodIcon} className="h-16 mx-auto"/>
<h1 className="mt-12 text-gray-500 text-3xl">Your account has been blocked.</h1>
<p className="mt-4 mb-8 text-lg w-96 mx-auto">Please contact support if you think this is an error. See also <a className="hover:text-blue-600" href="https://www.gitpod.io/terms/">terms of service</a>.</p>
<p className="mt-4 mb-8 text-lg w-96 mx-auto">Please contact support if you think this is an error. See also <a className="hover:text-blue-600 dark:hover:text-blue-400" href="https://www.gitpod.io/terms/">terms of service</a>.</p>
<a className="mx-auto" href="mailto:[email protected]?Subject=Blocked"><button className="secondary">Contact Support</button></a>
</div>;
}
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/FromReferrer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function FromReferrer() {
return <div className="lg:px-28 px-10 flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between space-x-2 text-gray-400 h-96">
<div className="flex flex-col items-center w-96 m-auto mt-40">
<h3 className="text-center pb-3 text-gray-500">No Referrer Found</h3>
<h3 className="text-center pb-3 text-gray-500 dark:text-gray-400">No Referrer Found</h3>
<div className="text-center pb-6 text-gray-500">
<p>It looks like you are trying to open a workspace, but the referrer URL is empty. This happens when the git hoster doesn't send the referrer header.
<br/> Please prefix the repository URL with <pre>https://gitpod.io/#</pre> in order to start a workspace. <a className="text-gray-400 underline underline-thickness-thin underline-offset-small hover:text-gray-600" href="https://www.gitpod.io/docs/getting-started/">Learn more</a></p>
Expand Down
8 changes: 5 additions & 3 deletions components/dashboard/src/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { UserContext } from "./user-context";
import { getGitpodService } from "./service/service";
import { iconForAuthProvider, openAuthorizeWindow, simplifyProviderName } from "./provider-utils";
import gitpod from './images/gitpod.svg';
import gitpodDark from './images/gitpod-dark.svg';
import gitpodIcon from './icons/gitpod.svg';
import automate from "./images/welcome/automate.svg";
import code from "./images/welcome/code.svg";
Expand Down Expand Up @@ -87,11 +88,12 @@ export function Login() {
}

return (<div id="login-container" className="z-50 flex w-screen h-screen">
{showWelcome ? <div id="feature-section" className="flex-grow bg-gray-100 w-1/2 hidden lg:block">
{showWelcome ? <div id="feature-section" className="flex-grow bg-gray-100 dark:bg-gray-800 w-1/2 hidden lg:block">
<div id="feature-section-column" className="flex max-w-xl h-full mx-auto pt-6">
<div className="flex flex-col px-8 my-auto ml-auto">
<div className="mb-12">
<img src={gitpod} className="h-8" />
<img src={gitpod} className="h-8 block dark:hidden"/>
<img src={gitpodDark} className="h-8 hidden dark:block"/>
</div>
<div className="mb-10">
<h1 className="text-5xl mb-3">Welcome to Gitpod</h1>
Expand Down Expand Up @@ -127,7 +129,7 @@ export function Login() {
{authProviders.map(ap => {
return (
<button key={"button" + ap.host} className="btn-login flex-none w-56 h-10 p-0 inline-flex" onClick={() => openLogin(ap.host)}>
<img className="fill-current filter-grayscale w-5 h-5 ml-3 mr-3 my-auto" src={iconForAuthProvider(ap.authProviderType)} />
{iconForAuthProvider(ap.authProviderType)}
<span className="pt-2 pb-2 mr-3 text-sm my-auto font-medium truncate overflow-ellipsis">Continue with {simplifyProviderName(ap.host)}</span>
</button>
);
Expand Down
4 changes: 2 additions & 2 deletions components/dashboard/src/WhatsNew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ export function WhatsNew(props: { visible: boolean, onClose: () => void }) {
}
return <Modal visible={props.visible} onClose={internalClose}>
<h3 className="pb-4">What's New 🎁</h3>
<div className="border-t border-gray-200 -mx-6 px-6 py-4">
<div className="border-t border-gray-200 dark:border-gray-800 -mx-6 px-6 py-4">
<p className="pb-2 text-gray-900 text-base font-medium">New Dashboard</p>
<p className="pb-2 text-gray-500 text-sm">We have made some layout changes on the dashboard to improve the overall user experience of Gitpod.</p>
</div>
<div className="border-t border-b border-gray-200 -mx-6 px-6 py-4">
<div className="border-t border-b border-gray-200 dark:border-gray-800 -mx-6 px-6 py-4">
<p className="pb-2 text-gray-900 text-base font-medium">VS Code</p>
<p className="pb-4 text-gray-500 text-sm">We are changing the default IDE to VS Code.</p>
<ol className="pb-2 text-gray-500 text-sm list-outside list-decimal space-y-2">
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/admin/UserDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export function Property(p: { name: string, children: string | ReactChild, actio
{p.children}
</div>
{(p.actions || []).map(a =>
<div className="cursor-pointer text-sm text-blue-400 hover:text-blue-500 truncate" onClick={a.onClick}>
<div className="cursor-pointer text-sm text-blue-400 dark:text-blue-600 hover:text-blue-600 dark:hover:text-blue-400 truncate" onClick={a.onClick}>
{a.label || ''}
</div>
)}
Expand Down
12 changes: 6 additions & 6 deletions components/dashboard/src/admin/UserSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ export default function UserSearch() {
<path fillRule="evenodd" clipRule="evenodd" d="M6 2a4 4 0 100 8 4 4 0 000-8zM0 6a6 6 0 1110.89 3.477l4.817 4.816a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 010 6z" fill="#A8A29E" />
</svg>
</div>
<input className="border-0" type="text" placeholder="Search Users" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
<input type="search" placeholder="Search Users" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
</div>
<button className="" disabled={searching} onClick={search}>Search</button>
<button disabled={searching} onClick={search}>Search</button>
</div>
</div>
<div className="flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between space-x-2 text-sm text-gray-400 border-t border-b border-gray-200 mb-2">
<div className="px-6 py-3 flex justify-between space-x-2 text-sm text-gray-400 border-t border-b border-gray-200 dark:border-gray-800 mb-2">
<div className="w-1/12"></div>
<div className="w-6/12">Name</div>
<div className="w-5/12">Created</div>
Expand All @@ -99,13 +99,13 @@ function UserEntry(p: { user: User }) {
log.error(e);
}
return <Link key={p.user.id} to={'/admin/users/' + p.user.id}>
<div className="rounded-xl whitespace-nowrap flex space-x-2 py-6 px-6 w-full justify-between hover:bg-gray-100 focus:bg-gitpod-kumquat-light group">
<div className="rounded-xl whitespace-nowrap flex space-x-2 py-6 px-6 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light group">
<div className="pr-3 self-center w-1/12">
<img className="rounded-full" src={p.user.avatarUrl} alt={p.user.fullName || p.user.name}/>
</div>
<div className="flex flex-col w-6/12">
<div className="font-medium text-gray-800 truncate hover:text-blue-600">{p.user.fullName}</div>
<div className="text-sm overflow-ellipsis truncate text-gray-400 hover:text-blue-600">{email}</div>
<div className="font-medium text-gray-800 dark:text-gray-100 truncate hover:text-blue-600 dark:hover:text-blue-400">{p.user.fullName}</div>
<div className="text-sm overflow-ellipsis truncate text-gray-400 hover:text-blue-600 dark:hover:text-blue-400">{email}</div>
</div>
<div className="flex w-5/12 self-center">
<div className="text-sm w-full text-gray-400 truncate">{moment(p.user.creationDate).fromNow()}</div>
Expand Down
6 changes: 3 additions & 3 deletions components/dashboard/src/admin/WorkspaceDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default function WorkspaceDetail(props: { workspace: WorkspaceAndInstance
}
}
const adminLinks = getAdminLinks(workspace);
const adminLink = (i: number) => <Property key={'admin-'+i} name={adminLinks[i]?.name || ''}><a className="text-blue-400 hover:text-blue-600" href={adminLinks[i]?.url}>{adminLinks[i]?.title || ''}</a></Property>;
const adminLink = (i: number) => <Property key={'admin-'+i} name={adminLinks[i]?.name || ''}><a className="text-blue-400 dark:text-blue-600 hover:text-blue-600 dark:hover:text-blue-400" href={adminLinks[i]?.url}>{adminLinks[i]?.title || ''}</a></Property>;
return <>
<div className="flex">
<div className="flex-1">
Expand All @@ -57,10 +57,10 @@ export default function WorkspaceDetail(props: { workspace: WorkspaceAndInstance
<div className="flex w-full mt-6">
<Property name="Created">{moment(workspace.workspaceCreationTime).format('MMM D, YYYY')}</Property>
<Property name="Last Start">{moment(workspace.instanceCreationTime).fromNow()}</Property>
<Property name="Context"><a className="text-blue-400 hover:text-blue-600" href={workspace.contextURL}>{workspace.context.title}</a></Property>
<Property name="Context"><a className="text-blue-400 dark:text-blue-600 hover:text-blue-600 dark:hover:text-blue-400" href={workspace.contextURL}>{workspace.context.title}</a></Property>
</div>
<div className="flex w-full mt-6">
<Property name="User"><Link className="text-blue-400 hover:text-blue-600" to={"/admin/users/" + props.workspace.ownerId}>{user?.name || props.workspace.ownerId}</Link></Property>
<Property name="User"><Link className="text-blue-400 dark:text-blue-600 hover:text-blue-600 dark:hover:text-blue-400" to={"/admin/users/" + props.workspace.ownerId}>{user?.name || props.workspace.ownerId}</Link></Property>
<Property name="Sharing">{workspace.shareable ? 'Enabled' : 'Disabled'}</Property>
<Property name=""><div></div></Property>
</div>
Expand Down
10 changes: 5 additions & 5 deletions components/dashboard/src/admin/WorkspacesSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ export function WorkspaceSearch(props: Props) {
<path fillRule="evenodd" clipRule="evenodd" d="M6 2a4 4 0 100 8 4 4 0 000-8zM0 6a6 6 0 1110.89 3.477l4.817 4.816a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 010 6z" fill="#A8A29E" />
</svg>
</div>
<input className="border-0" type="text" placeholder="Search context URLs" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
<input type="search" placeholder="Search context URLs" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
</div>
<button className="" disabled={searching} onClick={search}>Search</button>
<button disabled={searching} onClick={search}>Search</button>
</div>
</div>
<div className="flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between text-sm text-gray-400 border-t border-b border-gray-200 mb-2">
<div className="px-6 py-3 flex justify-between text-sm text-gray-400 border-t border-b border-gray-200 dark:border-gray-800 mb-2">
<div className="w-8"></div>
<div className="w-5/12">Name</div>
<div className="w-5/12">Context</div>
Expand All @@ -108,12 +108,12 @@ export function WorkspaceSearch(props: Props) {

function WorkspaceEntry(p: { ws: WorkspaceAndInstance }) {
return <Link key={'ws-' + p.ws.workspaceId} to={'/admin/workspaces/' + p.ws.workspaceId}>
<div className="rounded-xl whitespace-nowrap flex py-6 px-6 w-full justify-between hover:bg-gray-100 focus:bg-gitpod-kumquat-light group">
<div className="rounded-xl whitespace-nowrap flex py-6 px-6 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light group">
<div className="pr-3 self-center w-8">
<WorkspaceStatusIndicator instance={WorkspaceAndInstance.toInstance(p.ws)}/>
</div>
<div className="flex flex-col w-5/12 truncate">
<div className="font-medium text-gray-800 truncate hover:text-blue-600 truncate">{p.ws.workspaceId}</div>
<div className="font-medium text-gray-800 dark:text-gray-100 truncate hover:text-blue-600 dark:hover:text-blue-400 truncate">{p.ws.workspaceId}</div>
<div className="text-sm overflow-ellipsis truncate text-gray-400 truncate">{getProject(WorkspaceAndInstance.toWorkspace(p.ws))}</div>
</div>
<div className="flex flex-col w-5/12 self-center truncate">
Expand Down
4 changes: 2 additions & 2 deletions components/dashboard/src/components/CheckBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ function CheckBox(props: {
const checkboxId = `checkbox-${props.title}-${String(Math.random())}`;

return <div className="flex mt-4">
<input className={"h-4 w-4 focus:ring-0 mt-1 rounded cursor-pointer border border-gray-300 focus:border-gray-400 " + (props.checked ? 'bg-gray-800' : '')} type="checkbox"
<input className={"h-4 w-4 focus:ring-0 mt-1 rounded cursor-pointer bg-transparent border-2 dark:filter-invert border-gray-800 dark:border-gray-900 focus:border-gray-900 dark:focus:border-gray-800 " + (props.checked ? 'bg-gray-800 dark:bg-gray-900' : '')} type="checkbox"
id={checkboxId}
{...inputProps}
/>
<div className="flex flex-col ml-2">
<label htmlFor={checkboxId} className="text-gray-800 text-md font-semibold tracking-wide">{props.title}</label>
<label htmlFor={checkboxId} className="text-gray-800 dark:text-gray-100 text-md font-semibold tracking-wide">{props.title}</label>
<div className="text-gray-400 text-md">{props.desc}</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions components/dashboard/src/components/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function ContextMenu(props: ContextMenuProps) {
}, []); // Empty array ensures that effect is only run on mount and unmount


const font = "text-gray-600 hover:text-gray-800"
const font = "text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-100"

const menuId = String(Math.random());

Expand All @@ -66,10 +66,10 @@ function ContextMenu(props: ContextMenuProps) {
{props.children}
</div>
{expanded ?
<div className={`mt-2 z-50 ${props.width || 'w-48'} bg-white absolute right-0 flex flex-col border border-gray-200 rounded-lg truncated`}>
<div className={`mt-2 z-50 ${props.width || 'w-48'} bg-white dark:bg-gray-900 absolute right-0 flex flex-col border border-gray-200 dark:border-gray-800 rounded-lg truncated`}>
{props.menuEntries.map((e, index) => {
const clickable = e.href || e.onClick || e.link;
const entry = <div className={`px-4 flex py-3 ${clickable ? 'hover:bg-gray-200' : ''} text-sm leading-1 ${e.customFontStyle || font} ${e.separator ? ' border-b border-gray-200' : ''}`} >
const entry = <div className={`px-4 flex py-3 ${clickable ? 'hover:bg-gray-200 dark:hover:bg-gray-800' : ''} text-sm leading-1 ${e.customFontStyle || font} ${e.separator ? ' border-b border-gray-200 dark:border-gray-800' : ''}`} >
<div className="truncate w-52">{e.title}</div><div className="flex-1"></div>{e.active ? <div className="pl-1 font-semibold">&#x2713;</div> : null}
</div>
const key = `entry-${menuId}-${index}-${e.title}`;
Expand Down
4 changes: 2 additions & 2 deletions components/dashboard/src/components/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface DropDownProps {
}

function Arrow(props: {up: boolean}) {
return <span className="mx-2 border-gray-400 group-hover:border-gray-600" style={{ margin: 2, padding: 3, border: 'solid black', borderWidth: '0 2px 2px 0', display: 'inline-block', transform: `rotate(${props.up ? '-135deg' : '45deg'})`}}></span>
return <span className="mx-2 border-gray-400 dark:border-gray-600 group-hover:border-gray-600 dark:group-hover:border-gray-400" style={{ margin: 2, padding: 3, border: 'solid black', borderWidth: '0 2px 2px 0', display: 'inline-block', transform: `rotate(${props.up ? '-135deg' : '45deg'})`}}></span>
}

function DropDown(props: DropDownProps) {
Expand All @@ -36,7 +36,7 @@ function DropDown(props: DropDownProps) {
}
}
})
const font = "text-gray-400 text-sm leading-1 group hover:text-gray-600 transition ease-in-out"
const font = "text-gray-400 dark:text-gray-500 text-sm leading-1 group hover:text-gray-600 dark:hover:text-gray-400 transition ease-in-out"
return (
<ContextMenu menuEntries={enhancedEntries} width={props.contextMenuWidth}>
<span className={`py-2 cursor-pointer ${font}`}>{props.prefix}{current}<Arrow up={false}/></span>
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface HeaderProps {
}

export default function Header(p: HeaderProps) {
return <div className="lg:px-28 px-10 border-gray-200">
return <div className="lg:px-28 px-10 border-gray-200 dark:border-gray-800">
<div className="flex pb-8 pt-6">
<div className="">
<h1 className="tracking-tight">{p.title}</h1>
Expand Down
8 changes: 4 additions & 4 deletions components/dashboard/src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ interface Entry {

function MenuItem(entry: Entry) {
const location = useLocation();
let classes = "flex block text-sm font-medium px-3 px-0 py-1.5 rounded-md transition ease-in-out";
let classes = "flex block text-sm font-medium dark:text-gray-200 px-3 px-0 py-1.5 rounded-md transition ease-in-out";
const all = [entry.link, ...(entry.alternatives||[])];
const path = location.pathname.toLowerCase();
if (all.find( n => n === path || n+'/' === path)) {
classes += " bg-gray-200";
classes += " bg-gray-200 dark:bg-gray-700";
} else {
classes += " text-gray-600 hover:bg-gray-100 transition ease-in-out";
classes += " text-gray-600 hover:bg-gray-100 dark:hover:bg-gray-800";
}
return <li key={entry.title}>
{entry.link.startsWith('https://')
Expand Down Expand Up @@ -57,7 +57,7 @@ function Menu(props: { left: Entry[], right: Entry[] }) {
{props.right.map(MenuItem)}
</ul>
</nav>
<div className="ml-3 flex items-center justify-start mb-0 pointer-cursor m-l-auto rounded-full border-2 border-white hover:border-gray-200 p-0.5 font-medium">
<div className="ml-3 flex items-center justify-start mb-0 pointer-cursor m-l-auto rounded-full border-2 border-transparent hover:border-gray-200 dark:hover:border-gray-700 p-0.5 font-medium">
<ContextMenu menuEntries={[
{
title: (user && User.getPrimaryEmail(user)) || '',
Expand Down
Loading

0 comments on commit ce05f58

Please sign in to comment.