mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
about modal (#244)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
.about-modal {
|
||||
width: 445px;
|
||||
padding-bottom: 34px;
|
||||
|
||||
.modal-content {
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 24px;
|
||||
|
||||
.section-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 26px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.section {
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
&.logo-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
|
||||
.app-name {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.text-standard {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section:nth-child(3) {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 7px;
|
||||
|
||||
.wave-button-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import Logo from "@/app/asset/logo.svg";
|
||||
import { LinkButton } from "@/app/element/linkbutton";
|
||||
import { modalsModel } from "@/app/store/modalmodel";
|
||||
import { Modal } from "./modal";
|
||||
|
||||
import "./about.less";
|
||||
|
||||
interface AboutModalProps {}
|
||||
|
||||
const AboutModal = ({}: AboutModalProps) => {
|
||||
const currentDate = new Date();
|
||||
|
||||
return (
|
||||
<Modal className="about-modal" title="About" onClose={() => modalsModel.popModal()}>
|
||||
<div className="section-wrapper">
|
||||
<div className="section logo-section">
|
||||
<Logo />
|
||||
<div className="app-name">Wave Terminal</div>
|
||||
<div className="text-standard">
|
||||
Open-Source AI-Native Terminal
|
||||
<br />
|
||||
Built for Seamless Workflows
|
||||
</div>
|
||||
</div>
|
||||
<div className="section text-standard">Client Version 0.1.8 (20240615-002636)</div>
|
||||
<div className="section">
|
||||
<LinkButton
|
||||
className="secondary solid"
|
||||
href="https://github.com/wavetermdev/waveterm"
|
||||
target="_blank"
|
||||
leftIcon={<i className="fa-brands fa-github"></i>}
|
||||
>
|
||||
Github
|
||||
</LinkButton>
|
||||
<LinkButton
|
||||
className="secondary solid"
|
||||
href="https://www.waveterm.dev/"
|
||||
target="_blank"
|
||||
leftIcon={<i className="fa-sharp fa-light fa-globe"></i>}
|
||||
>
|
||||
Website
|
||||
</LinkButton>
|
||||
<LinkButton
|
||||
className="secondary solid"
|
||||
href="https://github.com/wavetermdev/waveterm/blob/main/acknowledgements/README.md"
|
||||
target="_blank"
|
||||
rel={"noopener"}
|
||||
leftIcon={<i className="fa-sharp fa-light fa-heart"></i>}
|
||||
>
|
||||
Acknowledgements
|
||||
</LinkButton>
|
||||
</div>
|
||||
<div className="section text-standard">© {currentDate.getFullYear()} Command Line Inc.</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
AboutModal.displayName = "AboutModal";
|
||||
|
||||
export { AboutModal };
|
||||
@@ -24,51 +24,61 @@
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: relative;
|
||||
z-index: var(--zindex-modal);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
border-radius: 10px;
|
||||
gap: 32px;
|
||||
padding: 24px 16px 16px;
|
||||
border-radius: 8px;
|
||||
border: 0.5px solid var(--modal-border-color);
|
||||
background: var(--modal-bg-color);
|
||||
border: 1px solid var(--border-color);
|
||||
box-shadow: 0px 5px 5px 5px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25);
|
||||
|
||||
.modal-header {
|
||||
width: 100%;
|
||||
.header-content-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 14px 12px 20px;
|
||||
justify-content: space-between;
|
||||
line-height: 20px;
|
||||
border-bottom: 1px solid var(--modal-header-bottom-border-color);
|
||||
user-select: none;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.modal-title {
|
||||
color: var(--main-text-color);
|
||||
font-size: var(--title-font-size);
|
||||
}
|
||||
.modal-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
|
||||
button {
|
||||
padding-right: 4px !important;
|
||||
i {
|
||||
font-size: 18px;
|
||||
.modal-title {
|
||||
color: var(--main-text-color);
|
||||
font-size: var(--title-font-size);
|
||||
}
|
||||
|
||||
button {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
padding: 8px 16px;
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
width: 100%;
|
||||
padding: 0px 20px;
|
||||
.modal-content {
|
||||
width: 100%;
|
||||
padding: 0px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
padding: 0 20px 20px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
button:last-child {
|
||||
.button:last-child {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Button } from "@/app/element/button";
|
||||
import clsx from "clsx";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import "./modal.less";
|
||||
|
||||
interface ModalHeaderProps {
|
||||
title: React.ReactNode;
|
||||
description?: string;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const ModalHeader = ({ onClose, title, description }: ModalHeaderProps) => (
|
||||
const ModalHeader = ({ onClose, description }: ModalHeaderProps) => (
|
||||
<header className="modal-header">
|
||||
{typeof title === "string" ? <h3 className="modal-title">{title}</h3> : title}
|
||||
{description && <p>{description}</p>}
|
||||
{onClose && (
|
||||
<Button className="secondary ghost" onClick={onClose} title="Close (ESC)">
|
||||
@@ -39,20 +38,22 @@ interface ModalFooterProps {
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
const ModalFooter = ({ onCancel, onOk, cancelLabel = "Cancel", okLabel = "Ok" }: ModalFooterProps) => (
|
||||
<footer className="modal-footer">
|
||||
{onCancel && (
|
||||
<Button className="secondary" onClick={onCancel}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
)}
|
||||
{onOk && (
|
||||
<Button className="primary" onClick={onOk}>
|
||||
{okLabel}
|
||||
</Button>
|
||||
)}
|
||||
</footer>
|
||||
);
|
||||
const ModalFooter = ({ onCancel, onOk, cancelLabel = "Cancel", okLabel = "Ok" }: ModalFooterProps) => {
|
||||
return (
|
||||
<footer className="modal-footer">
|
||||
{onCancel && (
|
||||
<Button className="secondary ghost" onClick={onCancel}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
)}
|
||||
{onOk && (
|
||||
<Button className="primary" onClick={onOk}>
|
||||
{okLabel}
|
||||
</Button>
|
||||
)}
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
interface ModalProps {
|
||||
title: string;
|
||||
@@ -81,13 +82,21 @@ const Modal = ({
|
||||
}: ModalProps) => {
|
||||
const renderBackdrop = (onClick) => <div className="modal-backdrop" onClick={onClick}></div>;
|
||||
|
||||
const renderFooter = () => {
|
||||
return onOk || onCancel;
|
||||
};
|
||||
|
||||
const renderModal = () => (
|
||||
<div className="modal-wrapper">
|
||||
{renderBackdrop(onClickBackdrop)}
|
||||
<div className={`modal ${className}`}>
|
||||
<ModalHeader title={title} onClose={onClose} description={description} />
|
||||
<ModalContent>{children}</ModalContent>
|
||||
<ModalFooter onCancel={onCancel} onOk={onOk} cancelLabel={cancelLabel} okLabel={okLabel} />
|
||||
<div className={clsx(`modal`, className)}>
|
||||
<div className="header-content-wrapper">
|
||||
<ModalHeader onClose={onClose} description={description} />
|
||||
<ModalContent>{children}</ModalContent>
|
||||
</div>
|
||||
{renderFooter() && (
|
||||
<ModalFooter onCancel={onCancel} onOk={onOk} cancelLabel={cancelLabel} okLabel={okLabel} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { AboutModal } from "./about";
|
||||
import { TosModal } from "./tos";
|
||||
import { UserInputModal } from "./userinputmodal";
|
||||
|
||||
const modalRegistry: { [key: string]: React.ComponentType<any> } = {
|
||||
[TosModal.displayName || "TosModal"]: TosModal,
|
||||
[UserInputModal.displayName || "UserInputModal"]: UserInputModal,
|
||||
[AboutModal.displayName || "AboutModal"]: AboutModal,
|
||||
};
|
||||
|
||||
export const getModalComponent = (key: string): React.ComponentType<any> | undefined => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.tos-modal {
|
||||
width: 640px;
|
||||
border-radius: 10px;
|
||||
|
||||
.modal-inner {
|
||||
padding: 40px 76px;
|
||||
@@ -16,6 +17,8 @@
|
||||
|
||||
.logo {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
|
||||
Reference in New Issue
Block a user