Styled Paper - Copy this React, Mui Component to your project
import { useState } from "react"; import { Box, Button, Card, CardContent, CircularProgress, Container, Divider, Grid, List, ListItem, TextField, Typography, } from "@mui/material"; import { useSelector } from "react-redux"; import { useSnackbar } from "notistack"; import Friends from "./Friends"; import { capitalizeFirstLetter } from "./utils"; import { convertToBlobLink, convertToBytes, } from "../../DataProcessing/imageToVec"; import BasicTabs from "./History"; import TransactionHistory from "./TransactionHistory"; import { UserHistoryComponent } from "../User"; import ProfilePhoto from "./ProfilePhoto"; import ProfileRatings from "./ProfileRating"; import WalletSection from "./WalletSection"; import { useBackendContext } from "../../contexts/BackendContext"; import * as React from "react"; export default function ProfileComponent() { const { backendActor } = useBackendContext(); const { enqueueSnackbar } = useSnackbar(); const { profile, friends, profile_history, wallet } = useSelector( (state: any) => state.filesState, ); const [profileData, setProfileData] = useState({ changed: false, ...profile, }); const [buttonLoading, setButtonLoading] = useState(false); const handleSaveChanges = async () => { setButtonLoading(true); try { const res = await backendActor?.update_user_profile({ name: [profileData.name], description: [profileData.description], photo: [profileData.photo], }); setProfileData((prev) => ({ ...prev, changed: false })); enqueueSnackbar("Profile updated successfully!", { variant: "success", }); return res; } catch (error) { console.error("Error saving profile:", error); enqueueSnackbar("Failed to update profile.", { variant: "error" }); } finally { setButtonLoading(false); } }; const [photoUpload, setUploading] = useState(false); const handlePhotoChange = async (e: React.ChangeEvent<HTMLInputElement>) => { setUploading(true); const fileInput = e.target; if (fileInput.files && fileInput.files[0]) { try { const photo = await convertToBytes(fileInput.files[0]); setProfileData((prev) => ({ ...prev, photo, changed: true })); // dispatch(handleRedux("UPDATE_PROFILE", { profile: { photo } })); } catch (error) { console.error("Error processing photo:", error); } fileInput.value = ""; } setUploading(false); }; if (!profile) { return <Typography variant="h6">please login</Typography>; } const ProfileDetailList = () => ( <List> {Object.entries(profileData).map(([key, value]) => { if (["photo", "changed"].includes(key)) return null; return ( <ListItem key={key}> <TextField disabled={key === "id"} label={capitalizeFirstLetter(key)} defaultValue={value} onBlur={(e) => setProfileData((prev) => ({ ...prev, [key]: e.target.value, changed: true, })) } fullWidth multiline={key === "description"} rows={key === "description" ? 4 : 1} variant="outlined" InputLabelProps={{ style: { fontWeight: "bold" } }} InputProps={{ style: { borderRadius: 8 } }} /> </ListItem> ); })} </List> ); return ( <Container maxWidth="lg" sx={{ mt: 4 }}> <Grid container spacing={4}> <Grid item xs={12} md={8}> <Card sx={{ borderRadius: 2, boxShadow: 3, overflow: "hidden" }}> <CardContent> <Divider sx={{ my: 2 }} /> <Grid container spacing={2}> <Grid item xs={12}> <ProfilePhoto loading={photoUpload} photo={convertToBlobLink(profileData.photo)} onPhotoChange={handlePhotoChange} /> <ProfileRatings profile_history={profile_history} profileData={profileData} /> </Grid> <Grid item xs={12}> <ProfileDetailList /> {profileData.changed && ( <Box sx={{ width: "100%", mt: 2 }}> <Button color="warning" onClick={handleSaveChanges} variant="contained" sx={{ width: "100% !important" }} > {buttonLoading ? ( <CircularProgress size={20} /> ) : ( "Save changes" )} </Button> </Box> )} </Grid> </Grid> </CardContent> </Card> </Grid> <Grid item xs={12} md={4}> <WalletSection /> <Divider sx={{ my: 4 }} /> <Box sx={{ display: "flex", justifyContent: "center" }}> <BasicTabs items={{ Friends: <Friends />, ...(wallet && { Transactions: <TransactionHistory /> }), }} /> </Box> </Grid> </Grid> <Divider style={{ marginTop: "20px" }} /> <UserHistoryComponent {...profile_history} /> </Container> ); } use this code but make it more beaitufl