From 26e9adbb4e07796b5689045d480e6b82a8cd0f29 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro <47680931+tubarao312@users.noreply.github.com> Date: Thu, 29 Feb 2024 01:38:34 +0000 Subject: [PATCH] Edit tutorial cards and input --- src/PublicApp.tsx | 33 +- src/components/auth/AuthInput.tsx | 15 +- src/components/graph/search_bar/SearchBar.tsx | 14 +- .../graph/tutorial/TutorialDialog.tsx | 15 +- .../graph/tutorial/steps/TutorialSteps.tsx | 410 ++++++++++-------- src/templates/SavedGraphsTemplate.tsx | 58 +-- 6 files changed, 292 insertions(+), 253 deletions(-) diff --git a/src/PublicApp.tsx b/src/PublicApp.tsx index da0a0a4e..610640a8 100644 --- a/src/PublicApp.tsx +++ b/src/PublicApp.tsx @@ -13,9 +13,10 @@ interface UnauthenticatedTimeContextProps { setStartTime: (startTime: boolean) => void; } -export const UnauthenticatedTimeContext = createContext({ - setStartTime: () => { }, -}); +export const UnauthenticatedTimeContext = + createContext({ + setStartTime: () => {}, + }); const PublicApp: FC = () => { // The total time spent on the app @@ -23,11 +24,12 @@ const PublicApp: FC = () => { const [startTime, setStartTime] = useState(false); // Time limit in seconds - const timeLimit = 1 * 60; // 1 minutes + const timeLimit = 100; // 100 seconds // The AuthDialog is shown when the user is not authenticated and the time limit is reached const initialShowDialog = localStorage.getItem("expiredFreeTrial") === "true"; - const [showAuthDialog, setShowAuthDialog] = useState(initialShowDialog); + const [showAuthDialog, setShowAuthDialog] = + useState(initialShowDialog); // Create time context const unauthenticatedTimeContext: UnauthenticatedTimeContextProps = { @@ -54,10 +56,19 @@ const PublicApp: FC = () => {
- } /> - } /> + } + /> + } + /> } /> - } /> + } + /> {/* Keep for legacy reasons */} } /> } /> @@ -66,7 +77,11 @@ const PublicApp: FC = () => { {/* The AuthDialog is shown when the user is not authenticated and the time limit is reached No setter is passed to the AuthDialog because the user can only close it by logging in or creating an account */} - { }} signInText="Sign in to your account to continue using the app" /> + {}} + signInText="Sign in to your account to continue using the app" + /> ); }; diff --git a/src/components/auth/AuthInput.tsx b/src/components/auth/AuthInput.tsx index bea3c74d..b6091f0d 100644 --- a/src/components/auth/AuthInput.tsx +++ b/src/components/auth/AuthInput.tsx @@ -6,7 +6,10 @@ interface AuthInputProps extends React.InputHTMLAttributes { } const AuthInput = ({ label, name, ...rest }: AuthInputProps) => { - const { register, formState: { errors } } = useFormContext(); + const { + register, + formState: { errors }, + } = useFormContext(); const error = errors[name]; @@ -22,14 +25,12 @@ const AuthInput = ({ label, name, ...rest }: AuthInputProps) => { {...register(name)} {...rest} className={ - "block w-full rounded-none rounded-l-md border-0 py-1.5 text-sm leading-6 text-gray-900 ring-1 ring-inset ring-gray-300 transition-all placeholder:text-gray-400 focus:ring-2 focus:ring-inset" + "block w-full rounded-md border-0 py-1.5 text-sm leading-6 text-gray-900 ring-1 ring-inset ring-gray-300 transition-all placeholder:text-gray-400 focus:outline focus:outline-[3px] focus:outline-blue-200 focus:ring-2 focus:ring-blue-400" } /> - {error && -

- {error.message?.toString()} -

- } + {error && ( +

{error.message?.toString()}

+ )}
); }; diff --git a/src/components/graph/search_bar/SearchBar.tsx b/src/components/graph/search_bar/SearchBar.tsx index 2fde4951..362240a2 100644 --- a/src/components/graph/search_bar/SearchBar.tsx +++ b/src/components/graph/search_bar/SearchBar.tsx @@ -56,16 +56,15 @@ const SearchBar: FC = ({ className, onSearchAddress }) => { const popoverRef = useRef(null); // Popover ref for hotkeys const { user } = useAuthState(); const { mutate: searchLabels } = useSearchLabels({ - mutation: - { + mutation: { onSuccess: (data) => { if (data.labels) { setEntitySearchResults(data.labels); } else { setEntitySearchResults([]); } - } - } + }, + }, }); // The current query the user is typing @@ -100,9 +99,10 @@ const SearchBar: FC = ({ className, onSearchAddress }) => { // If the query is the same as the last time searched, don't search again searchLabels({ data: { - query, limit: MAX_SEARCH_HISTORY - } - }) + query, + limit: MAX_SEARCH_HISTORY, + }, + }); }, [query]); // Combine uniqueSearchHistory and entitySearchResults into a single list of search results diff --git a/src/components/graph/tutorial/TutorialDialog.tsx b/src/components/graph/tutorial/TutorialDialog.tsx index d359a0f0..58730525 100644 --- a/src/components/graph/tutorial/TutorialDialog.tsx +++ b/src/components/graph/tutorial/TutorialDialog.tsx @@ -43,7 +43,7 @@ const ProgressCircle: FC = ({
} @@ -63,7 +63,7 @@ const ProgressCircles: FC = ({ setCurrentStep, }) => { // Number of circles to show at a time - const maxVisibleCircles = 5; + const maxVisibleCircles = 8; // Start index of the circles to show const start = Math.max(0, currentStep - Math.floor(maxVisibleCircles / 2)); @@ -141,9 +141,10 @@ const TutorialDialog: FC = ({ }; return ( - -
) => { + +
) => { const hotKey = event.key; switch (hotKey) { case hotKeysMap.ARROW_LEFT.key: @@ -153,8 +154,8 @@ const TutorialDialog: FC = ({ await hotKeysMap.ARROW_RIGHT.asyncHandler!(event); break; } - } - }> + }} + >
{ - return ( - <> - - - - - ); + return ( + <> + + + + + ); }; /** The InspectionCard component is a tutorial step that explains how to inspect an address in the Ward Graph application. */ const InspectionCard: FC = () => { - return ( - <> - - - - - ); + return ( + <> + + + + + ); }; /** The ExplorationCard component is a tutorial step that explains how to explore the blockchain in the Ward Graph application. */ const ExplorationCard: FC = () => { - return ( - <> - - - - - ); + return ( + <> + + + + + ); }; /** The EdgeManagementCard component is a tutorial step that explains how to manage edges in the Ward Graph application. */ const EdgeManagementCard: FC = () => { - const listItems = [ - { - text: "Only the paths you expand through are shown by default.", - Icon: ArrowPathIcon, - }, - { - text: "You can inspect an address to see its hidden 'grayed-out' edges.", - Icon: EyeSlashIcon, - }, - { - text: "Click the edges to toggle them on or off.", - Icon: CursorArrowRaysIcon, - }, - ]; + const listItems = [ + { + text: "Only the paths you expand through are shown by default.", + Icon: ArrowPathIcon, + }, + { + text: "You can inspect an address to see its hidden 'grayed-out' edges.", + Icon: EyeSlashIcon, + }, + { + text: "Click the edges to toggle them on or off.", + Icon: CursorArrowRaysIcon, + }, + ]; - return ( - <> - - -
- - -
- - ); + return ( + <> + + +
+ + +
+ + ); }; /** The HotbarCard component is a tutorial step that explains the functionality of the hotbar in the Ward Graph application. * The hotbar is a set of buttons that provide quick access to important features of the application. - * + * * The hotbar contains the following buttons: * - Search Address * - Organize Layout @@ -125,166 +130,195 @@ const EdgeManagementCard: FC = () => { * - Share Graph * - Tutorial Button * - Report Bug - * + * * Each button has an icon and a text label. */ const HotbarCard: FC = () => { - // List of items to display in the tutorial card list - const listItems = [ - { - text: "Search Address", - Icon: PlusCircleIcon, - }, - { - text: "Organize Layout", - Icon: RectangleGroupIcon, - }, - { - text: "Risk Vision", - Icon: EyeIcon, - }, - { - text: "Save Graph", - Icon: BookmarkIcon, - }, - { - text: "Share Graph", - Icon: ShareIcon, - }, - { - text: "Tutorial Button", - Icon: QuestionMarkCircleIcon, - }, - { - text: "Report Bug", - Icon: BugAntIcon, - }, - ]; + // List of items to display in the tutorial card list + const listItems = [ + { + text: "Search Address", + Icon: PlusCircleIcon, + }, + { + text: "Organize Layout", + Icon: RectangleGroupIcon, + }, + { + text: "Risk Vision", + Icon: EyeIcon, + }, + { + text: "Save Graph", + Icon: BookmarkIcon, + }, + { + text: "Share Graph", + Icon: ShareIcon, + }, + { + text: "Tutorial Button", + Icon: QuestionMarkCircleIcon, + }, + { + text: "Report Bug", + Icon: BugAntIcon, + }, + ]; - return ( - <> - - -
- - -
- - ); -} + return ( + <> + + +
+ + +
+ + ); +}; /** The RiskVisionCard component is a tutorial step that explains the functionality of the risk vision feature in the Ward Graph application. */ const RiskVisionCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The SearchAddressCard component is a tutorial step that explains how to search for an address in the Ward Graph application. */ const SearchAddressCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The ShareGraphCard component is a tutorial step that explains how to share a graph in the Ward Graph application. */ const ShareGraphCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The TaggingAddressesCard component is a tutorial step that explains how to tag addresses in the Ward Graph application. */ const TaggingAddressesCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The AdvancedMenuCard component is a tutorial step that explains how to access the advanced menu in the Ward Graph application. */ const AdvancedMenuCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The ExpandWithAICard component is a tutorial step that explains how to expand the graph with AI in the Ward Graph application. */ const ExpandWithAICard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The TransactionsMenuCard component is a tutorial step that explains how to access the transactions menu in the Ward Graph application. */ const TransactionsMenuCard: FC = () => { - return ( - <> - - - - - ); -} + return ( + <> + + + + + ); +}; /** The GoodLuckCard component is a tutorial step that wishes the user good luck as they explore the blockchain in the Ward Graph application. */ const GoodLuckCard: FC = () => { - return ( - <> - - - - - ); + return ( + <> + + +

+ You're ready to explore the blockchain. Good luck! You can view the + advanced documentation in the{" "} + + Ward Spellbook Documentation + + . +

+ + ); }; /** A list of tutorial steps for the Ward Graph tutorial. Each step is a React component that is displayed in the tutorial dialog. */ const tutorialSteps = [ - IntroductionCard, - InspectionCard, - ExplorationCard, - EdgeManagementCard, - AdvancedMenuCard, - ExpandWithAICard, - TransactionsMenuCard, - TaggingAddressesCard, - HotbarCard, - RiskVisionCard, - SearchAddressCard, - ShareGraphCard, - GoodLuckCard, + IntroductionCard, + InspectionCard, + ExplorationCard, + GoodLuckCard, ]; export default tutorialSteps; diff --git a/src/templates/SavedGraphsTemplate.tsx b/src/templates/SavedGraphsTemplate.tsx index 2ca08c07..e17bc90e 100644 --- a/src/templates/SavedGraphsTemplate.tsx +++ b/src/templates/SavedGraphsTemplate.tsx @@ -40,7 +40,7 @@ const GraphCard: FC = ({ userID, graph }) => { graph.name = graphName; await updatePersonalGraph(userID, graph); setEditMode(false); - } + }; // Hotkeys for the graph name input // Enter: Save the graph name @@ -58,40 +58,28 @@ const GraphCard: FC = ({ userID, graph }) => { return (

