'Display a Circle with Dynamic Children
I'm creating a dynamic array display using a circle as a layout. Each element of the array will take the same portion of space inside the circle. If there are 3 elements in the array, 100% of the circle needs to be filled up in 3 equal spaces. I have made it work up to the point of displaying 4 elements of equal size. I need help figuring out a formula to resize the squares based on the size of the array.
My approach is to create each element individually. I need to control each child inside the circle while also centering the text inside the child. I'm also open to new ideas, I feel the code is getting a little messy. If you have a cleaner approach please share!
Below is my code:
import React, { useState, forwardRef } from "react";
import {dataFlow} from './database'
const PieDisplay = forwardRef(({ showWindow }, ref) => {
const [display, setDisplay] = useState(dataFlow.map((item) => item));
const getPieStyle = (index) => {
let pieButtonStyle = {
transform: "",
};
const rotX = (360 / display.length) * index; //set the angle for each element of the pie
pieButtonStyle.transform = `rotate(${rotX}deg) skewY(0deg)`;
return pieButtonStyle;
};
const getPieTextStyle = (index) => {
let pieButtonStyle = {
transform: "",
};
const rotX = 360 / display.length / 2; //set the angle for each element's text of the pie
pieButtonStyle.transform = `rotate(${rotX}deg) skewY(0deg)`;
return pieButtonStyle;
};
let i = 0;
let j = 0;
return (
<div className="background">
<div className="pie-parent">
{display.map((elem) => (
<div
className="pie-button"
style={getPieStyle(i += 1)}
key={elem.name}
onClick={
elem.items ? () => updateDisplay(elem.name) : () => showWindow()
}
ref={ref}
>
<pre
className="pie-button--text"
style={getPieTextStyle(j += 1)}
>
{elem.name}
</pre>
</div>
))}
</div>
</div>
);
});
export default PieDisplay;
CSS:
.background {
position: relative;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: var(--white);
font-size: 48px;
width: 320px;
height: 320px;
padding: 20px;
border-radius: 50rem;
box-shadow: 0px 0px 30px 10px rgba(255, 255, 255, 0.2) inset, 0px 0px 30px 10px rgba(255, 255, 255, 0.2);
}
.pie-parent {
position: absolute;
box-shadow: 0px 0px 30px 10px rgba(255, 255, 255, 0.2) inset, 0px 0px 30px 10px rgba(255, 255, 255, 0.2);
padding: 0;
margin: 1em auto;
width: 225%;
height: 225%;
border-radius: 50%;
overflow: hidden;
}
.pie-button {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 50%;
transform-origin: 0% 100%;
z-index: 2;
}
.pie-button--text {
position: absolute;
left: -100%;
width: 200%;
height: 200%;
text-align: center;
padding-top: 50px;
}
.pie-button:hover {
background-color: grey;
cursor: pointer;
}
.pie-button:nth-child(1) {
background-color: red;
}
.pie-button:nth-child(2) {
background-color: blue;
}
.pie-button:nth-child(3) {
background-color: yellow;
}
.pie-button:nth-child(4) {
background-color: green;
}
Test Data:
export const dataFlow = [
{
name: 'Contact',
},
{
name: 'About',
},
{
name: 'Projects',
items: [
{
name: "Test1",
},
{
name: 'Test2',
},
{
name: 'Test3',
},
{
name: 'Test4',
},
{
name: 'Test5'
},
]
},
{
name: "Professional\nExperience",
items: [
{
name: 'Test1',
},
{
name: 'Test2',
},
{
name: 'Test3',
}
]
},
];
Solution 1:[1]
I want to redirect the user to the login page after being inactive for 5 minutes
If you use Cookie Authentication, you can specify the ExpiresUtc property to set the time at which the authentication ticket expires. Then use js to judge if user is inactive for 5 minutes, afterwards reload the page. At that time the cookie has been expired and it will redirect to the login page when reload the page.
Here is a whole working demo you could follow:
1.AccountController:
[HttpGet]
public async Task<IActionResult> Login()
{
return View(); //render the login page
}
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,model.Name),
new Claim("Password",model.Password)
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(5),//set valid period of cookie
IsPersistent = false,
AllowRefresh = false
});
return RedirectToAction("Index","Home");
}
2.HomeController:
[Authorize]
public async Task<IActionResult> Index()
{
return View();
}
When you send request to /Home/Index, it will redirect to /Account/Login page and you need enter the name and password to login.
3.In the Startup.ConfigureServices method, create the Authentication Middleware services with the AddAuthentication and AddCookie methods:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, m =>
{
m.LoginPath = "/Account/Login"; //specify the login url
m.AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("");
m.SlidingExpiration = true;
});
}
4.In Startup.Configure, call the UseAuthentication and UseAuthorization methods before calling UseEndpoints:
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
5.Set the refresh time in authorized page(Home/Index.cshtml):
@section Scripts{
<script >
window.document.onmouseover = function () { oldTime = new Date().getTime(); }
var oldTime = new Date().getTime();
var currentTime;
var timeOut = 300000;//refresh time
$(function () {
$(document).mouseover(function () {
oldTime = new Date().getTime();
});
});
function refresh() {
currentTime = new Date().getTime();
if (currentTime - oldTime > timeOut) {
location.reload();
}
}
window.setInterval(refresh,1000)
</script>
}
If your application contains many authorized pages, you can move the js code to external js file and add the reference to the authorized page.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rena |
