feat: init
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
chuan
2025-11-11 01:56:44 +08:00
commit bba4bb40c8
4638 changed files with 447437 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
export * from "./product-updates";
export * from "./timezone-select";

View File

@@ -0,0 +1,66 @@
import { USER_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { getButtonStyling } from "@plane/propel/button";
import { PlaneLogo } from "@plane/propel/icons";
// helpers
import { cn } from "@plane/utils";
export const ProductUpdatesFooter = () => {
const { t } = useTranslation();
return (
<div className="flex items-center justify-between flex-shrink-0 gap-4 m-6 mb-4">
<div className="flex items-center gap-2">
<a
href="https://go.plane.so/p-docs"
target="_blank"
className="text-sm text-custom-text-200 hover:text-custom-text-100 hover:underline underline-offset-1 outline-none"
>
{t("docs")}
</a>
<svg viewBox="0 0 2 2" className="h-0.5 w-0.5 fill-current">
<circle cx={1} cy={1} r={1} />
</svg>
<a
data-ph-element={USER_TRACKER_ELEMENTS.CHANGELOG_REDIRECTED}
href="https://go.plane.so/p-changelog"
target="_blank"
className="text-sm text-custom-text-200 hover:text-custom-text-100 hover:underline underline-offset-1 outline-none"
>
{t("full_changelog")}
</a>
<svg viewBox="0 0 2 2" className="h-0.5 w-0.5 fill-current">
<circle cx={1} cy={1} r={1} />
</svg>
<a
href="mailto:support@plane.so"
target="_blank"
className="text-sm text-custom-text-200 hover:text-custom-text-100 hover:underline underline-offset-1 outline-none"
>
{t("support")}
</a>
<svg viewBox="0 0 2 2" className="h-0.5 w-0.5 fill-current">
<circle cx={1} cy={1} r={1} />
</svg>
<a
href="https://go.plane.so/p-discord"
target="_blank"
className="text-sm text-custom-text-200 hover:text-custom-text-100 hover:underline underline-offset-1 outline-none"
>
Discord
</a>
</div>
<a
href="https://plane.so/pages"
target="_blank"
className={cn(
getButtonStyling("accent-primary", "sm"),
"flex gap-1.5 items-center text-center font-medium hover:underline underline-offset-2 outline-none"
)}
>
<PlaneLogo className="h-4 w-auto text-custom-text-100" />
{t("powered_by_plane_pages")}
</a>
</div>
);
};

View File

@@ -0,0 +1,2 @@
export * from "./modal";
export * from "./footer";

View File

@@ -0,0 +1,60 @@
import type { FC } from "react";
import { useEffect } from "react";
import { observer } from "mobx-react";
import { USER_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
// components
import { ProductUpdatesFooter } from "@/components/global";
// helpers
import { captureView } from "@/helpers/event-tracker.helper";
// hooks
import { useInstance } from "@/hooks/store/use-instance";
// plane web components
import { ProductUpdatesHeader } from "@/plane-web/components/global";
export type ProductUpdatesModalProps = {
isOpen: boolean;
handleClose: () => void;
};
export const ProductUpdatesModal: FC<ProductUpdatesModalProps> = observer((props) => {
const { isOpen, handleClose } = props;
const { t } = useTranslation();
const { config } = useInstance();
useEffect(() => {
if (isOpen) {
captureView({ elementName: USER_TRACKER_ELEMENTS.PRODUCT_CHANGELOG_MODAL });
}
}, [isOpen]);
return (
<ModalCore isOpen={isOpen} handleClose={handleClose} position={EModalPosition.CENTER} width={EModalWidth.XXXXL}>
<ProductUpdatesHeader />
<div className="flex flex-col h-[60vh] vertical-scrollbar scrollbar-xs overflow-hidden overflow-y-scroll px-6 mx-0.5">
{config?.instance_changelog_url && config?.instance_changelog_url !== "" ? (
<iframe src={config?.instance_changelog_url} className="w-full h-full" />
) : (
<div className="flex flex-col items-center justify-center w-full h-full mb-8">
<div className="text-lg font-medium">{t("we_are_having_trouble_fetching_the_updates")}</div>
<div className="text-sm text-custom-text-200">
{t("please_visit")}
<a
data-ph-element={USER_TRACKER_ELEMENTS.CHANGELOG_REDIRECTED}
href="https://go.plane.so/p-changelog"
target="_blank"
className="text-sm text-custom-primary-100 font-medium hover:text-custom-primary-200 underline underline-offset-1 outline-none"
>
{t("our_changelogs")}
</a>{" "}
{t("for_the_latest_updates")}.
</div>
</div>
)}
</div>
<ProductUpdatesFooter />
</ModalCore>
);
});

View File

@@ -0,0 +1,53 @@
"use client";
import type { FC } from "react";
import { observer } from "mobx-react";
import { CustomSearchSelect } from "@plane/ui";
import { cn } from "@plane/utils";
// hooks
import useTimezone from "@/hooks/use-timezone";
type TTimezoneSelect = {
value: string | undefined;
onChange: (value: string) => void;
error?: boolean;
label?: string;
buttonClassName?: string;
className?: string;
optionsClassName?: string;
disabled?: boolean;
};
export const TimezoneSelect: FC<TTimezoneSelect> = observer((props) => {
// props
const {
value,
onChange,
error = false,
label = "Select a timezone",
buttonClassName = "",
className = "",
optionsClassName = "",
disabled = false,
} = props;
// hooks
const { disabled: isDisabled, timezones, selectedValue } = useTimezone();
return (
<div>
<CustomSearchSelect
value={value}
label={value && selectedValue ? selectedValue(value) : label}
options={isDisabled || disabled ? [] : timezones}
onChange={onChange}
buttonClassName={cn(buttonClassName, {
"border-red-500": error,
})}
className={cn("rounded-md border-[0.5px] !border-custom-border-200", className)}
optionsClassName={cn("w-72", optionsClassName)}
input
disabled={isDisabled || disabled}
/>
</div>
);
});