修正
This commit is contained in:
@@ -1,104 +1,228 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="ja">
|
<html lang="ja">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>給与管理 - 従業員管理</title>
|
<title>給与管理 - 従業員管理</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
<link rel="stylesheet" href="/css/style.css" />
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
<style>
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Noto Sans JP", Arial, sans-serif;
|
||||||
|
background: #f6f8fa;
|
||||||
|
color: #222;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 900px;
|
||||||
|
margin: 30px auto 40px auto;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 32px 24px 24px 24px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
color: #007bff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #0056b3;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 24px;
|
||||||
border-bottom: 2px solid #ddd;
|
border-bottom: 2px solid #e3e7ee;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.nav-tab {
|
.nav-tab {
|
||||||
padding: 10px 20px;
|
padding: 12px 32px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
background: #f0f0f0;
|
background: #e9f2ff;
|
||||||
border-radius: 5px 5px 0 0;
|
border-radius: 8px 8px 0 0;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #007bff;
|
||||||
|
transition:
|
||||||
|
background 0.2s,
|
||||||
|
color 0.2s;
|
||||||
}
|
}
|
||||||
.nav-tab.active {
|
.nav-tab.active {
|
||||||
background: #007bff;
|
background: #007bff;
|
||||||
color: white;
|
color: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.08);
|
||||||
|
}
|
||||||
|
.nav-tab:not(.active):hover {
|
||||||
|
background: #d0e6ff;
|
||||||
|
color: #0056b3;
|
||||||
}
|
}
|
||||||
.tab-content {
|
.tab-content {
|
||||||
display: none;
|
display: none;
|
||||||
|
animation: fadeIn 0.3s;
|
||||||
}
|
}
|
||||||
.tab-content.active {
|
.tab-content.active {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
.employee-list {
|
.employee-list {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
||||||
|
gap: 18px;
|
||||||
}
|
}
|
||||||
.employee-item {
|
.employee-item {
|
||||||
padding: 15px;
|
background: #fff;
|
||||||
border: 1px solid #ddd;
|
padding: 18px 16px;
|
||||||
margin-bottom: 10px;
|
border: 1px solid #e3e7ee;
|
||||||
border-radius: 5px;
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition:
|
||||||
|
box-shadow 0.2s,
|
||||||
|
border 0.2s,
|
||||||
|
background 0.2s;
|
||||||
}
|
}
|
||||||
.employee-item:hover {
|
.employee-item:hover {
|
||||||
background: #f9f9f9;
|
background: #f0f8ff;
|
||||||
|
border-color: #007bff;
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 123, 255, 0.08);
|
||||||
}
|
}
|
||||||
.form-group {
|
.form-group {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
.form-group label {
|
.form-group label {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 6px;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
|
color: #0056b3;
|
||||||
}
|
}
|
||||||
.form-group input,
|
.form-group input,
|
||||||
.form-group select,
|
.form-group select,
|
||||||
.form-group textarea {
|
.form-group textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
padding: 10px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #e3e7ee;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
|
font-size: 1rem;
|
||||||
|
background: #f8fbff;
|
||||||
|
transition: border 0.2s;
|
||||||
|
}
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-group select:focus,
|
||||||
|
.form-group textarea:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
outline: none;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
padding: 10px 20px;
|
padding: 10px 24px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition:
|
||||||
|
background 0.2s,
|
||||||
|
color 0.2s,
|
||||||
|
box-shadow 0.2s;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.06);
|
||||||
}
|
}
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background: #007bff;
|
background: linear-gradient(90deg, #007bff 0%, #0056b3 100%);
|
||||||
color: white;
|
color: #fff;
|
||||||
|
}
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: linear-gradient(90deg, #0056b3 0%, #007bff 100%);
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 123, 255, 0.12);
|
||||||
}
|
}
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
background: #6c757d;
|
background: #e3e7ee;
|
||||||
color: white;
|
color: #007bff;
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: #d0e6ff;
|
||||||
|
color: #0056b3;
|
||||||
}
|
}
|
||||||
.btn-danger {
|
.btn-danger {
|
||||||
background: #dc3545;
|
background: #dc3545;
|
||||||
color: white;
|
color: #fff;
|
||||||
|
}
|
||||||
|
.btn-danger:hover {
|
||||||
|
background: #b71c1c;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.filters {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
.dependent-list {
|
.dependent-list {
|
||||||
margin-top: 20px;
|
margin-top: 24px;
|
||||||
padding: 15px;
|
padding: 18px;
|
||||||
background: #f9f9f9;
|
background: #f8fbff;
|
||||||
border-radius: 5px;
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.04);
|
||||||
}
|
}
|
||||||
.dependent-item {
|
.dependent-item {
|
||||||
padding: 10px;
|
padding: 12px 10px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #e3e7ee;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background: white;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
||||||
|
}
|
||||||
|
.dependent-item strong {
|
||||||
|
color: #007bff;
|
||||||
}
|
}
|
||||||
.back-link {
|
.back-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 24px;
|
||||||
color: #007bff;
|
color: #007bff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 14px;
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: color 0.2s;
|
||||||
}
|
}
|
||||||
.back-link:hover {
|
.back-link:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
color: #0056b3;
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 12px 4px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
.nav-tabs {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
.employee-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -597,7 +721,7 @@
|
|||||||
async function uploadFileToServer(
|
async function uploadFileToServer(
|
||||||
file,
|
file,
|
||||||
employeeCode,
|
employeeCode,
|
||||||
fileType = "image"
|
fileType = "image",
|
||||||
) {
|
) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
@@ -609,7 +733,7 @@
|
|||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -676,10 +800,12 @@
|
|||||||
${emp.name_kana ? `(${emp.name_kana})` : ""}
|
${emp.name_kana ? `(${emp.name_kana})` : ""}
|
||||||
<br>
|
<br>
|
||||||
<small>入社日: ${emp.hire_date} ${
|
<small>入社日: ${emp.hire_date} ${
|
||||||
emp.termination_date ? ` | 退職日: ${emp.termination_date}` : ""
|
emp.termination_date
|
||||||
|
? ` | 退職日: ${emp.termination_date}`
|
||||||
|
: ""
|
||||||
}</small>
|
}</small>
|
||||||
</div>
|
</div>
|
||||||
`
|
`,
|
||||||
)
|
)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
@@ -719,7 +845,7 @@
|
|||||||
const filePath = await uploadFileToServer(
|
const filePath = await uploadFileToServer(
|
||||||
fileInput.files[0],
|
fileInput.files[0],
|
||||||
employeeCode,
|
employeeCode,
|
||||||
"image"
|
"image",
|
||||||
);
|
);
|
||||||
photoUploads[field] = filePath;
|
photoUploads[field] = filePath;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -783,7 +909,7 @@
|
|||||||
async function viewEmployee(employeeId) {
|
async function viewEmployee(employeeId) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${API_BASE}/payroll/employees/${employeeId}`
|
`${API_BASE}/payroll/employees/${employeeId}`,
|
||||||
);
|
);
|
||||||
const employee = await response.json();
|
const employee = await response.json();
|
||||||
currentEmployee = employee;
|
currentEmployee = employee;
|
||||||
@@ -805,10 +931,10 @@
|
|||||||
employee.my_number
|
employee.my_number
|
||||||
? `${employee.my_number.substring(
|
? `${employee.my_number.substring(
|
||||||
0,
|
0,
|
||||||
4
|
4,
|
||||||
)}-${employee.my_number.substring(
|
)}-${employee.my_number.substring(
|
||||||
4,
|
4,
|
||||||
8
|
8,
|
||||||
)}-${employee.my_number.substring(8, 12)}`
|
)}-${employee.my_number.substring(8, 12)}`
|
||||||
: "-"
|
: "-"
|
||||||
}</p>
|
}</p>
|
||||||
@@ -853,7 +979,7 @@
|
|||||||
<strong>マイナンバーカード</strong><br>
|
<strong>マイナンバーカード</strong><br>
|
||||||
<img src="${
|
<img src="${
|
||||||
employee.my_number_card_image_url.startsWith(
|
employee.my_number_card_image_url.startsWith(
|
||||||
"data:"
|
"data:",
|
||||||
)
|
)
|
||||||
? employee.my_number_card_image_url
|
? employee.my_number_card_image_url
|
||||||
: API_BASE + employee.my_number_card_image_url
|
: API_BASE + employee.my_number_card_image_url
|
||||||
@@ -869,7 +995,7 @@
|
|||||||
<strong>在留カード</strong><br>
|
<strong>在留カード</strong><br>
|
||||||
<img src="${
|
<img src="${
|
||||||
employee.residence_card_image_url.startsWith(
|
employee.residence_card_image_url.startsWith(
|
||||||
"data:"
|
"data:",
|
||||||
)
|
)
|
||||||
? employee.residence_card_image_url
|
? employee.residence_card_image_url
|
||||||
: API_BASE + employee.residence_card_image_url
|
: API_BASE + employee.residence_card_image_url
|
||||||
@@ -885,7 +1011,7 @@
|
|||||||
<strong>健康保険証</strong><br>
|
<strong>健康保険証</strong><br>
|
||||||
<img src="${
|
<img src="${
|
||||||
employee.health_insurance_card_image_url.startsWith(
|
employee.health_insurance_card_image_url.startsWith(
|
||||||
"data:"
|
"data:",
|
||||||
)
|
)
|
||||||
? employee.health_insurance_card_image_url
|
? employee.health_insurance_card_image_url
|
||||||
: API_BASE +
|
: API_BASE +
|
||||||
@@ -924,7 +1050,7 @@
|
|||||||
) {
|
) {
|
||||||
koureiCount = employee.dependents.filter((dep) => {
|
koureiCount = employee.dependents.filter((dep) => {
|
||||||
const taxStatus = getTaxDeductionStatus(
|
const taxStatus = getTaxDeductionStatus(
|
||||||
dep.birth_date
|
dep.birth_date,
|
||||||
);
|
);
|
||||||
// 源泉税控除対象は16歳以上(一般扶養親族16-18歳、特定扶養親族19-22歳、老人扶養親族70歳以上)
|
// 源泉税控除対象は16歳以上(一般扶養親族16-18歳、特定扶養親族19-22歳、老人扶養親族70歳以上)
|
||||||
return (
|
return (
|
||||||
@@ -950,7 +1076,7 @@
|
|||||||
? employee.dependents
|
? employee.dependents
|
||||||
.map((dep) => {
|
.map((dep) => {
|
||||||
const taxStatus = getTaxDeductionStatus(
|
const taxStatus = getTaxDeductionStatus(
|
||||||
dep.birth_date
|
dep.birth_date,
|
||||||
);
|
);
|
||||||
return `
|
return `
|
||||||
<div class="dependent-item">
|
<div class="dependent-item">
|
||||||
@@ -981,7 +1107,7 @@
|
|||||||
dep.valid_to || "現在"
|
dep.valid_to || "現在"
|
||||||
}</small>
|
}</small>
|
||||||
<button class="btn btn-primary" onclick='editDependent(${JSON.stringify(
|
<button class="btn btn-primary" onclick='editDependent(${JSON.stringify(
|
||||||
dep
|
dep,
|
||||||
)})' style="padding: 3px 8px; font-size: 11px; margin-left: 10px;">編集</button>
|
)})' style="padding: 3px 8px; font-size: 11px; margin-left: 10px;">編集</button>
|
||||||
<button class="btn btn-secondary" onclick="deleteDependent(${
|
<button class="btn btn-secondary" onclick="deleteDependent(${
|
||||||
dep.dependent_id
|
dep.dependent_id
|
||||||
@@ -1001,7 +1127,7 @@
|
|||||||
) {
|
) {
|
||||||
koureiCount = employee.dependents.filter((dep) => {
|
koureiCount = employee.dependents.filter((dep) => {
|
||||||
const taxStatus = getTaxDeductionStatus(
|
const taxStatus = getTaxDeductionStatus(
|
||||||
dep.birth_date
|
dep.birth_date,
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
taxStatus?.isDeductible &&
|
taxStatus?.isDeductible &&
|
||||||
@@ -1048,7 +1174,7 @@
|
|||||||
async function editEmployee(employeeId) {
|
async function editEmployee(employeeId) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${API_BASE}/payroll/employees/${employeeId}`
|
`${API_BASE}/payroll/employees/${employeeId}`,
|
||||||
);
|
);
|
||||||
const employee = await response.json();
|
const employee = await response.json();
|
||||||
currentEmployee = employee;
|
currentEmployee = employee;
|
||||||
@@ -1178,7 +1304,7 @@
|
|||||||
const filePath = await uploadFileToServer(
|
const filePath = await uploadFileToServer(
|
||||||
fileInput.files[0],
|
fileInput.files[0],
|
||||||
employeeCode,
|
employeeCode,
|
||||||
"image"
|
"image",
|
||||||
);
|
);
|
||||||
photoUploads[field] = filePath;
|
photoUploads[field] = filePath;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1214,7 +1340,7 @@
|
|||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@@ -1326,7 +1452,7 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@@ -1408,7 +1534,7 @@
|
|||||||
`${API_BASE}/payroll/employees/dependents/${dependentId}`,
|
`${API_BASE}/payroll/employees/dependents/${dependentId}`,
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@@ -1542,7 +1668,7 @@
|
|||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|||||||
Reference in New Issue
Block a user