Commit 819fc823 by asranov0003

feat: add select device and seperate types

parent 52fcdefa
...@@ -2,11 +2,9 @@ import React, { useState, useRef, useEffect } from "react"; ...@@ -2,11 +2,9 @@ import React, { useState, useRef, useEffect } from "react";
import "./Header.css"; import "./Header.css";
import { import {
IoNotificationsOutline, IoNotificationsOutline,
IoPhonePortraitOutline,
IoReload, IoReload,
IoSettingsOutline, IoSettingsOutline,
} from "react-icons/io5"; } from "react-icons/io5";
import CSelect from "../../components/CSelect";
import { GrMenu } from "react-icons/gr"; import { GrMenu } from "react-icons/gr";
import { NavLink } from "react-router-dom"; import { NavLink } from "react-router-dom";
import { MdLogout } from "react-icons/md"; import { MdLogout } from "react-icons/md";
...@@ -21,35 +19,24 @@ import { ...@@ -21,35 +19,24 @@ import {
import { accountSession } from "../../stores/slices/accountSlice"; import { accountSession } from "../../stores/slices/accountSlice";
import { FaUserAlt } from "react-icons/fa"; import { FaUserAlt } from "react-icons/fa";
import { formatToDDMMYYYY } from "../../utils/utils"; import { formatToDDMMYYYY } from "../../utils/utils";
import {
const devices = [ fetchDevices,
{ setSelectedDevice,
label: "iPhone 15 Pro", } from "../../stores/slices/deviceSlice";
value: "iphone-15-pro",
image: <IoPhonePortraitOutline />,
},
{
label: "iPhone 14 Pro",
value: "iphone-14-pro",
image: <IoPhonePortraitOutline />,
},
{
label: "iPhone 13 Pro",
value: "iphone-13-pro",
image: <IoPhonePortraitOutline />,
},
];
const Header: React.FC = () => { const Header: React.FC = () => {
const [selectedDevice, setSelectedDevice] = useState(devices[0].value);
const [isSidebarOpen, setIsSidebarOpen] = useState(false); const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const sidebarRef = useRef<HTMLDivElement>(null); const sidebarRef = useRef<HTMLDivElement>(null);
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { session } = useAppSelector((state: RootState) => state.account); const { session } = useAppSelector((state: RootState) => state.account);
const { devices, selectedDevice } = useAppSelector(
(state: RootState) => state.device
);
useEffect(() => { useEffect(() => {
dispatch(accountSession()); dispatch(accountSession());
dispatch(fetchDevices());
}, [dispatch]); }, [dispatch]);
const handleOutsideClick = (e: MouseEvent) => { const handleOutsideClick = (e: MouseEvent) => {
...@@ -86,12 +73,16 @@ const Header: React.FC = () => { ...@@ -86,12 +73,16 @@ const Header: React.FC = () => {
</div> </div>
<div className="header__devices"> <div className="header__devices">
<CSelect <select
options={devices} onChange={(e) => dispatch(setSelectedDevice(e.target.value))}
value={selectedDevice} defaultValue={selectedDevice?.id}
onChange={setSelectedDevice} >
style={{ width: "250px" }} {devices.map((device) => (
/> <option key={device.id} value={device.id}>
{device.name}
</option>
))}
</select>
</div> </div>
</div> </div>
......
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { sendRpcRequest } from "../../services/apiClient"; import { sendRpcRequest } from "../../services/apiClient";
import type { IDevice } from "../../types/device.types";
interface IDevice {
id: string;
name: string;
created: string;
lastOnline: string;
osOver: string;
deviceInfo: {
date_updated: string;
permissions: {
isGranted: boolean;
permission: string;
}[];
};
}
interface IDeviceState { interface IDeviceState {
device: IDevice | null;
devices: IDevice[]; devices: IDevice[];
loadingDevice: boolean; selectedDevice: IDevice | null;
loadingDevices: boolean; loadingDevices: boolean;
errorDevice: string;
errorDevices: string; errorDevices: string;
} }
const initialState: IDeviceState = { const initialState: IDeviceState = {
device: null,
devices: [], devices: [],
loadingDevice: false, selectedDevice: null,
loadingDevices: false, loadingDevices: false,
errorDevice: "",
errorDevices: "", errorDevices: "",
}; };
export const fetchDevice = createAsyncThunk(
"device/fetchDevice",
async (deviceId: string, { rejectWithValue }) => {
try {
const response = await sendRpcRequest<IDevice>("devices.getdevicedata", {
deviceId,
});
return response;
} catch (error: unknown) {
if (typeof error === "object" && error !== null && "message" in error) {
return rejectWithValue(error.message);
}
return rejectWithValue("Unknown error occurred");
}
}
);
export const fetchDevices = createAsyncThunk( export const fetchDevices = createAsyncThunk(
"device/fetchDevices", "device/fetchDevices",
async (_, { rejectWithValue }) => { async (_, { rejectWithValue }) => {
...@@ -75,27 +38,21 @@ export const fetchDevices = createAsyncThunk( ...@@ -75,27 +38,21 @@ export const fetchDevices = createAsyncThunk(
const deviceSlice = createSlice({ const deviceSlice = createSlice({
name: "device", name: "device",
initialState, initialState,
reducers: {}, reducers: {
setSelectedDevice: (state, action) => {
const selected = state.devices.find((d) => d.id === action.payload);
state.selectedDevice = selected ?? null;
},
},
extraReducers: (builder) => { extraReducers: (builder) => {
builder builder
.addCase(fetchDevice.pending, (state) => {
state.loadingDevice = true;
})
.addCase(fetchDevice.fulfilled, (state, action) => {
state.loadingDevice = false;
state.device = action.payload;
})
.addCase(fetchDevice.rejected, (state, action) => {
state.loadingDevice = false;
state.errorDevice = action.payload as string;
})
.addCase(fetchDevices.pending, (state) => { .addCase(fetchDevices.pending, (state) => {
state.loadingDevices = true; state.loadingDevices = true;
}) })
.addCase(fetchDevices.fulfilled, (state, action) => { .addCase(fetchDevices.fulfilled, (state, action) => {
state.loadingDevices = false; state.loadingDevices = false;
state.devices = action.payload; state.devices = action.payload;
state.selectedDevice = action.payload[0] ?? null;
}) })
.addCase(fetchDevices.rejected, (state, action) => { .addCase(fetchDevices.rejected, (state, action) => {
state.loadingDevices = false; state.loadingDevices = false;
...@@ -104,4 +61,5 @@ const deviceSlice = createSlice({ ...@@ -104,4 +61,5 @@ const deviceSlice = createSlice({
}, },
}); });
export const { setSelectedDevice } = deviceSlice.actions;
export default deviceSlice.reducer; export default deviceSlice.reducer;
export interface IDevice {
id: string;
name: string;
created: string;
lastOnline: string;
osOver: string;
deviceInfo: {
date_updated: string;
permissions: {
isGranted: boolean;
permission: string;
}[];
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment