Compare commits
2 Commits
89493853e9
...
1570185792
| Author | SHA1 | Date | |
|---|---|---|---|
| 1570185792 | |||
| c48fc96b33 |
@@ -1,7 +1,8 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
import { features } from './config/features';
|
||||||
|
|
||||||
const baseURL = import.meta.env.VITE_API_URL;
|
const baseURL = features.apiUrl;
|
||||||
console.log(baseURL);
|
console.log(baseURL);
|
||||||
|
|
||||||
export const axiosRealEstateApi = axios.create({
|
export const axiosRealEstateApi = axios.create({
|
||||||
|
|||||||
@@ -395,11 +395,17 @@ const ChatPane = ({ showChat, isMinimized, toggleMinimize, closeChat }: ChatPane
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FloatingChatButton = (): ReactElement => {
|
import { features } from 'config/features';
|
||||||
|
|
||||||
|
const FloatingChatButton = (): ReactElement | null => {
|
||||||
const [showChat, setShowChat] = useState<boolean>(false);
|
const [showChat, setShowChat] = useState<boolean>(false);
|
||||||
// State to control if the chat pane is minimized
|
// State to control if the chat pane is minimized
|
||||||
const [isMinimized, setIsMinimized] = useState<boolean>(false);
|
const [isMinimized, setIsMinimized] = useState<boolean>(false);
|
||||||
|
|
||||||
|
if (!features.enableFloatingChatButton) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Function to toggle the chat pane visibility
|
// Function to toggle the chat pane visibility
|
||||||
const toggleChat = () => {
|
const toggleChat = () => {
|
||||||
setShowChat(!showChat);
|
setShowChat(!showChat);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
import { test_property_search } from 'data/mock_property_search';
|
import { test_property_search } from 'data/mock_property_search';
|
||||||
import { extractLatLon } from 'utils';
|
import { extractLatLon } from 'utils';
|
||||||
import { test_autocomplete } from 'data/mock_autocomplete_results';
|
import { test_autocomplete } from 'data/mock_autocomplete_results';
|
||||||
|
import { features } from '../../../../../config/features';
|
||||||
|
|
||||||
interface AddPropertyDialogProps {
|
interface AddPropertyDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -204,7 +205,7 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
console.log('here we go', value);
|
console.log('here we go', value);
|
||||||
if (value) {
|
if (value) {
|
||||||
console.log('find the test data');
|
console.log('find the test data');
|
||||||
const test: boolean = import.meta.env.USE_LIVE_DATA;
|
const test: boolean = features.useLiveData;
|
||||||
if (test) {
|
if (test) {
|
||||||
const parts: string[] =
|
const parts: string[] =
|
||||||
test_property_search.data.currentMortgages[0].recordingDate.split('T');
|
test_property_search.data.currentMortgages[0].recordingDate.split('T');
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { PlacePrediction } from './AddPropertyDialog';
|
|||||||
import { test_autocomplete } from 'data/mock_autocomplete_results';
|
import { test_autocomplete } from 'data/mock_autocomplete_results';
|
||||||
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
||||||
import { extractLatLon } from 'utils';
|
import { extractLatLon } from 'utils';
|
||||||
|
import { features } from '../../../../../config/features';
|
||||||
|
|
||||||
interface AttorneyProfileCardProps {
|
interface AttorneyProfileCardProps {
|
||||||
attorney: AttorneyAPI;
|
attorney: AttorneyAPI;
|
||||||
@@ -115,7 +116,7 @@ const AttorneyProfileCard: React.FC<AttorneyProfileCardProps> = ({
|
|||||||
event: React.SyntheticEvent,
|
event: React.SyntheticEvent,
|
||||||
value: string,
|
value: string,
|
||||||
) => {
|
) => {
|
||||||
const test: boolean = !import.meta.env.USE_LIVE_DATA;
|
const test: boolean = !features.useLiveData;
|
||||||
let data: AutocompleteDataResponseAPI[] = [];
|
let data: AutocompleteDataResponseAPI[] = [];
|
||||||
if (value.length > 2) {
|
if (value.length > 2) {
|
||||||
if (test) {
|
if (test) {
|
||||||
|
|||||||
63
ditch-the-agent/src/config/features.ts
Normal file
63
ditch-the-agent/src/config/features.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* Feature flags and environment configuration
|
||||||
|
* Controls feature availability and environment settings based on build mode (production, beta, development)
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface FeatureConfig {
|
||||||
|
// Registration features
|
||||||
|
enableAttorneyRegistration: boolean;
|
||||||
|
enableRealEstateAgentRegistration: boolean;
|
||||||
|
enableRegistration: boolean;
|
||||||
|
|
||||||
|
// UI Features
|
||||||
|
enableFloatingChatButton: boolean;
|
||||||
|
|
||||||
|
// API Configuration
|
||||||
|
apiUrl: string;
|
||||||
|
|
||||||
|
// Data Configuration
|
||||||
|
useLiveData: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get feature configuration based on current environment
|
||||||
|
*/
|
||||||
|
const getFeatureConfig = (): FeatureConfig => {
|
||||||
|
const mode = import.meta.env.MODE || 'development';
|
||||||
|
|
||||||
|
// Production configuration
|
||||||
|
if (mode === 'production') {
|
||||||
|
return {
|
||||||
|
enableAttorneyRegistration: false,
|
||||||
|
enableRealEstateAgentRegistration: false,
|
||||||
|
enableRegistration: false,
|
||||||
|
enableFloatingChatButton: false,
|
||||||
|
apiUrl: 'https://backend.ditchtheagent.com/api/',
|
||||||
|
useLiveData: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beta configuration
|
||||||
|
if (mode === 'beta') {
|
||||||
|
return {
|
||||||
|
enableAttorneyRegistration: true,
|
||||||
|
enableRealEstateAgentRegistration: true,
|
||||||
|
enableRegistration: true,
|
||||||
|
enableFloatingChatButton: true,
|
||||||
|
apiUrl: 'https://beta.backend.ditchtheagent.com/api/',
|
||||||
|
useLiveData: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Development configuration (default)
|
||||||
|
return {
|
||||||
|
enableAttorneyRegistration: true,
|
||||||
|
enableRealEstateAgentRegistration: true,
|
||||||
|
enableRegistration: true,
|
||||||
|
enableFloatingChatButton: true,
|
||||||
|
apiUrl: 'http://127.0.0.1:8010/api/',
|
||||||
|
useLiveData: false,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const features = getFeatureConfig();
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, createContext, useRef, useState, useContext, ReactNode } from 'react';
|
import React, { useEffect, createContext, useRef, useState, useContext, ReactNode } from 'react';
|
||||||
import { AccountContext } from './AccountContext';
|
import { AccountContext } from './AccountContext';
|
||||||
import { AuthContext } from './AuthContext';
|
import { AuthContext } from './AuthContext';
|
||||||
|
import { features } from '../config/features';
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
// Define Types and Interfaces
|
// Define Types and Interfaces
|
||||||
@@ -65,10 +66,10 @@ interface WebSocketProviderProps {
|
|||||||
// Provide a default value that matches the IWebSocketContext interface.
|
// Provide a default value that matches the IWebSocketContext interface.
|
||||||
// This is used when a component tries to consume the context without a provider.
|
// This is used when a component tries to consume the context without a provider.
|
||||||
const WebSocketContext = createContext<IWebSocketContext>({
|
const WebSocketContext = createContext<IWebSocketContext>({
|
||||||
subscribe: () => {},
|
subscribe: () => { },
|
||||||
unsubscribe: () => {},
|
unsubscribe: () => { },
|
||||||
socket: null,
|
socket: null,
|
||||||
sendMessages: () => {},
|
sendMessages: () => { },
|
||||||
});
|
});
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
@@ -141,7 +142,7 @@ function WebSocketProvider({ children }: WebSocketProviderProps) {
|
|||||||
ws.current.close();
|
ws.current.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const wsUrl = new URL(import.meta.env.VITE_API_URL || 'ws://127.0.0.1:8010/ws/');
|
const wsUrl = new URL(features.apiUrl || 'ws://127.0.0.1:8010/ws/');
|
||||||
wsUrl.protocol = wsUrl.protocol.replace('http', 'ws');
|
wsUrl.protocol = wsUrl.protocol.replace('http', 'ws');
|
||||||
|
|
||||||
ws.current = new WebSocket(
|
ws.current = new WebSocket(
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
import { features } from '../../config/features';
|
||||||
|
|
||||||
const base_url: string = `${import.meta.env.VITE_API_URL?.replace('/api/', '')}/media/vendor_pictures/`;
|
const base_url: string = `${features.apiUrl?.replace('/api/', '')}/media/vendor_pictures/`;
|
||||||
|
|
||||||
// Define the array of corrected and alphabetized categories with 'as const'
|
// Define the array of corrected and alphabetized categories with 'as const'
|
||||||
export const CATEGORY_NAMES = [
|
export const CATEGORY_NAMES = [
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import Image from 'components/base/Image';
|
|||||||
import { axiosInstance } from '../../axiosApi.js';
|
import { axiosInstance } from '../../axiosApi.js';
|
||||||
import PasswordStrengthChecker from '../../components/PasswordStrengthChecker';
|
import PasswordStrengthChecker from '../../components/PasswordStrengthChecker';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { features } from '../../config/features';
|
||||||
|
|
||||||
type SignUpValues = {
|
type SignUpValues = {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -191,10 +192,12 @@ const SignUp = (): ReactElement => {
|
|||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
|
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>
|
||||||
{[
|
{[
|
||||||
{ value: 'property_owner', label: 'Home Buyer/Seller', icon: 'mdi:home-account' },
|
{ value: 'property_owner', label: 'Home Buyer/Seller', icon: 'mdi:home-account', enabled: true },
|
||||||
{ value: 'attorney', label: 'Attorney', icon: 'mdi:gavel' },
|
{ value: 'attorney', label: 'Attorney', icon: 'mdi:gavel', enabled: features.enableAttorneyRegistration },
|
||||||
{ value: 'vendor', label: 'Vendor', icon: 'mdi:briefcase' },
|
{ value: 'vendor', label: 'Vendor', icon: 'mdi:briefcase', enabled: features.enableRealEstateAgentRegistration },
|
||||||
].map((type) => (
|
]
|
||||||
|
.filter((type) => type.enabled)
|
||||||
|
.map((type) => (
|
||||||
<Paper
|
<Paper
|
||||||
key={type.value}
|
key={type.value}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|||||||
Reference in New Issue
Block a user