title page + fav
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-01 10:29:00 +03:30
parent 9d8dd549dc
commit da0069f2bc
10 changed files with 270 additions and 268 deletions
+2 -2
View File
@@ -2,9 +2,9 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/fav.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dpage-editor</title> <title>کاتالوگ دیجیتال | داناک</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+10
View File
@@ -0,0 +1,10 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_13784_19054)">
<path d="M4 14.1001V10.0001C4.4 10.0001 4.9 9.90006 5.3 9.90006H17.7C23.9 9.90006 28.2 14.3001 28.1 20.2001C28.1 25.9001 23.6 30.2001 17.6 30.3001H8.3V33.8001C13.4 33.4001 19.7 34.9001 24.6 31.9001C29.3 29.0001 32.7 22.3001 31.3 17.2001C29.8 11.5001 24 6.70006 18.2 6.60006H4V2.00006H13.3C16.1425 1.91726 18.9868 2.08457 21.8 2.50006C25.8647 3.32115 29.5123 5.54253 32.1072 8.77703C34.7021 12.0115 36.0798 16.0541 36 20.2001C35.7 29.0001 29.5 36.5001 20.9 37.5001C15.4 38.1001 9.8 37.6001 4.1 37.6001V17.4001H8.2V25.6001C11.8 25.6001 16.2 25.9001 19.6 25.6001C21.9 25.3001 24.1 21.8001 23.8 19.2001C23.5353 17.8626 22.8484 16.6454 21.8403 15.7273C20.8323 14.8093 19.5563 14.2389 18.2 14.1001H4Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_13784_19054">
<rect width="32" height="35.8" fill="white" transform="translate(4 2)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 993 B

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

