New Directory Setup (#2065)

* chore: moved app & space from apps to root

* chore: modified workspace configuration

* chore: modified dockerfiles for space and web

* chore: modified icons for space

* feat: updated files for new svg icons supported by next-images

* chore: added /spaces base path for next

* chore: added compose config for space

* chore: updated husky configuration

* chore: updated workflows for new configuration

* chore: changed app name to web

* fix: resolved build errors with web

* chore: reset file tracing root for both projects

* chore: added nginx config for deploy

* fix: eslint and tsconfig settings for space app

* husky setup fixes based on new dir

* eslint fixes

* prettier formatting

---------

Co-authored-by: Henit Chobisa <chobisa.henit@gmail.com>
This commit is contained in:
sriram veeraghanta 2023-09-03 18:50:30 +05:30 committed by GitHub
parent 20e36194b4
commit 1e152c666c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1022 changed files with 1475 additions and 1240 deletions

View file

@ -0,0 +1,129 @@
import React from "react";
// react-form
import {
FieldError,
FieldErrorsImpl,
Merge,
UseFormRegister,
UseFormSetValue,
UseFormWatch,
} from "react-hook-form";
// react-color
import { ColorResult, SketchPicker } from "react-color";
// component
import { Popover, Transition } from "@headlessui/react";
import { Input } from "components/ui";
// icons
import { ColorPickerIcon } from "components/icons";
// types
import { ICustomTheme } from "types";
type Props = {
name: keyof ICustomTheme;
position?: "left" | "right";
watch: UseFormWatch<any>;
setValue: UseFormSetValue<any>;
error: FieldError | Merge<FieldError, FieldErrorsImpl<any>> | undefined;
register: UseFormRegister<any>;
};
export const ColorPickerInput: React.FC<Props> = ({
name,
position = "left",
watch,
setValue,
error,
register,
}) => {
const handleColorChange = (newColor: ColorResult) => {
const { hex } = newColor;
setValue(name, hex);
};
const getColorText = (colorName: keyof ICustomTheme) => {
switch (colorName) {
case "background":
return "Background";
case "text":
return "Text";
case "primary":
return "Primary(Theme)";
case "sidebarBackground":
return "Sidebar Background";
case "sidebarText":
return "Sidebar Text";
default:
return "Color";
}
};
return (
<div className="relative">
<Input
id={name}
name={name}
type="name"
placeholder="#FFFFFF"
autoComplete="off"
error={error}
value={watch(name)}
register={register}
validations={{
required: `${getColorText(name)} color is required`,
pattern: {
value: /^#(?:[0-9a-fA-F]{3}){1,2}$/g,
message: `${getColorText(name)} color should be hex format`,
},
}}
/>
<div className="absolute right-4 top-2.5">
<Popover className="relative grid place-items-center">
{({ open }) => (
<>
<Popover.Button
type="button"
className={`group inline-flex items-center outline-none ${
open ? "text-custom-text-100" : "text-custom-text-200"
}`}
>
{watch(name) && watch(name) !== "" ? (
<span
className="h-4 w-4 rounded border border-custom-border-200"
style={{
backgroundColor: `${watch(name)}`,
}}
/>
) : (
<ColorPickerIcon
height={14}
width={14}
className="fill-current text-custom-text-100"
/>
)}
</Popover.Button>
<Transition
as={React.Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel
className={`absolute bottom-8 z-20 mt-1 max-w-xs px-2 sm:px-0 ${
position === "right" ? "left-0" : "right-0"
}`}
>
<SketchPicker color={watch(name)} onChange={handleColorChange} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</div>
</div>
);
};

View file

@ -0,0 +1,154 @@
import React, { useEffect, useState } from "react";
import { useTheme } from "next-themes";
import { useForm } from "react-hook-form";
// ui
import { PrimaryButton } from "components/ui";
import { ColorPickerInput } from "components/core";
// types
import { ICustomTheme } from "types";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
type Props = {
preLoadedData?: Partial<ICustomTheme> | null;
};
const defaultValues: ICustomTheme = {
background: "#0d101b",
text: "#c5c5c5",
primary: "#3f76ff",
sidebarBackground: "#0d101b",
sidebarText: "#c5c5c5",
darkPalette: false,
palette: "",
theme: "custom",
};
export const CustomThemeSelector: React.FC<Props> = observer(({ preLoadedData }) => {
const store: any = useMobxStore();
const { setTheme } = useTheme();
const [darkPalette, setDarkPalette] = useState(false);
const {
register,
formState: { errors, isSubmitting },
handleSubmit,
watch,
setValue,
reset,
} = useForm<ICustomTheme>({
defaultValues,
});
useEffect(() => {
reset({
...defaultValues,
...preLoadedData,
});
}, [preLoadedData, reset]);
const handleUpdateTheme = async (formData: any) => {
const payload: ICustomTheme = {
background: formData.background,
text: formData.text,
primary: formData.primary,
sidebarBackground: formData.sidebarBackground,
sidebarText: formData.sidebarText,
darkPalette: darkPalette,
palette: `${formData.background},${formData.text},${formData.primary},${formData.sidebarBackground},${formData.sidebarText}`,
theme: "custom",
};
setTheme("custom");
return store.user
.updateCurrentUserSettings({ theme: payload })
.then((response: any) => response)
.catch((error: any) => error);
};
return (
<form onSubmit={handleSubmit(handleUpdateTheme)}>
<div className="space-y-5">
<h3 className="text-lg font-semibold text-custom-text-100">Customize your theme</h3>
<div className="space-y-4">
<div className="grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2 md:grid-cols-3">
<div className="flex flex-col items-start gap-2">
<h3 className="text-left text-sm font-medium text-custom-text-200">
Background color
</h3>
<ColorPickerInput
name="background"
position="right"
error={errors.background}
watch={watch}
setValue={setValue}
register={register}
/>
</div>
<div className="flex flex-col items-start gap-2">
<h3 className="text-left text-sm font-medium text-custom-text-200">Text color</h3>
<ColorPickerInput
name="text"
error={errors.text}
watch={watch}
setValue={setValue}
register={register}
/>
</div>
<div className="flex flex-col items-start gap-2">
<h3 className="text-left text-sm font-medium text-custom-text-200">
Primary(Theme) color
</h3>
<ColorPickerInput
name="primary"
error={errors.primary}
watch={watch}
setValue={setValue}
register={register}
/>
</div>
<div className="flex flex-col items-start gap-2">
<h3 className="text-left text-sm font-medium text-custom-text-200">
Sidebar background color
</h3>
<ColorPickerInput
name="sidebarBackground"
position="right"
error={errors.sidebarBackground}
watch={watch}
setValue={setValue}
register={register}
/>
</div>
<div className="flex flex-col items-start gap-2">
<h3 className="text-left text-sm font-medium text-custom-text-200">
Sidebar text color
</h3>
<ColorPickerInput
name="sidebarText"
error={errors.sidebarText}
watch={watch}
setValue={setValue}
register={register}
/>
</div>
</div>
</div>
</div>
<div className="mt-5 flex justify-end gap-2">
<PrimaryButton type="submit" loading={isSubmitting}>
{isSubmitting ? "Creating Theme..." : "Set Theme"}
</PrimaryButton>
</div>
</form>
);
});

View file

@ -0,0 +1,3 @@
export * from "./color-picker-input";
export * from "./custom-theme-selector";
export * from "./theme-switch";

View file

@ -0,0 +1,135 @@
// next-themes
import { useTheme } from "next-themes";
// hooks
import useUser from "hooks/use-user";
// constants
import { THEMES_OBJ } from "constants/themes";
// ui
import { CustomSelect } from "components/ui";
// types
import { ICustomTheme } from "types";
import { unsetCustomCssVariables } from "helpers/theme.helper";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
type Props = {
setPreLoadedData: React.Dispatch<React.SetStateAction<ICustomTheme | null>>;
customThemeSelectorOptions: boolean;
setCustomThemeSelectorOptions: React.Dispatch<React.SetStateAction<boolean>>;
};
export const ThemeSwitch: React.FC<Props> = observer(
({ setPreLoadedData, customThemeSelectorOptions, setCustomThemeSelectorOptions }) => {
const store: any = useMobxStore();
const { user, mutateUser } = useUser();
const { theme, setTheme } = useTheme();
const updateUserTheme = (newTheme: string) => {
if (!user) return;
setTheme(newTheme);
return store.user
.updateCurrentUserSettings({ theme: { ...user.theme, theme: newTheme } })
.then((response: any) => response)
.catch((error: any) => error);
};
const currentThemeObj = THEMES_OBJ.find((t) => t.value === theme);
return (
<CustomSelect
value={theme}
label={
currentThemeObj ? (
<div className="flex items-center gap-2">
<div
className="border-1 relative flex h-4 w-4 rotate-45 transform items-center justify-center rounded-full border"
style={{
borderColor: currentThemeObj.icon.border,
}}
>
<div
className="h-full w-1/2 rounded-l-full"
style={{
background: currentThemeObj.icon.color1,
}}
/>
<div
className="h-full w-1/2 rounded-r-full border-l"
style={{
borderLeftColor: currentThemeObj.icon.border,
background: currentThemeObj.icon.color2,
}}
/>
</div>
{currentThemeObj.label}
</div>
) : (
"Select your theme"
)
}
onChange={({ value, type }: { value: string; type: string }) => {
if (value === "custom") {
if (user?.theme.palette) {
setPreLoadedData({
background: user.theme.background !== "" ? user.theme.background : "#0d101b",
text: user.theme.text !== "" ? user.theme.text : "#c5c5c5",
primary: user.theme.primary !== "" ? user.theme.primary : "#3f76ff",
sidebarBackground:
user.theme.sidebarBackground !== "" ? user.theme.sidebarBackground : "#0d101b",
sidebarText: user.theme.sidebarText !== "" ? user.theme.sidebarText : "#c5c5c5",
darkPalette: false,
palette:
user.theme.palette !== ",,,,"
? user.theme.palette
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
theme: "custom",
});
}
if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true);
} else {
if (customThemeSelectorOptions) setCustomThemeSelectorOptions(false);
unsetCustomCssVariables();
}
updateUserTheme(value);
document.documentElement.style.setProperty("--color-scheme", type);
}}
input
width="w-full"
position="right"
>
{THEMES_OBJ.map(({ value, label, type, icon }) => (
<CustomSelect.Option key={value} value={{ value, type }}>
<div className="flex items-center gap-2">
<div
className="border-1 relative flex h-4 w-4 rotate-45 transform items-center justify-center rounded-full border"
style={{
borderColor: icon.border,
}}
>
<div
className="h-full w-1/2 rounded-l-full"
style={{
background: icon.color1,
}}
/>
<div
className="h-full w-1/2 rounded-r-full border-l"
style={{
borderLeftColor: icon.border,
background: icon.color2,
}}
/>
</div>
{label}
</div>
</CustomSelect.Option>
))}
</CustomSelect>
);
}
);