Skip to content

Commit

Permalink
Merge remote-tracking branch 'second/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmed-deriv committed Jan 9, 2025
2 parents aba6b56 + 57e5352 commit 8c02f05
Show file tree
Hide file tree
Showing 18 changed files with 619 additions and 208 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ env:
REACT_APP_WS_PORT: ${{ secrets.REACT_APP_WS_PORT }}
REACT_APP_WS_URL: ${{ secrets.REACT_APP_WS_URL }}
REACT_CURRENT_ENVIRONMENT: ${{ secrets.REACT_CURRENT_ENVIRONMENT }}
OAUTH_URL: ${{ secrets.OAUTH_URL }}

REACT_OAUTH_URL: ${{ secrets.REACT_OAUTH_URL }}
jobs:
deploy:
environment:
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-deriv.png" />
<title>Trade Rise Fall</title>
</head>
<body>
Expand Down
68 changes: 66 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/favicon-deriv.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 26 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
import React, { Suspense, useEffect } from 'react';
import { BrowserRouter, Routes, Route, useLocation, useNavigate } from 'react-router-dom';
import { ThemeProvider } from '@deriv-com/quill-ui';
import { observer } from 'mobx-react-lite';
import LoadingSpinner from './components/LoadingSpinner/LoadingSpinner';
import Header from './components/Header/Header';
import ProtectedRoute from './components/ProtectedRoute/ProtectedRoute';
import ErrorBoundary from './components/ErrorBoundary/ErrorBoundary';
import { authStore } from './stores/AuthStore';
import { authService } from './services/auth.service';
import React, { Suspense, useEffect } from "react";
import {
BrowserRouter,
Routes,
Route,
useLocation,
useNavigate,
} from "react-router-dom";
import { ThemeProvider } from "@deriv-com/quill-ui";
import { observer } from "mobx-react-lite";
import LoadingSpinner from "./components/LoadingSpinner/LoadingSpinner";
import Header from "./components/Header/Header";
import ProtectedRoute from "./components/ProtectedRoute/ProtectedRoute";
import ErrorBoundary from "./components/ErrorBoundary/ErrorBoundary";
import { authStore } from "./stores/AuthStore";
import { authService } from "./services/auth.service";

const Homepage = React.lazy(() => import('./pages/homepage'));
const DerivTrading = React.lazy(() => import('./pages/trading'));
const Homepage = React.lazy(() => import("./pages/homepage"));
const DerivTrading = React.lazy(() => import("./pages/trading"));