+30 -88
View File
@@ -1,91 +1,33 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 229.9 36.8">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <defs>
viewBox="0 0 961.6 222.5" style="enable-background:new 0 0 961.6 222.5;" xml:space="preserve"> <style>
<style type="text/css"> .cls-1 {
.st0{fill:#1D1D1B;} fill: #000;
</style> }
<g>
.cls-1, .cls-2 {
stroke-width: 0px;
}
.cls-2 {
fill: #231f20;
}
</style>
</defs>
<polygon class="cls-2" points="129.6 6.2 140.6 36.2 145.4 36.2 131.7 .4 127.6 .4 113.9 36.2 118.8 36.2 129.6 6.2"/>
<path class="cls-2" d="M64.8,20.1h-12.1v-3.8h12.1v3.8Z"/>
<path class="cls-1" d="M10.1,12.5v-4.1c.4,0,.9-.1,1.3-.1,4.1,0,8.3,0,12.4,0,6.2,0,10.5,4.4,10.4,10.3,0,5.7-4.5,10-10.5,10.1-2.7,0-6.5,0-9.3,0v3.5c5.1-.4,11.4,1.1,16.3-1.9,4.7-2.9,8.1-9.6,6.7-14.7-1.5-5.7-7.3-10.5-13.1-10.6-4.1,0-8.2,0-12.2,0-.6,0-1.3,0-2,0V.4c3.1,0,6.2,0,9.3,0,2.8,0,5.7,0,8.5.5,8.4,1.6,14.4,9.3,14.2,17.7-.3,8.8-6.5,16.3-15.1,17.3-5.5.6-11.1.1-16.8.1V15.8h4.1v8.2c3.6,0,8,.3,11.4,0,2.3-.3,4.5-3.8,4.2-6.4s-3.1-5-5.6-5.1c-4,0-8,0-12.1,0-.6,0-1.3,0-2,0Z"/>
<path class="cls-1" d="M5.2,36.1H.1v-1.7c0-.6.1-1,.3-1.2.2-.3.6-.4,1-.4s.4,0,.6.2c.2.1.3.3.4.6,0-.3.2-.5.4-.7.2-.2.5-.2.8-.2.5,0,.8.1,1.1.4s.4.7.4,1.3v1.8ZM2.3,35.5v-1c0-.3,0-.5-.2-.7-.1-.2-.3-.3-.6-.3s-.5,0-.6.2c-.1.2-.2.4-.2.7v1h1.6ZM2.8,35.5h1.8v-1.1c0-.3,0-.6-.2-.7-.2-.2-.4-.3-.7-.3-.6,0-.9.3-.9,1v1.1Z"/>
<path class="cls-1" d="M2.7,29.9l-2.6-1.3v-.8l3.2,1.8h1.9v.7h-1.9l-3.2,1.8v-.8l2.6-1.3Z"/>
<path class="cls-1" d="M5.1,24.7H0v-1.4c0-.4,0-.8.3-1.2.2-.3.5-.6.8-.8.4-.2.8-.3,1.2-.3h.3c.5,0,.9,0,1.3.3s.6.5.8.8c.2.3.3.7.3,1.2v1.4ZM.6,24h4v-.7c0-.5-.2-.9-.5-1.2-.3-.3-.8-.4-1.4-.4h-.3c-.6,0-1,.1-1.4.4-.3.3-.5.7-.5,1.2v.8Z"/>
<path class="cls-1" d="M5.1,10.6v.7l-3.9,2.6h3.9v.7H0v-.7l4-2.6H0v-.7h5.1Z"/>
<path class="cls-1" d="M2.7,2.6l.6.6h1.7v.7H0v-.7h2.5L0,1V.2l2.3,2L5.1,0v.8l-2.4,1.8Z"/>
<polygon class="cls-1" points=".8 17.9 5.1 16.3 5.1 15.6 0 17.6 0 18.2 5.1 20.1 5.1 19.4 .8 17.9"/>
<polygon class="cls-1" points=".8 7.3 5.1 5.8 5.1 5.1 0 7 0 7.6 5.1 9.6 5.1 8.9 .8 7.3"/>
<g> <g>
<g> <path class="cls-2" d="M82.1,22.3v14h-4.7V.5h13.2c3.9,0,7,1,9.2,3,2.2,2,3.3,4.6,3.3,7.9s-1.1,6.1-3.3,8c-2.2,1.9-5.3,2.8-9.3,2.8h-8.4ZM82.1,18.4h8.5c2.5,0,4.5-.6,5.8-1.8,1.3-1.2,2-2.9,2-5.2s-.7-3.8-2-5.1c-1.3-1.3-3.2-1.9-5.5-2h-8.7v14.1Z"/>
<g> <path class="cls-2" d="M187.8,31.6c-1.2,1.7-2.9,3-5.1,3.9-2.2.9-4.7,1.3-7.6,1.3s-5.5-.7-7.8-2.1c-2.3-1.4-4-3.3-5.2-5.8s-1.9-5.4-1.9-8.8v-3.1c0-5.4,1.3-9.6,3.8-12.5,2.5-3,6-4.4,10.6-4.4s6.7,1,9,2.9c2.3,1.9,3.7,4.6,4.2,8.1h-4.7c-.9-4.8-3.7-7.1-8.5-7.1s-5.6,1.1-7.2,3.3c-1.6,2.2-2.5,5.4-2.5,9.7v2.9c0,4,.9,7.2,2.8,9.6,1.8,2.4,4.3,3.6,7.4,3.6s3.3-.2,4.6-.6c1.3-.4,2.4-1.1,3.3-2v-8h-8.3v-3.9h13v13.1Z"/>
<path class="st0" d="M246,180.4h-8.7v24.3h-3.6v-24.3H225v-2.9h21V180.4z"/> <path class="cls-2" d="M227.4,19.7h-15.5v12.7h18v3.9h-22.7V.5h22.5v3.9h-17.8v11.5h15.5v3.9Z"/>
<path class="st0" d="M279.1,205c-2.7,0-5-0.9-6.7-2.7s-2.6-4.2-2.6-7.2v-0.6c0-2,0.4-3.8,1.1-5.4s1.8-2.8,3.2-3.7
s2.9-1.3,4.5-1.3c2.6,0,4.7,0.9,6.1,2.6c1.5,1.7,2.2,4.2,2.2,7.4v1.4h-13.7c0,2,0.6,3.6,1.7,4.8s2.5,1.8,4.2,1.8
c1.2,0,2.3-0.2,3.1-0.7s1.6-1.2,2.2-2l2.1,1.6C285,203.7,282.5,205,279.1,205z M278.7,186.9c-1.4,0-2.6,0.5-3.5,1.5
s-1.5,2.4-1.8,4.3h10.1v-0.3c-0.1-1.8-0.6-3.1-1.4-4.1C281.3,187.4,280.1,186.9,278.7,186.9z"/>
<path class="st0" d="M320.4,202.2c1.2,0,2.3-0.4,3.2-1.1c0.9-0.7,1.4-1.7,1.5-2.8h3.3c-0.1,1.2-0.5,2.3-1.2,3.3
s-1.7,1.9-2.9,2.5c-1.2,0.6-2.5,0.9-3.9,0.9c-2.8,0-4.9-0.9-6.6-2.8c-1.6-1.8-2.4-4.3-2.4-7.5v-0.6c0-2,0.4-3.7,1.1-5.2
s1.8-2.7,3.1-3.6c1.4-0.8,2.9-1.3,4.8-1.3c2.3,0,4.1,0.7,5.6,2c1.5,1.4,2.3,3.1,2.4,5.3h-3.3c-0.1-1.3-0.6-2.4-1.5-3.2
s-2-1.3-3.3-1.3c-1.8,0-3.1,0.6-4.1,1.9s-1.4,3.1-1.4,5.5v0.7c0,2.3,0.5,4.1,1.4,5.4C317.2,201.6,318.6,202.2,320.4,202.2z"/>
<path class="st0" d="M357,186.9c1.5-1.9,3.5-2.8,6-2.8c4.3,0,6.4,2.4,6.5,7.2v13.4H366v-13.4c0-1.5-0.3-2.5-1-3.2s-1.7-1-3.1-1
c-1.1,0-2.1,0.3-3,0.9s-1.5,1.4-2,2.4v14.4h-3.4v-28.7h3.5V186.9z"/>
<path class="st0" d="M399.1,184.5l0.1,2.5c1.5-1.9,3.6-2.9,6.1-2.9c4.3,0,6.4,2.4,6.5,7.2v13.4h-3.5v-13.4c0-1.5-0.3-2.5-1-3.2
s-1.7-1-3.1-1c-1.1,0-2.1,0.3-3,0.9s-1.5,1.4-2,2.4v14.4h-3.5v-20.2h3.4V184.5z"/>
<path class="st0" d="M437.3,194.4c0-2,0.4-3.8,1.2-5.3c0.8-1.6,1.9-2.8,3.2-3.7s3-1.3,4.8-1.3c2.8,0,5,1,6.7,2.9
s2.5,4.4,2.5,7.6v0.2c0,2-0.4,3.7-1.1,5.3s-1.8,2.8-3.2,3.7c-1.4,0.9-3,1.3-4.8,1.3c-2.7,0-5-1-6.7-2.9s-2.5-4.4-2.5-7.6v-0.2
H437.3z M440.8,194.8c0,2.2,0.5,4,1.6,5.4c1,1.4,2.4,2,4.2,2c1.8,0,3.1-0.7,4.2-2.1s1.6-3.3,1.6-5.8c0-2.2-0.5-4-1.6-5.4
s-2.5-2.1-4.2-2.1s-3.1,0.7-4.1,2C441.3,190.3,440.8,192.3,440.8,194.8z"/>
<path class="st0" d="M485.1,204.7h-3.5V176h3.5V204.7z"/>
<path class="st0" d="M511,194.4c0-2,0.4-3.8,1.2-5.3c0.8-1.5,1.9-2.8,3.2-3.7c1.4-0.9,3-1.3,4.8-1.3c2.8,0,5,1,6.7,2.9
s2.5,4.4,2.5,7.6v0.2c0,2-0.4,3.7-1.1,5.3s-1.8,2.8-3.2,3.7s-3,1.3-4.8,1.3c-2.7,0-5-1-6.7-2.9c-1.7-1.9-2.5-4.4-2.5-7.6v-0.2
H511z M514.4,194.8c0,2.2,0.5,4,1.6,5.4c1,1.4,2.4,2,4.2,2s3.2-0.7,4.2-2.1c1-1.4,1.5-3.3,1.5-5.8c0-2.2-0.5-4-1.6-5.4
s-2.5-2.1-4.2-2.1s-3.1,0.7-4.1,2C515,190.3,514.4,192.3,514.4,194.8z"/>
<path class="st0" d="M554.1,194.4c0-3.2,0.7-5.7,2.2-7.5s3.4-2.8,5.8-2.8c2.5,0,4.4,0.9,5.8,2.6l0.2-2.2h3.2v19.7
c0,2.6-0.8,4.7-2.3,6.2c-1.6,1.5-3.6,2.3-6.2,2.3c-1.5,0-2.9-0.3-4.3-0.9c-1.4-0.6-2.5-1.5-3.2-2.6l1.8-2.1
c1.5,1.8,3.3,2.7,5.4,2.7c1.7,0,3-0.5,3.9-1.4s1.4-2.3,1.4-4v-1.7c-1.4,1.6-3.3,2.4-5.7,2.4s-4.3-1-5.7-2.9
S554.1,197.7,554.1,194.4z M557.6,194.8c0,2.3,0.5,4.1,1.4,5.4c0.9,1.3,2.2,2,3.9,2c2.2,0,3.8-1,4.8-3V190
c-1.1-1.9-2.6-2.9-4.8-2.9c-1.7,0-3,0.7-3.9,2C558.1,190.3,557.6,192.2,557.6,194.8z"/>
<path class="st0" d="M604.3,199.6l4.7-15.1h3.7l-8.1,23.3c-1.3,3.4-3.3,5-6,5l-0.7-0.1l-1.3-0.2v-2.8l0.9,0.1
c1.2,0,2.1-0.2,2.7-0.7c0.7-0.5,1.2-1.3,1.6-2.6l0.8-2.1l-7.2-20h3.8L604.3,199.6z"/>
<path class="st0" d="M688.3,196c-0.3,2.9-1.4,5.1-3.2,6.7c-1.8,1.6-4.2,2.3-7.1,2.3c-3.2,0-5.8-1.2-7.7-3.5s-2.9-5.4-2.9-9.2
v-2.6c0-2.5,0.5-4.8,1.4-6.7s2.2-3.4,3.8-4.4s3.6-1.5,5.8-1.5c2.9,0,5.2,0.8,6.9,2.4c1.7,1.6,2.8,3.8,3,6.7h-3.6
c-0.3-2.2-1-3.7-2-4.7s-2.5-1.5-4.4-1.5c-2.3,0-4.1,0.8-5.4,2.5c-1.3,1.7-2,4.1-2,7.2v2.6c0,3,0.6,5.3,1.8,7s3,2.6,5.2,2.6
c2,0,3.5-0.5,4.6-1.4s1.8-2.5,2.1-4.7h3.7V196z"/>
<path class="st0" d="M713,194.4c0-2,0.4-3.8,1.2-5.3s1.9-2.8,3.2-3.7c1.4-0.9,3-1.3,4.8-1.3c2.8,0,5,1,6.7,2.9s2.5,4.4,2.5,7.6
v0.2c0,2-0.4,3.7-1.1,5.3s-1.8,2.8-3.2,3.7s-3,1.3-4.8,1.3c-2.7,0-5-1-6.7-2.9s-2.5-4.4-2.5-7.6v-0.2H713z M716.5,194.8
c0,2.2,0.5,4,1.6,5.4c1,1.4,2.4,2,4.2,2s3.2-0.7,4.2-2.1c1-1.4,1.5-3.3,1.5-5.8c0-2.2-0.5-4-1.6-5.4s-2.5-2.1-4.2-2.1
s-3.1,0.7-4.1,2C717,190.3,716.5,192.3,716.5,194.8z"/>
<path class="st0" d="M760.3,184.5l0.1,2.2c1.5-1.7,3.5-2.6,6-2.6c2.8,0,4.8,1.1,5.8,3.2c0.7-1,1.5-1.8,2.6-2.4
c1.1-0.6,2.4-0.9,3.8-0.9c4.4,0,6.7,2.3,6.8,7v13.5h-3.5v-13.3c0-1.4-0.3-2.5-1-3.2s-1.8-1.1-3.3-1.1c-1.3,0-2.3,0.4-3.2,1.1
c-0.8,0.8-1.3,1.8-1.5,3.1v13.4h-3.5v-13.2c0-2.9-1.4-4.4-4.3-4.4c-2.3,0-3.8,1-4.7,2.9v14.8h-3.5v-20.2h3.4V184.5z"/>
<path class="st0" d="M828.9,194.8c0,3.1-0.7,5.6-2.1,7.4c-1.4,1.9-3.3,2.8-5.7,2.8c-2.5,0-4.4-0.8-5.8-2.3v9.7h-3.5v-28h3.2
l0.2,2.2c1.4-1.7,3.4-2.6,5.9-2.6c2.4,0,4.3,0.9,5.8,2.7c1.4,1.8,2.1,4.4,2.1,7.6v0.5H828.9z M825.5,194.4
c0-2.3-0.5-4.1-1.5-5.4c-1-1.3-2.3-2-4-2c-2.1,0-3.7,0.9-4.7,2.8v9.7c1,1.8,2.6,2.8,4.7,2.8c1.7,0,3-0.7,4-2
S825.5,197,825.5,194.4z"/>
<path class="st0" d="M867,204.7c-0.2-0.4-0.4-1.1-0.5-2.1c-1.6,1.7-3.5,2.5-5.8,2.5c-2,0-3.6-0.6-4.9-1.7s-1.9-2.6-1.9-4.3
c0-2.1,0.8-3.7,2.4-4.9c1.6-1.2,3.9-1.7,6.8-1.7h3.4v-1.7c0-1.2-0.4-2.2-1.1-2.9c-0.7-0.7-1.8-1.1-3.2-1.1
c-1.2,0-2.3,0.3-3.1,0.9c-0.8,0.6-1.3,1.4-1.3,2.3h-3.5c0-1,0.4-2,1.1-2.9c0.7-0.9,1.7-1.7,2.9-2.2s2.6-0.8,4-0.8
c2.3,0,4.2,0.6,5.5,1.7c1.3,1.2,2,2.8,2.1,4.8v9.3c0,1.9,0.2,3.3,0.7,4.4v0.3H867V204.7z M861.3,202c1.1,0,2.1-0.3,3.1-0.8
c1-0.6,1.7-1.3,2.1-2.2v-4.1h-2.7c-4.2,0-6.4,1.2-6.4,3.7c0,1.1,0.4,1.9,1.1,2.5C859.2,201.7,860.2,202,861.3,202z"/>
<path class="st0" d="M899.9,184.5l0.1,2.5c1.5-1.9,3.6-2.9,6.1-2.9c4.3,0,6.4,2.4,6.5,7.2v13.4h-3.5v-13.4c0-1.5-0.3-2.5-1-3.2
s-1.7-1-3.1-1c-1.1,0-2.1,0.3-3,0.9s-1.5,1.4-2,2.4v14.4h-3.5v-20.2h3.4V184.5z"/>
<path class="st0" d="M945.6,199.6l4.7-15.1h3.7l-8.1,23.3c-1.3,3.4-3.3,5-6,5l-0.7-0.1l-1.3-0.2v-2.8l0.9,0.1
c1.2,0,2.1-0.2,2.7-0.7c0.7-0.5,1.2-1.3,1.6-2.6l0.8-2.1l-7.2-20h3.8L945.6,199.6z"/>
</g> </g>
</g>
<path class="st0" d="M221.6,148.7V44.1h29.5c9.1,0,17.1,2,24.1,6s12.4,9.7,16.2,17.2c3.8,7.4,5.7,15.9,5.8,25.6v6.7
c0,9.9-1.9,18.5-5.7,25.9c-3.8,7.4-9.2,13.1-16.3,17.1c-7.1,4-15.3,6-24.7,6.1L221.6,148.7L221.6,148.7z M235.4,55.4v82h14.5
c10.6,0,18.9-3.3,24.8-9.9c5.9-6.6,8.9-16,8.9-28.3v-6.1c0-11.9-2.8-21.1-8.4-27.7s-13.5-9.9-23.7-10L235.4,55.4L235.4,55.4z"/>
<path class="st0" d="M627.1,148.7h-13.9l-52.7-80.6v80.6h-13.9V44.1h13.9l52.8,81v-81H627v104.6H627.1z"/>
<path class="st0" d="M900.9,100.1l-12.8,13.3v35.3h-13.8V44.1h13.8v51.7l46.5-51.7h16.7l-41.2,46.2l44.4,58.4H938L900.9,100.1z"/>
<polygon class="st0" points="423.2,61.1 455.1,148.7 469.2,148.7 429.2,44.1 417.1,44.1 377.2,148.7 391.4,148.7 "/>
<polygon class="st0" points="750.6,61.1 782.6,148.7 796.7,148.7 756.7,44.1 744.6,44.1 704.7,148.7 718.9,148.7 "/>
</g>
<path class="st0" d="M132.1,140.4c0,0-26.1,25.2-48,46.5v28.9c-2.2,1.7,77.6-75.4,77.6-75.4L84.1,59v31L132.1,140.4z"/>
<g>
<polygon class="st0" points="83.7,157.5 6.5,75.1 7.5,74.2 84.7,156.6 "/>
<polygon class="st0" points="83.7,149.8 13.6,75.2 14.6,74.3 84.6,148.9 "/>
<polygon class="st0" points="83.7,142.1 20.7,75.4 21.7,74.4 84.6,141.1 "/>
<polygon class="st0" points="83.6,134.3 27.8,75.5 28.7,74.6 84.6,133.4 "/>
<polygon class="st0" points="83.6,126.6 34.9,75.6 35.8,74.7 84.6,125.7 "/>
</g>
<g>
<polygon class="st0" points="8,75.5 7.1,74.5 83.7,0 84.6,0.9 "/>
<polygon class="st0" points="15.2,75.5 14.3,74.6 83.6,7 84.5,7.9 "/>
<polygon class="st0" points="22.4,75.6 21.4,74.7 83.6,14 84.5,14.9 "/>
<polygon class="st0" points="29.5,75.6 28.6,74.7 83.5,21 84.4,22 "/>
<polygon class="st0" points="36.7,75.7 35.7,74.8 83.5,28 84.4,29 "/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

+14
View File
@@ -0,0 +1,14 @@
import { useEffect } from 'react'
export const DEFAULT_PAGE_TITLE = 'کاتالوگ دیجیتال | داناک'
const BRAND_SUFFIX = ' | داناک'
export function formatPageTitle(pageTitle: string): string {
return `${pageTitle}${BRAND_SUFFIX}`
}
export function usePageTitle(pageTitle: string) {
useEffect(() => {
document.title = formatPageTitle(pageTitle)
}, [pageTitle])
}
+2
View File
@@ -1,10 +1,12 @@
import GridWrapper from "@/components/GridWrapper"; import GridWrapper from "@/components/GridWrapper";
import { usePageTitle } from "@/hooks/usePageTitle";
import { type FC } from "react"; import { type FC } from "react";
import { useGetCatalog } from "../home/hooks/useHomeData"; import { useGetCatalog } from "../home/hooks/useHomeData";
import ButtonAddCatalogue from "./components/ButtonAddCatalogue"; import ButtonAddCatalogue from "./components/ButtonAddCatalogue";
import CatalogueItem from "./components/CatalogueItem"; import CatalogueItem from "./components/CatalogueItem";
const CatalogueList: FC = () => { const CatalogueList: FC = () => {
usePageTitle("لیست کاتالوگ‌ها");
const { data, refetch } = useGetCatalog(); const { data, refetch } = useGetCatalog();
return ( return (
+2
View File
@@ -1,3 +1,4 @@
import { usePageTitle } from '@/hooks/usePageTitle'
import { useMemo, useState, type FC } from 'react' import { useMemo, useState, type FC } from 'react'
import Button from '@/components/Button' import Button from '@/components/Button'
import DatePicker from '@/components/DatePicker' import DatePicker from '@/components/DatePicker'
@@ -17,6 +18,7 @@ const pageCountOptions = Array.from({ length: 20 }, (_, index) => {
}) })
const DesignerRequest: FC = () => { const DesignerRequest: FC = () => {
usePageTitle('درخواست طراحی')
const [catalogTitle, setCatalogTitle] = useState('') const [catalogTitle, setCatalogTitle] = useState('')
const [, setDeliveryDate] = useState('') const [, setDeliveryDate] = useState('')
const [pageCount, setPageCount] = useState('1') const [pageCount, setPageCount] = useState('1')
+86 -63
View File
@@ -1,102 +1,125 @@
import { type FC, useEffect, useRef, useState } from 'react' import { clx } from "@/helpers/utils";
import Konva from 'konva' import { usePageTitle } from "@/hooks/usePageTitle";
import { clx } from '@/helpers/utils' import Konva from "konva";
import EditorSidebar from './components/EditorSidebar' import { type FC, useEffect, useRef, useState } from "react";
import EditorCanvas from './components/EditorCanvas' import { useParams } from "react-router-dom";
import LayersPanel from './components/LayersPanel' import { useGetCatalogById, useUpdateCatalog } from "../home/hooks/useHomeData";
import { useGetCatalogById, useUpdateCatalog } from '../home/hooks/useHomeData' import EditorCanvas from "./components/EditorCanvas";
import { useParams } from 'react-router-dom' import EditorSidebar from "./components/EditorSidebar";
import { useEditorStore } from './store/editorStore' import LayersPanel from "./components/LayersPanel";
import { useEditorStore } from "./store/editorStore";
const Editor: FC = () => { const Editor: FC = () => {
const { id } = useParams();
const { id } = useParams()
// Konva 10 با legacyTextRendering=false متن را با baseline جدید می‌کشد ولی getWidth/getHeight // Konva 10 با legacyTextRendering=false متن را با baseline جدید می‌کشد ولی getWidth/getHeight
// و کادر ترنسفورمر هنوز بر اساس جعبهٔ قدیمی‌اند؛ نتیجه: متن از کادر آبی بیرون می‌زند. // و کادر ترنسفورمر هنوز بر اساس جعبهٔ قدیمی‌اند؛ نتیجه: متن از کادر آبی بیرون می‌زند.
useEffect(() => { useEffect(() => {
const prev = Konva.legacyTextRendering const prev = Konva.legacyTextRendering;
Konva.legacyTextRendering = true Konva.legacyTextRendering = true;
return () => { return () => {
Konva.legacyTextRendering = prev Konva.legacyTextRendering = prev;
} };
}, []) }, []);
const [isLayersPanelOpen, setIsLayersPanelOpen] = useState(false) const [isLayersPanelOpen, setIsLayersPanelOpen] = useState(false);
const [isInitialContentReady, setIsInitialContentReady] = useState(false) const [isInitialContentReady, setIsInitialContentReady] = useState(false);
const loadedCatalogIdRef = useRef<string | null>(null) const loadedCatalogIdRef = useRef<string | null>(null);
const skipNextAutosaveRef = useRef(true) const skipNextAutosaveRef = useRef(true);
const { loadPages, resetEditor, pages, documentSettings, gallery, objects, currentPageId } = useEditorStore() const {
const { data, isFetched } = useGetCatalogById(id!) loadPages,
const { scheduleUpdate, cancelPendingUpdate, isSaving } = useUpdateCatalog() resetEditor,
pages,
documentSettings,
gallery,
objects,
currentPageId,
} = useEditorStore();
const { data, isFetched } = useGetCatalogById(id!);
const catalogName = data?.data?.name;
usePageTitle(
catalogName ? `ویرایش کاتالوگ ${catalogName}` : "ویرایش کاتالوگ",
);
const { scheduleUpdate, cancelPendingUpdate, isSaving } = useUpdateCatalog();
// هنگام تعویض کاتالوگ: لغو ذخیرهٔ معلق، پاک‌سازی store، و منتظر بارگذاری مجدد بمان // هنگام تعویض کاتالوگ: لغو ذخیرهٔ معلق، پاک‌سازی store، و منتظر بارگذاری مجدد بمان
useEffect(() => { useEffect(() => {
cancelPendingUpdate() cancelPendingUpdate();
loadedCatalogIdRef.current = null loadedCatalogIdRef.current = null;
skipNextAutosaveRef.current = true skipNextAutosaveRef.current = true;
setIsInitialContentReady(false) setIsInitialContentReady(false);
resetEditor() resetEditor();
}, [id, cancelPendingUpdate, resetEditor]) }, [id, cancelPendingUpdate, resetEditor]);
// بارگذاری محتوا فقط یک‌بار برای هر id (نه در هر refetch) // بارگذاری محتوا فقط یک‌بار برای هر id (نه در هر refetch)
useEffect(() => { useEffect(() => {
if (!id || !isFetched) return if (!id || !isFetched) return;
if (loadedCatalogIdRef.current === id) return if (loadedCatalogIdRef.current === id) return;
const rawContent = data?.data?.content const rawContent = data?.data?.content;
if (rawContent) { if (rawContent) {
try { try {
const json = JSON.parse(rawContent) const json = JSON.parse(rawContent);
if (Array.isArray(json)) { if (Array.isArray(json)) {
loadPages(json) loadPages(json);
} else if (json?.pages) { } else if (json?.pages) {
loadPages(json.pages, json.documentSettings, json.gallery) loadPages(json.pages, json.documentSettings, json.gallery);
} else { } else {
console.error('Invalid catalog content JSON: missing pages') console.error("Invalid catalog content JSON: missing pages");
return return;
} }
} catch (error) { } catch (error) {
console.error('Invalid catalog content JSON:', error) console.error("Invalid catalog content JSON:", error);
return return;
} }
} else { } else {
resetEditor() resetEditor();
} }
loadedCatalogIdRef.current = id loadedCatalogIdRef.current = id;
skipNextAutosaveRef.current = true skipNextAutosaveRef.current = true;
setIsInitialContentReady(true) setIsInitialContentReady(true);
}, [id, isFetched, data?.data?.content, loadPages, resetEditor]) }, [id, isFetched, data?.data?.content, loadPages, resetEditor]);
useEffect(() => { useEffect(() => {
if (!id) return if (!id) return;
if (!isInitialContentReady) return if (!isInitialContentReady) return;
if (!pages || pages.length === 0) return if (!pages || pages.length === 0) return;
if (skipNextAutosaveRef.current) { if (skipNextAutosaveRef.current) {
skipNextAutosaveRef.current = false skipNextAutosaveRef.current = false;
return return;
} }
const pagesToSave = currentPageId const pagesToSave = currentPageId
? pages.map((p) => ? pages.map((p) => (p.id === currentPageId ? { ...p, objects } : p))
p.id === currentPageId ? { ...p, objects } : p, : pages;
)
: pages
scheduleUpdate({ scheduleUpdate({
id, id,
content: JSON.stringify({ pages: pagesToSave, documentSettings, gallery }), content: JSON.stringify({
}) pages: pagesToSave,
documentSettings,
gallery,
}),
});
// عمداً scheduleUpdate را در وابستگی‌ها نیاوردیم تا از لوپ ذخیره‌سازی جلوگیری شود // عمداً scheduleUpdate را در وابستگی‌ها نیاوردیم تا از لوپ ذخیره‌سازی جلوگیری شود
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, isInitialContentReady, pages, documentSettings, gallery, objects, currentPageId]) }, [
id,
isInitialContentReady,
pages,
documentSettings,
gallery,
objects,
currentPageId,
]);
return ( return (
<div className={clx( <div
className={clx(
"flex h-full w-full", "flex h-full w-full",
isLayersPanelOpen ? "xl:pl-[296px]" : "xl:pl-[80px]" isLayersPanelOpen ? "xl:pl-[296px]" : "xl:pl-[80px]",
)}> )}
>
{isSaving ? ( {isSaving ? (
<div className="fixed bottom-10 left-10 z-50 rounded-full shadow-sm"> <div className="fixed bottom-10 left-10 z-50 rounded-full shadow-sm">
<div className="flex items-center gap-2 text-sm text-gray-700"> <div className="flex items-center gap-2 text-sm text-gray-700">
@@ -112,7 +135,7 @@ const Editor: FC = () => {
<EditorCanvas catalogSize={data?.data?.size} /> <EditorCanvas catalogSize={data?.data?.size} />
<EditorSidebar catalogSize={data?.data?.size} /> <EditorSidebar catalogSize={data?.data?.size} />
</div> </div>
) );
} };
export default Editor export default Editor;
+2
View File
@@ -1,4 +1,5 @@
import Divider from '@/components/Divider' import Divider from '@/components/Divider'
import { usePageTitle } from '@/hooks/usePageTitle'
import { ArrowLeft, DocumentText } from 'iconsax-react' import { ArrowLeft, DocumentText } from 'iconsax-react'
import { useState, type FC } from 'react' import { useState, type FC } from 'react'
import PdfIcon from '@/assets/images/PDF.svg' import PdfIcon from '@/assets/images/PDF.svg'
@@ -18,6 +19,7 @@ const CATALOG_SIZES = [
] as const ] as const
const Home: FC = () => { const Home: FC = () => {
usePageTitle('ساخت کاتالوگ')
const navigate = useNavigate() const navigate = useNavigate()
const [active, setActive] = useState<string>('a4') const [active, setActive] = useState<string>('a4')
+30 -22
View File
@@ -1,43 +1,47 @@
import { type FC, useEffect, useState } from 'react'; import { usePageTitle } from "@/hooks/usePageTitle";
import BookViewer from './components/BookViewer'; import type { DocumentSettings } from "@/pages/editor/store/editorStore";
import ViewerLoading from './components/ViewerLoading'; import { useGetCatalogById } from "@/pages/home/hooks/useHomeData";
import { transformViewerDataToPages } from './utils/dataTransformer'; import { type FC, useEffect, useState } from "react";
import type { PageData } from './types'; import { useParams } from "react-router-dom";
import type { DocumentSettings } from '@/pages/editor/store/editorStore'; import BookViewer from "./components/BookViewer";
import { useParams } from 'react-router-dom'; import ViewerLoading from "./components/ViewerLoading";
import { useGetCatalogById } from '@/pages/home/hooks/useHomeData'; import { useBrowserFullscreen } from "./hooks/useBrowserFullscreen";
import { useBrowserFullscreen } from './hooks/useBrowserFullscreen'; import { useInitialPagesPreload } from "./hooks/useInitialPagesPreload";
import { useInitialPagesPreload } from './hooks/useInitialPagesPreload'; import type { PageData } from "./types";
import { transformViewerDataToPages } from "./utils/dataTransformer";
const Viewer: FC = () => { const Viewer: FC = () => {
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
const { data, isLoading, error: queryError } = useGetCatalogById(id ?? ''); const { data, isLoading, error: queryError } = useGetCatalogById(id ?? "");
usePageTitle(`کاتالوگ ${data?.data?.name}`);
const [pages, setPages] = useState<PageData[]>([]); const [pages, setPages] = useState<PageData[]>([]);
const [documentSettings, setDocumentSettings] = useState<Partial<DocumentSettings> | undefined>(undefined); const [documentSettings, setDocumentSettings] = useState<
Partial<DocumentSettings> | undefined
>(undefined);
useEffect(() => { useEffect(() => {
if (!data?.data?.content || !id) return; if (!data?.data?.content || !id) return;
try { try {
const parsed = JSON.parse(data.data.content); const parsed = JSON.parse(data.data.content);
const pagesArray = Array.isArray(parsed) ? parsed : (parsed.pages ?? []); const pagesArray = Array.isArray(parsed) ? parsed : (parsed.pages ?? []);
const settings: Partial<DocumentSettings> | undefined = Array.isArray(parsed) const settings: Partial<DocumentSettings> | undefined = Array.isArray(
parsed,
)
? undefined ? undefined
: parsed.documentSettings; : parsed.documentSettings;
const transformedPages = transformViewerDataToPages( const transformedPages = transformViewerDataToPages({
{ pages: pagesArray } as Parameters<typeof transformViewerDataToPages>[0] pages: pagesArray,
); } as Parameters<typeof transformViewerDataToPages>[0]);
setPages(transformedPages); setPages(transformedPages);
setDocumentSettings(settings); setDocumentSettings(settings);
} catch (err) { } catch (err) {
console.error('خطا در پردازش محتوای کاتالوگ:', err); console.error("خطا در پردازش محتوای کاتالوگ:", err);
} }
}, [data?.data?.content, id]); }, [data?.data?.content, id]);
useBrowserFullscreen({ enabled: Boolean(id) }); useBrowserFullscreen({ enabled: Boolean(id) });
const { isReady: areInitialPagesReady, progress: preloadProgress } = useInitialPagesPreload( const { isReady: areInitialPagesReady, progress: preloadProgress } =
pages, useInitialPagesPreload(pages, documentSettings);
documentSettings,
);
if (!id) { if (!id) {
return ( return (
@@ -73,7 +77,11 @@ const Viewer: FC = () => {
return ( return (
<div className="w-full h-full min-h-0 flex flex-col"> <div className="w-full h-full min-h-0 flex flex-col">
<BookViewer pages={pages} catalogSize={data?.data?.size} documentSettings={documentSettings} /> <BookViewer
pages={pages}
catalogSize={data?.data?.size}
documentSettings={documentSettings}
/>
</div> </div>
); );
}; };