import * as React from "react"; import { useEffect, useState } from "react"; import MatchSizes from "./MatchSizes"; import MatchProperties from "./MatchProperties"; import RoundImage from "./RoundImage"; import SwapPositions from "./SwapPositions"; import InsertTitles from "./InsertTitles"; import ConfidentialButtons from "./ConfidentialButtons"; import DraftButtons from "./DraftButtons"; import ProgressBarButtons from "./ProgressBarButtons"; import AlignmentButtons from "./AlignmentButtons"; import GridGuidelineManager from "./GridGuidelineManager"; import { makeStyles, Text, Subtitle1, tokens, Theme, Spinner } from "@fluentui/react-components"; import { ShapeUnionRegular, SquareRegular, InfoRegular } from "@fluentui/react-icons"; interface AppProps { title: string; } export type StatusType = "info" | "success" | "warning" | "error"; export interface StatusContextType { statusMessage: string; setStatusMessage: (message: string) => void; statusType: StatusType; setStatusType: (type: StatusType) => void; isProcessing: boolean; setIsProcessing: (processing: boolean) => void; } export const StatusContext = React.createContext(undefined); export const useStatusContext = () => { const context = React.useContext(StatusContext); if (context === undefined) { throw new Error('useStatusContext must be used within a StatusProvider'); } return context; }; const useStyles = makeStyles({ root: { display: "flex", flexDirection: "column", height: "100%", padding: "16px", fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", backgroundColor: tokens.colorNeutralBackground1, overflow: "auto", maxHeight: "100vh", }, statusContainer: { marginTop: "4px", padding: "8px 12px", fontSize: "13px", borderRadius: "6px", backgroundColor: "#f3f2f1", // Light gray background transition: "all 0.3s ease", }, successStatus: { backgroundColor: "#DFF6DD", // Light green background color: "#107C10", // Green text }, warningStatus: { backgroundColor: "#FFF4CE", // Light yellow background color: "#797673", // Dark gray text }, errorStatus: { backgroundColor: "#FDE7E9", // Light red background color: "#A80000", // Red text }, statusIcon: { marginRight: "8px", }, statusText: { display: "flex", alignItems: "center", }, section: { marginBottom: "6px", padding: "12px", borderRadius: "8px", backgroundColor: tokens.colorNeutralBackground2, boxShadow: "0 1px 2px rgba(0, 0, 0, 0.06)", transition: "all 0.2s ease", ":hover": { boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)", }, }, sectionTitle: { marginBottom: "12px", fontWeight: tokens.fontWeightSemibold, color: tokens.colorBrandForeground1, }, footer: { fontSize: "12px", color: tokens.colorNeutralForeground3, textAlign: "center", marginTop: "auto", padding: "8px 0", }, }); const App: React.FC = () => { const styles = useStyles(); const [theme, setTheme] = useState("light"); // Status state const [statusMessage, setStatusMessage] = useState(""); const [statusType, setStatusType] = useState("info"); const [isProcessing, setIsProcessing] = useState(false); // Check if macOS is in dark mode (would need to be expanded in production) useEffect(() => { // In a real implementation, we would listen to Office theme changes const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; setTheme(prefersDarkMode ? "dark" : "light"); }, []); // Auto-clear success messages after 5 seconds useEffect(() => { let timer: number; if (statusType === "success" && statusMessage) { timer = window.setTimeout(() => { setStatusMessage(""); }, 5000); } return () => { if (timer) clearTimeout(timer); }; }, [statusMessage, statusType]); const getStatusIcon = () => { switch (statusType) { case "success": return ; case "warning": return ; case "error": return ; default: return null; } }; return (
Content
Progress Bar
Confidential Marking
Draft Watermark
Alignment
Layout
{/* Status message area at the bottom */} {isProcessing && (
Processing...
)} {!isProcessing && statusMessage && (
{getStatusIcon()} {statusMessage}
)}
Edison • v1.0.0
); }; export default App;