- { - editMode ? ( -

- setGraphName(e.target.value)} - autoFocus - className="group-hover:block bg-gray-100 text-gray-800 text-base font-semibold rounded-md p-1.5 transition-all duration-150 w-full" - onKeyDown={async (event) => { - const hotKey = event.key.toLocaleLowerCase(); - switch (hotKey) { - case hotKeysMap.ENTER.key: - await hotKeysMap.ENTER.asyncHandler!(event); - break; - } - }} - /> - - { - // Reset the graph name - setGraphName(graph.name); - setEditMode(false); - }} - /> -
- ) : - setEditMode(true)}>{graph.name} - } + {editMode ? ( +
+ setGraphName(e.target.value)} + autoFocus + className="block w-full rounded-md border-0 py-1.5 text-sm leading-6 text-gray-900 ring-1 ring-inset ring-gray-300 transition-all placeholder:text-gray-400 focus:outline focus:outline-[3px] focus:outline-blue-200 focus:ring-2 focus:ring-blue-400" + onKeyDown={async (event) => { + const hotKey = event.key.toLocaleLowerCase(); + switch (hotKey) { + case hotKeysMap.ENTER.key: + await hotKeysMap.ENTER.asyncHandler!(event); + break; + } + }} + onBlur={onChangeGraphName} + /> +
+ ) : ( + setEditMode(true)}>{graph.name} + )}