feat: create PageLoader spinner component

This commit is contained in:
gnezim
2026-04-05 20:54:12 +03:00
parent 509e1afb20
commit 9ba5c9cbf0
3 changed files with 77 additions and 0 deletions
@@ -0,0 +1,2 @@
export { PageLoader } from './page-loader'
export type { PageLoaderProps } from './page-loader'
@@ -0,0 +1,33 @@
.page-loader {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.8);
z-index: 1000;
}
.page-loader__content {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
padding: 40px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.page-loader__message {
font-size: 16px;
color: #666;
margin: 0;
}
.page-loader__cancel {
margin-top: 10px;
}
@@ -0,0 +1,42 @@
import React from 'react'
import { ProgressSpinner } from 'primereact/progressspinner'
import { Button } from 'primereact/button'
import { useTranslation } from 'react-i18next'
import './page-loader.scss'
export interface PageLoaderProps {
isLoading: boolean
onCancel?: () => void
message?: string
}
export const PageLoader: React.FC<PageLoaderProps> = ({ isLoading, onCancel, message }) => {
const { t } = useTranslation()
if (!isLoading) {
return null
}
return (
<div className="page-loader" data-testid="page-loader">
<div className="page-loader__content">
<ProgressSpinner
style={{ width: '50px', height: '50px' }}
strokeWidth="4"
fill="var(--surface-ground)"
animationDuration=".5s"
/>
{message && <p className="page-loader__message">{message}</p>}
{onCancel && (
<Button
label={t('SHARED.CANCEL')}
severity="secondary"
onClick={onCancel}
data-testid="page-loader-cancel"
className="page-loader__cancel"
/>
)}
</div>
</div>
)
}