const AuthHandler: React.FC = observer(() => {
const location = useLocation();
const navigate = useNavigate();

useEffect(() => {
const params = new URLSearchParams(location.search);
const token = params.get('token1');
const token = params.get("token1");

if (token) {
authStore.handleAuthCallback(token).then((success) => {
// Clear the token from URL
const cleanUrl = window.location.pathname;
window.history.replaceState({}, document.title, cleanUrl);

if (success) {
navigate('/dashboard');
navigate("/dashboard");
} else {
navigate('/');
navigate("/");
}
});
}
Expand All @@ -44,12 +50,9 @@ const AppContent: React.FC = () => {
<AuthHandler />
<Header />
<Routes>
<Route
path="/"
element={<Homepage />}
/>
<Route
path="/dashboard"
<Route path="/" element={<Homepage />} />
<Route
path="/dashboard"
element={
<ProtectedRoute>
<DerivTrading />
Expand Down Expand Up @@ -82,7 +85,7 @@ const App: React.FC = observer(() => {

return (
<ErrorBoundary>
<ThemeProvider theme='light' persistent>
<ThemeProvider theme="light" persistent>
<BrowserRouter basename="/trade-rise-fall">
<AppContent />
</BrowserRouter>
Expand Down
6 changes: 6 additions & 0 deletions src/common/utils/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { authStore } from "../../stores/AuthStore";

/**
* Check if code is running in a browser environment
* @returns {boolean} True if running in browser, false otherwise
Expand All @@ -20,6 +22,10 @@ export const getChartUrl = (): string => {
return `${baseUrl}/js/smartcharts/`;
};

export const isLogged = (): boolean => {
return authStore.isAuthenticated;
};

export const getUrlBase = (path: string = ""): string => {
const l = window.location;

Expand Down
15 changes: 9 additions & 6 deletions src/components/ProtectedRoute/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import React from 'react';
import { Navigate, useLocation } from 'react-router-dom';
import { observer } from 'mobx-react-lite';
import { authStore } from '../../stores/AuthStore';
import React from "react";
import { Navigate, useLocation } from "react-router-dom";
import { observer } from "mobx-react-lite";
import { authStore } from "../../stores/AuthStore";
import { isLogged } from "../../common/utils";

interface ProtectedRouteProps {
children: React.ReactNode;
}

const ProtectedRoute = observer(function ProtectedRoute({ children }: ProtectedRouteProps) {
const ProtectedRoute = observer(function ProtectedRoute({
children,
}: ProtectedRouteProps) {
const location = useLocation();
const { isAuthenticated, isInitializing } = authStore;

if (isInitializing) {
return <div>Loading...</div>;
}

if (!isAuthenticated) {
if (!isLogged()) {
return <Navigate to="/" state={{ from: location }} replace />;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Text, TextField, TextFieldWithSteppers } from "@deriv-com/quill-ui";
import { Tab } from "../Tab";
import { DurationTabValue } from "../types";

interface DurationSectionProps {
duration: number;
selectedDurationTab: DurationTabValue;
durationError: string;
setDuration: (value: string) => void;
setSelectedDurationTab: (value: DurationTabValue) => void;
}

interface DurationTab {
label: string;
value: DurationTabValue;
}

export const DurationSection = ({
duration,
selectedDurationTab,
durationError,
setDuration,
setSelectedDurationTab,
}: DurationSectionProps) => {
const durationTabs: DurationTab[] = [
{ label: "Duration", value: "duration" },
{ label: "End time", value: "endtime" },
];

return (
<div className="duration-endtime-section">
<Tab
tabs={durationTabs}
activeTab={selectedDurationTab}
onChange={setSelectedDurationTab}
/>
{selectedDurationTab === "duration" ? (
<div className="duration-input">
<Text as="span" size="sm" className="text-bold">
Minutes
</Text>
<TextFieldWithSteppers
type="text"
value={duration.toString()}
onChange={(e) => setDuration(e.target.value)}
className="duration-field"
allowDecimals={false}
allowSign={false}
regex={/[^0-9]|^$/g}
inputMode="numeric"
shouldRound={true}
textAlignment="center"
minusDisabled={Number(duration) - 1 <= 0}
variant="fill"
status={durationError ? "error" : "success"}
message={durationError}
/>
<Text as="span" size="sm" className="text-less-prominent">
Range: 1 - 1,440 minutes
</Text>
</div>
) : (
<div className="endtime-inputs">
<TextField
type="text"
value="03 Jan 2025"
readOnly
className="date-input"
/>
<TextField
type="text"
value="03:20 GMT"
readOnly
className="time-input"
/>
</div>
)}
</div>
);
};
34 changes: 34 additions & 0 deletions src/components/TradingComponents/PayoutInfo/PayoutInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Text, Tooltip } from "@deriv-com/quill-ui";
import { LabelPairedCircleInfoSmBoldIcon } from "@deriv/quill-icons";

interface PayoutInfoProps {
type: "rise" | "fall";
label: string;
amount: string;
isLoading: boolean;
}

export const PayoutInfo = ({
type,
label,
amount,
isLoading,
}: PayoutInfoProps) => {
return (
<div className="payout-info-row">
{!isLoading && (
<>
<Text as="span" size="sm" className="text-bold">
{label}
</Text>
<Text as="span" size="lg" className="text-bold">
{amount} USD
</Text>
<Tooltip tooltipContent={`${label} info`}>
<LabelPairedCircleInfoSmBoldIcon className="info-icon" />
</Tooltip>
</>
)}
</div>
);
};
Loading

0 comments on commit 8c02f05

Please sign in to comment.