Commits (2)
<svg id="TRAVEL" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="0" x2="512.02" y1="256" y2="256"><stop offset="0" stop-color="#283451"/><stop offset=".6" stop-color="#384c6c"/><stop offset="1" stop-color="#465a77"/></linearGradient><path d="m362.83 228.31c-7.59-53.3-53.25-92.9-107.08-92.9s-99.99 39.99-107.19 93.63c0 0-1.26 9.34-1.46 19.06h-124.87l-7.64-53.39c-.33-3.77-3.49-6.66-7.27-6.66h-7.29v60.05h-.03v18.93c0 9.81 7.5 18 17.27 18.86l120.84 10.62c3.19.28 5.68 2.87 5.85 6.07v.05c1.43 26.33 21.96 51.78 47.44 57.6 15.65 3.31 35.29 5.62 64.89 5.67 29.61-.05 49.22-2.36 64.85-5.67 25.45-5.81 45.79-31.27 47.03-57.6 0-.02 0-.04 0-.05.14-3.19 2.6-5.79 5.79-6.07l120.79-10.62c9.77-.86 17.27-9.04 17.27-18.85v-18.93h-.03v-60.05h-7.29c-3.78 0-6.94 2.89-7.27 6.66l-7.64 53.39h-125.25c-.03-8.28-1.71-19.79-1.71-19.79zm-98.96-35.58c-.09-3.44 2.39-6.22 5.59-6.2 18.25.13 36.5.51 54.75 1.15 2.61.09 5.75 1.96 7.41 4.54 3.36 5.26 6.01 10.49 7.8 15.67 1.08 3.05-1.04 6.19-4.35 7.13-21.52 6.1-43.67 12.73-63.91 19.19-3.82 1.23-7.39-1.75-7.29-5.92.39-11.86.39-23.71 0-35.57zm-91.24 15.17c1.79-5.19 4.44-10.41 7.8-15.67 1.66-2.58 4.8-4.45 7.41-4.54 18.25-.64 36.5-1.02 54.75-1.15 3.2-.02 5.68 2.76 5.59 6.2-.39 11.86-.39 23.71 0 35.57.1 4.18-3.47 7.15-7.29 5.92-20.23-6.46-42.39-13.09-63.91-19.19-3.32-.94-5.43-4.09-4.35-7.13zm66.34-89.37 4.11-51.59c.56-7.06 6.46-12.51 13.54-12.51s12.98 5.45 13.54 12.51l4.13 51.85c-6.11-.91-12.3-1.38-18.55-1.38-5.64 0-11.24.38-16.77 1.12zm34.19 318.58c.04 3.92-.48 9.84-.91 11.96-.68 3.48-3.86 6.85-7.33 7.62-2.11.44-4.98.87-8.9.88-3.92 0-6.79-.44-8.9-.88-3.47-.77-6.66-4.14-7.33-7.62-.42-2.12-.95-8.04-.91-11.96-.04-3.92.48-9.84.91-11.96.68-3.48 3.86-6.85 7.33-7.62 1.05-.22 2.29-.43 3.75-.6v-37.15c0-1.99 1.61-3.6 3.6-3.6h3.1c1.99 0 3.6 1.61 3.6 3.6v37.15c1.46.16 2.7.38 3.75.6 3.47.77 6.66 4.14 7.33 7.62.42 2.12.95 8.04.91 11.96zm-48.23-32.57c.03 3.01-.37 7.57-.7 9.21-.52 2.68-2.97 5.27-5.64 5.87-1.62.34-3.83.67-6.85.67s-5.22-.34-6.85-.67c-2.67-.59-5.12-3.18-5.64-5.87-.33-1.63-.73-6.19-.7-9.21-.03-3.01.37-7.57.7-9.21.52-2.68 2.97-5.27 5.64-5.87.77-.16 1.68-.32 2.74-.44v-12.2c0-1.99 1.61-3.6 3.6-3.6h1.02c1.99 0 3.6 1.61 3.6 3.6v12.2c1.06.12 1.97.28 2.74.44 2.67.59 5.12 3.19 5.64 5.87.33 1.63.73 6.19.7 9.21zm88.56 0c.03 3.01-.37 7.57-.7 9.21-.52 2.68-2.97 5.27-5.64 5.87-1.62.34-3.83.67-6.85.67s-5.22-.34-6.85-.67c-2.67-.59-5.12-3.18-5.64-5.87-.33-1.63-.73-6.19-.7-9.21-.03-3.01.37-7.57.7-9.21.52-2.68 2.97-5.27 5.64-5.87.77-.16 1.68-.32 2.74-.44v-13.14c0-1.47 1.19-2.66 2.66-2.66h2.9c1.47 0 2.66 1.19 2.66 2.66v13.14c1.06.12 1.97.28 2.74.44 2.67.59 5.12 3.19 5.64 5.87.33 1.63.73 6.19.7 9.21zm-242.63-96.91c-23.42 0-42.4 18.98-42.4 42.4s18.98 42.4 42.4 42.4 42.4-18.98 42.4-42.4-18.98-42.4-42.4-42.4zm0 61.84c-10.73 0-19.43-8.7-19.43-19.43s8.7-19.44 19.43-19.44 19.43 8.7 19.43 19.44-8.7 19.43-19.43 19.43zm370.28-61.84c-23.42 0-42.4 18.98-42.4 42.4s18.98 42.4 42.4 42.4 42.4-18.98 42.4-42.4-18.98-42.4-42.4-42.4zm0 61.84c-10.73 0-19.43-8.7-19.43-19.43s8.7-19.44 19.43-19.44 19.43 8.7 19.43 19.44-8.7 19.43-19.43 19.43z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg id="TRAVEL" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="256" y2="256"><stop offset="0" stop-color="#ed6c14"/><stop offset=".6" stop-color="#ff9045"/><stop offset="1" stop-color="#ffb54a"/></linearGradient><path d="m105.04 328.91c27.89 0 50.49 22.61 50.49 50.49 0 27.89-22.61 50.49-50.49 50.49-27.89 0-50.49-22.61-50.49-50.49 0-27.89 22.61-50.49 50.49-50.49zm251.92 50.49c0 27.89 22.61 50.49 50.49 50.49 27.89 0 50.49-22.61 50.49-50.49s-22.61-50.49-50.49-50.49c-27.89 0-50.49 22.61-50.49 50.49zm117.47-139.24-3.76-32.85c-.72-6.26-6.38-10.76-12.64-10.04-6.26.72-10.76 6.38-10.04 12.64l3.76 32.85c.72 6.26 6.38 10.76 12.64 10.04 6.26-.72 10.76-6.38 10.04-12.64zm34.19 101.69c-3.12 19.19-15.24 26.29-33 30.87-3.37-34.64-32.65-61.81-68.16-61.81-37.77 0-68.49 30.73-68.49 68.49 0 4.92.53 9.71 1.52 14.34-25.41 1.05-49.83 1.67-65.18 1.52-15.64.16-73.17-.49-103.28-1.58.98-4.61 1.51-9.39 1.51-14.28 0-37.77-30.73-68.49-68.49-68.49-35.3 0-64.44 26.84-68.1 61.19-17.18-4.85-28.8-14.43-32.84-33.79-4-19.15-5.35-64.17-2.84-100.08 2.64-35.9 8.58-62.2 14.07-81.53 9.35-31.84 42.31-61.01 74.67-67.2 19.66-3.89 129.25-7.77 165.14-7.37 35.88-.4 170.56 4.41 190.25 8.3 32.43 6.19 43.43 34.43 53.11 66.27 5.68 19.33 9.12 45.63 12.12 81.53 2.87 35.9.79 84.28-2 103.61zm-369.06-170.84c0-6.05-4.94-10.93-10.98-10.86-6.39.07-31.32.15-37.71.23-8.75.12-18.64 5.58-22.46 12.96-8.33 18.1-12.11 36.16-10.74 54.15.21 9.49 12.86 18.4 24.2 18.57 9.39.13 37.32.24 46.71.35 6.05.07 10.99-4.81 10.99-10.86v-64.54zm112.96-.85c0-6.02-4.9-10.9-10.92-10.87-17.83.09-44.94.21-62.77.37-5.96.05-10.77 4.9-10.77 10.87v65.52c0 5.96 4.81 10.81 10.77 10.86 17.83.15 44.94.28 62.77.37 6.02.03 10.92-4.84 10.92-10.87v-66.26zm111.1-.2c0-5.99-4.85-10.86-10.85-10.86-17.83-.03-44.94-.02-62.77 0-5.99.01-10.84 4.88-10.84 10.87v66.62c0 5.99 4.85 10.85 10.84 10.87 17.83.04 44.94.04 62.77.01 5.99 0 10.85-4.87 10.85-10.86zm123.94 90.34c-1.54-30.6-4-57.01-13-89.05-.01-.04-.03-.08-.04-.12-2.51-6.88-10.13-11.51-18.62-11.58-16.7-.13-37.1-.22-53.8-.3-6.01-.03-10.9 4.84-10.9 10.86v66.37c0 .27 0 .54.03.8.31 4.24 3.37 7.78 7.41 9.09l74.22 23.96c3.51 1.13 7.42.7 10.43-1.44 2.86-2.04 4.58-5.18 4.27-8.59z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg id="TRAVEL" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="256" y2="256"><stop offset="0" stop-color="#cc3232"/><stop offset=".6" stop-color="#ef5a5a"/><stop offset="1" stop-color="#f47e67"/></linearGradient><path d="m404.82 313.19c27.47 0 49.73 22.27 49.73 49.73 0 27.47-22.27 49.73-49.73 49.73s-49.73-22.27-49.73-49.73c0-27.47 22.27-49.73 49.73-49.73zm-347.37 49.73c0 27.47 22.27 49.73 49.73 49.73s49.73-22.27 49.73-49.73c0-27.47-22.27-49.73-49.73-49.73-27.47 0-49.73 22.27-49.73 49.73zm-57.12-42.83c2.57-18.45 5.13-37.14 7.7-56.08 1.77-13 10.59-24.53 22.8-29.88 16.58-7.19 33.18-14.67 49.79-22.29 4.52-24.67 10.58-43 15.81-56.63 9.16-23.56 35.23-45.15 59.16-49.73 14.46-2.87 54.11-6.41 80.13-6.12 26.03-.29 65.62 3.21 80.04 6.04 23.86 4.49 49.63 25.65 58.47 48.74 4.85 12.83 10.4 29.91 14.53 52.68 28.48 9.69 56.92 19.42 85.32 28.68 12.67 4.18 22.49 15.19 25.32 28.27 3.92 18.21 7.85 36.09 11.77 53.6 4.73 20.8-11.45 42.9-33.29 45.62-1.74.19-3.48.37-5.23.55 0-.21.02-.43.02-.64 0-37.41-30.44-67.85-67.85-67.85s-67.85 30.44-67.85 67.85c0 3.58.28 7.1.82 10.53-54.5 2.18-109.07 2.18-163.57 0 .54-3.43.82-6.95.82-10.53 0-37.41-30.44-67.85-67.85-67.85s-67.85 30.44-67.85 67.85c0 .21.01.43.02.64-1.74-.19-3.49-.36-5.23-.55-20.71-2.54-36.62-22.79-33.78-42.91zm249.51-134.41c0 6.31 5.12 11.43 11.43 11.43h81.15c7.63 0 13.13-7.35 10.96-14.67-2.2-7.41-4.37-13.47-6.18-18.26-5.31-13.81-22.74-28.31-37.33-31.06l-.11-.02-.11-.02c-8.03-1.58-27.91-3.69-47.74-4.79-6.55-.36-12.07 4.85-12.07 11.41zm-122.78 11.42h79.54c6.31 0 11.43-5.12 11.43-11.43v-45.85c0-6.57-5.53-11.8-12.09-11.41-19.1 1.14-37.82 3.18-45.55 4.72l-.09.02-.09.02c-14.75 2.82-32.57 17.87-38.17 32.22-1.73 4.51-3.77 10.11-5.88 16.85-2.3 7.36 3.19 14.86 10.9 14.86z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg id="TIME_AND_DATE_GLYPH" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-name="TIME AND DATE GLYPH"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="17.33" x2="494.67" y1="256" y2="256"><stop offset="0" stop-color="#0caa0c"/><stop offset=".6" stop-color="#4bd14b"/><stop offset="1" stop-color="#60e260"/></linearGradient><path d="m25.29 158.12c.57-3.82 1.15-7.49 1.73-11 8.56-48.43 51.94-92.47 100.21-102.25v-19.62c0-13.94 11.3-25.24 25.24-25.24s25.24 11.3 25.24 25.24v12.92c15.71-1.47 33.3-2.6 53.04-3.15v-9.77c0-13.94 11.3-25.24 25.24-25.24 13.94 0 25.24 11.3 25.24 25.24v9.77c19.74.54 37.33 1.68 53.04 3.15v-12.92c0-13.94 11.3-25.24 25.24-25.24s25.24 11.3 25.24 25.24v19.62c48.27 9.78 91.65 53.82 100.21 102.25.58 3.46 1.15 7.08 1.71 10.84-197.7-13.79-391.9-4.2-461.39.17zm469.38 115.21c-.06 55.59-4.72 96.3-9.7 126.21-8.71 49.29-53.47 94.05-102.76 102.76-29.91 4.98-70.62 9.64-126.21 9.7-55.59-.06-96.3-4.72-126.21-9.7-49.29-8.71-94.06-53.47-102.76-102.76-4.98-29.91-9.63-70.62-9.7-126.21.03-29.64 1.37-55.04 3.37-76.83 62.07-4.07 265.33-15.04 470.59-.12 2 21.82 3.35 47.26 3.38 76.95zm-135.32-15.35c-12.53-11.94-32.37-11.45-44.3 1.09l-84.34 88.57-33.97-35c-12.06-12.43-31.89-12.72-44.3-.67-12.42 12.05-12.72 31.89-.67 44.31l56.68 58.4c5.9 6.08 14.01 9.51 22.49 9.51h.14c8.53-.04 16.67-3.56 22.54-9.73l106.82-112.17c11.94-12.54 11.45-32.38-1.09-44.3z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x2="512.09" y1="256" y2="256"><stop offset="0" stop-color="#cc3232"/><stop offset=".6" stop-color="#ef5a5a"/><stop offset="1" stop-color="#f47e67"/></linearGradient><g id="SECURITY_BLACK" data-name="SECURITY BLACK"><path d="m376.82 302.65c-1.82 21.44-4.07 39.77-6.17 50.31-8.29 42.61-46 81.7-87.72 90.94l-.24.05q-9.65 2-19.45 3.55c-7.73 35.66-33.24 60.05-61.37 57.5h-.18c-20.91-2.26-42.51-7.8-66.05-16.94a338.62 338.62 0 0 1 -66.11-34.71l-.17-.12c-29.76-20.58-56.65-69.08-62.56-112.81-1.2-8.68-2.45-22.16-3.55-37.66-2.06-24.17-3.45-51.37-3.25-72.83-.42-40 4.79-99.93 9.4-123 3.7-18.93 13.17-37.14 26.21-52.36a47.24 47.24 0 0 1 10.33-10.73c14.76-13.67 32.57-23.75 51.19-27.84l.25-.05c29.32-6.13 59.62-9.11 92.62-9.17s63.42 3 92.69 9.13l.24.05c41.73 9.24 79.43 48.33 87.72 90.94 2.1 10.52 4.34 28.81 6.16 50.2a19 19 0 0 1 -37.87 3.22c-1.68-19.78-3.76-37-5.57-46v-.11c-5.37-27.7-31.61-55.08-58.52-61.1-26.68-5.54-54.43-8.26-84.83-8.31a426.08 426.08 0 0 0 -66.7 5q6.08 2.09 12.29 4.5a338.2 338.2 0 0 1 66.08 34.7l.18.12c29.75 20.61 56.64 69.11 62.55 112.84 3.29 23.75 7 83.43 6.7 122.19.2 25.37-1.31 58.27-3.29 84 2.33-.44 4.67-.9 7-1.38 26.91-6 53.15-33.4 58.52-61.1v-.11c1.82-9.06 3.9-26.3 5.58-46.12a19 19 0 1 1 37.87 3.21zm135.27-72.75c0-.63 0-1.26-.1-1.89a.5.5 0 0 0 0-.12 17.39 17.39 0 0 0 -.27-1.76v-.13a18.9 18.9 0 0 0 -5.15-9.53l-68-68.06a19 19 0 0 0 -26.88 26.87l35.67 35.66h-131.17a19 19 0 0 0 0 38h131l-35.64 35.64a19 19 0 0 0 26.87 26.87l67.69-67.69a18.86 18.86 0 0 0 5.2-8.44 16.53 16.53 0 0 0 .42-1.75 2.17 2.17 0 0 0 0-.25c.09-.51.18-1 .23-1.54s0-.78 0-1.16c0-.22 0-.44 0-.66z" fill="url(#linear-gradient)"/></g></svg>
\ No newline at end of file
<svg id="TRAVEL" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="90.05" x2="421.95" y1="256" y2="256"><stop offset="0" stop-color="#0caa0c"/><stop offset=".6" stop-color="#4bd14b"/><stop offset="1" stop-color="#60e260"/></linearGradient><path d="m256.19 512h-.38c-21.22 0-38.43-17.21-38.43-38.43v-141.8c0-21.22 17.21-38.43 38.43-38.43h.38c21.22 0 38.43 17.21 38.43 38.43v141.8c0 21.22-17.21 38.43-38.43 38.43zm165.76-457.81c0 5.98-4.85 10.83-10.83 10.83h-49.34c-3.94 7.67-11.91 12.93-21.13 12.93h-22.87c-7.47 0-14.41 3.59-19 9.49-9.91 12.74-25.39 20.94-42.78 20.94s-32.87-8.2-42.78-20.94c-4.59-5.9-11.52-9.49-19-9.49h-22.87c-9.22 0-17.19-5.26-21.13-12.93h-49.34c-5.98 0-10.83-4.85-10.83-10.83s4.85-10.83 10.83-10.83h49.34c3.94-7.67 11.91-12.93 21.13-12.93h22.87c7.47 0 14.41-3.59 19-9.49 9.91-12.74 25.39-20.94 42.78-20.94s32.87 8.2 42.78 20.94c4.59 5.9 11.52 9.49 19 9.49h22.87c9.22 0 17.19 5.26 21.13 12.93h49.34c5.98 0 10.83 4.85 10.83 10.83zm-135.72-.22c0-16.7-13.53-30.23-30.23-30.23s-30.23 13.53-30.23 30.23 13.53 30.23 30.23 30.23 30.23-13.53 30.23-30.23zm100.73 221.39c.33 29.93-3.68 75.18-6.92 91.4-5.16 26.63-29.49 52.37-56.04 58.25-3.65.76-7.62 1.51-11.89 2.23v-95.28c0-30.93-25.17-56.1-56.1-56.1s-56.1 25.17-56.1 56.1v95.28c-4.27-.72-8.24-1.47-11.89-2.23-26.55-5.88-50.88-31.62-56.04-58.25-3.24-16.22-7.25-61.47-6.92-91.4-.33-29.93 3.68-75.18 6.92-91.4 5.16-26.62 29.49-52.37 56.04-58.25 16.12-3.35 38.05-6.64 68-6.69 29.94.05 51.87 3.34 68 6.69 26.55 5.88 50.88 31.62 56.04 58.25 3.24 16.22 7.25 61.47 6.92 91.4zm-193.24-69.73c0-11.59-.5-21.39-.95-23.61-.71-3.65-4.04-7.18-7.69-7.99-2.21-.46-5.22-.91-9.33-.92-4.11 0-7.11.46-9.33.92-3.64.81-6.98 4.34-7.69 7.99-.44 2.23-.95 11.84-.95 23.61s.5 21.39.95 23.61c.71 3.65 4.04 7.18 7.69 7.99 2.21.46 5.22.91 9.33.92 4.11 0 7.11-.46 9.33-.92 3.64-.81 6.98-4.34 7.69-7.99.44-2.23.95-11.32.95-23.61zm160.48 0c0-11.59-.5-21.39-.95-23.61-.71-3.65-4.04-7.18-7.69-7.99-2.21-.46-5.22-.91-9.33-.92-4.11 0-7.11.46-9.33.92-3.64.81-6.98 4.34-7.69 7.99-.44 2.23-.95 11.84-.95 23.61s.5 21.39.95 23.61c.71 3.65 4.04 7.18 7.69 7.99 2.21.46 5.22.91 9.33.92 4.11 0 7.11-.46 9.33-.92 3.64-.81 6.98-4.34 7.69-7.99.44-2.23.95-11.32.95-23.61z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg width="40" height="40" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Circle background same as your first icon -->
<circle cx="20" cy="20" r="20" fill="#EDF8FF"/>
<!-- Scale down the original 512x512 drawing into 40x40 -->
<g transform="scale(0.078125) translate(0,0)">
<path d="m207.72 34.37c-116.82 13.63-207.5 112.85-207.72 233.28-.22 127.67 105.81 234.77 233.48 235.74a234.38 234.38 0 0 0 151.08-53.39 24.62 24.62 0 0 0 1.38-36.73l-143.08-137.91a24.67 24.67 0 0 1 -7.54-17.75v-198.76a24.68 24.68 0 0 0 -27.6-24.48z" fill="#4193d2"/>
<path d="m463.2 386a234.24 234.24 0 0 0 48.8-143.49c0-120.71-90.89-220.2-208-233.75a24.61 24.61 0 0 0 -27.34 24.51v198.85a24.66 24.66 0 0 0 7.43 17.64l142.36 138.83a24.66 24.66 0 0 0 36.75-2.59z" fill="#dd4247"/>
<path d="m302.62 333-59.76-57.61a24.67 24.67 0 0 1 -7.54-17.75v-198.79a24.68 24.68 0 0 0 -27.6-24.48c-116.82 13.63-207.5 112.85-207.72 233.28a231.56 231.56 0 0 0 32.93 119.08 278.59 278.59 0 0 0 269.69-53.73z" fill="#48a4df"/>
<path d="m276.69 33.27v198.85a24.66 24.66 0 0 0 7.43 17.64l51.09 49.83a278.5 278.5 0 0 0 48.79-266.59 233.81 233.81 0 0 0 -80-24.24 24.62 24.62 0 0 0 -27.31 24.51z" fill="#e55353"/>
</g>
</svg>
<svg id="TRAVEL" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="256" y2="256"><stop offset="0" stop-color="#6949c6"/><stop offset=".6" stop-color="#7c6ee0"/><stop offset="1" stop-color="#a28eef"/></linearGradient><path d="m434.01 401.46c-.18 9.4-7.85 16.97-17.3 16.97h-397.4c-9.45 0-17.13-7.57-17.3-16.97-.18-9.7 8.06-17.63 17.76-17.63h62.3c-5.53-3.2-10.01-8-12.81-13.77-.78-1.61.41-3.49 2.21-3.49h53.14c1.79 0 2.99 1.88 2.21 3.49-2.8 5.77-7.28 10.57-12.81 13.77h39.63c-5.53-3.2-10.01-8-12.81-13.77-.78-1.61.41-3.49 2.21-3.49h53.14c1.79 0 2.99 1.88 2.21 3.49-2.8 5.77-7.28 10.57-12.81 13.77h100.79c-5.53-3.2-10.01-8-12.81-13.77-.78-1.61.41-3.49 2.21-3.49h53.14c1.79 0 2.99 1.88 2.21 3.49-2.8 5.77-7.28 10.57-12.81 13.77h38.3c-5.53-3.2-10.01-8-12.81-13.77-.78-1.61.41-3.49 2.21-3.49h53.14c1.79 0 2.99 1.88 2.21 3.49-2.8 5.77-7.28 10.57-12.81 13.77h27.74c9.7 0 17.94 7.94 17.76 17.63zm-433.46-137.15c-1.11-42.11-.55-84.23 1.7-126.35 1.27-23.09 21.6-42.22 44.65-42.64 98.58-1.65 197.16-2.14 295.74-1.47 72.61.62 140.21 54.2 155.04 126.11 5.28 26.45 9.94 52.85 13.88 79.18 3.82 25.74-18.03 50.14-44.28 50.63-140.13 2.34-280.25 2.34-420.38 0-23.05-.41-43.38-19.54-44.65-42.64-.44-8.28-.81-16.55-1.12-24.83l-.58-18zm141.37-78.35c.07-8.49-6.72-15.34-15.2-15.31-26.28.09-52.56.22-78.83.37-8.48.05-15.54 6.91-15.69 15.31-.27 15-.38 25-.31 40 .04 8.4 7.02 15.23 15.52 15.26 26.34.07 52.69.13 79.03.17 8.5.01 15.35-6.85 15.34-15.34-.03-15.15.02-25.3.15-40.45zm126.97-.09c-.03-8.5-6.93-15.41-15.41-15.41-25.14-.01-50.29 0-75.43.05-8.48.02-15.42 6.92-15.48 15.41-.1 15.17-.14 25.33-.11 40.5.01 8.49 6.94 15.39 15.44 15.4 25.21.02 50.41.03 75.62.03 8.5 0 15.41-6.9 15.41-15.41 0-15.19 0-25.38-.04-40.57zm197.27 35.24-5.8-19.24c-5.21-18.13-22.22-30.84-41.18-30.95-35.12-.19-40.24-.32-75.37-.39-8.48-.02-15.31 6.86-15.28 15.37.07 15.18.09 25.36.08 40.54 0 8.5 6.86 15.39 15.37 15.38 45.75-.04 60.49-.13 106.24-.27 10.79-.04 18.77-10.18 15.95-20.44z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
<svg id="Layer_16" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-name="Layer 16"><linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="256" y2="256"><stop offset="0" stop-color="#283451"/><stop offset=".6" stop-color="#384c6c"/><stop offset="1" stop-color="#465a77"/></linearGradient><path d="m505.25 229.85c-8.7-15.32-25.39-42.69-48.09-70.71-16.93-20.9-42.21-33.3-69.11-33.74-16.03-.26-31.77-.41-43.63-.41h-.12c-5.08-25.65-26.52-45.29-53.07-47.64-17.25-1.52-84.91-2.63-117.3-2.63s-100.05 1.1-117.3 2.63c-28.71 2.54-51.46 25.29-54 54-1.53 17.26-2.63 66.07-2.63 98.46s1.1 81.2 2.63 98.45c2.16 24.46 19 44.58 41.69 51.58 4.62-35.94 35.39-63.81 72.56-63.81s70.76 30.48 73.04 68.79c21.7-.16 49.87-.61 71.63-1.24 17.35.54 38.92.94 57.86 1.15 2.32-38.27 34.19-68.7 73.04-68.7s68.37 28.26 72.66 64.56c24.01-6.2 42.08-26.92 44.33-52.32 1.32-14.88 2.32-43.9 2.57-72.39.08-9.12-2.25-18.09-6.75-26.02zm-48.69 15.32h-108.78c.05-5.37.07-10.55.07-15.36 0-22.32-.52-52.44-1.35-74.65 11.39.02 26.19.16 41.05.4 17.96.29 34.79 8.52 46.17 22.57 13.78 17.01 25.24 33.86 33.72 47.32 5.4 8.57-.76 19.72-10.89 19.72zm-339.68 95.99c-26.54 0-48.05 21.51-48.05 48.05s21.52 48.05 48.05 48.05 48.05-21.51 48.05-48.05-21.51-48.05-48.05-48.05zm275.56 0c-26.54 0-48.05 21.51-48.05 48.05s21.51 48.05 48.05 48.05 48.05-21.51 48.05-48.05-21.51-48.05-48.05-48.05z" fill="url(#linear-gradient)"/></svg>
\ No newline at end of file
......@@ -44,6 +44,7 @@ class TP_List {
String? contactName;
String? engineNo;
TP_List({
this.genId,
this.address,
......
class jobDescriptionResponse {
JobDescription? jobDescription;
String? error;
String? message;
int? sessionExists;
jobDescriptionResponse(
{this.jobDescription, this.error, this.message, this.sessionExists});
jobDescriptionResponse.fromJson(Map<String, dynamic> json) {
jobDescription = json['job_description'] != null
? new JobDescription.fromJson(json['job_description'])
: null;
error = json['error'];
message = json['message'];
sessionExists = json['session_exists'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.jobDescription != null) {
data['job_description'] = this.jobDescription!.toJson();
}
data['error'] = this.error;
data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data;
}
}
class JobDescription {
String? name;
String? jobDescription;
String? id;
JobDescription({this.name, this.jobDescription, this.id});
JobDescription.fromJson(Map<String, dynamic> json) {
name = json['name'];
jobDescription = json['job_description'];
id = json['id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['job_description'] = this.jobDescription;
data['id'] = this.id;
return data;
}
}
......@@ -5,6 +5,7 @@ import 'package:generp/screens/LoginScreen.dart';
import 'package:generp/services/api_calling.dart';
import 'package:intl/intl.dart';
import '../Models/hrmModels/jobDescriptionResponse.dart';
import '../Utils/BackgroundLocationService.dart';
import '../Utils/WebSocketManager.dart';
import '../Utils/background_service.dart';
......@@ -176,4 +177,5 @@ class HomescreenNotifier extends ChangeNotifier {
print("$e");
}
}
}
......@@ -8,6 +8,8 @@ import 'package:generp/screens/LoginScreen.dart';
import 'package:generp/services/api_calling.dart';
import 'package:provider/provider.dart';
import '../Models/hrmModels/jobDescriptionResponse.dart';
class ProfileNotifer extends ChangeNotifier{
var _profileImage = "";
var _company = "";
......@@ -101,4 +103,40 @@ class ProfileNotifer extends ChangeNotifier{
}
}
String? _errorMessage;
jobDescriptionResponse? _response;
String? get errorMessage => _errorMessage;
jobDescriptionResponse? get response => _response;
Future<void> fetchJobDescription(HomescreenNotifier prov, BuildContext context) async {
_isLoading = true;
_errorMessage = null;
_response = null;
notifyListeners();
try {
final provider = Provider.of<HomescreenNotifier>(context, listen: false);
final result = await ApiCalling.jobDescriptAPI(
provider.empId,
provider.session,
);
if (result != null) {
_response = result;
} else {
_errorMessage = "No job description data found!";
}
} catch (e) {
_errorMessage = "Something went wrong: $e";
}
_isLoading = false;
notifyListeners();
}
}
\ No newline at end of file
......@@ -410,9 +410,22 @@ class Attendancelistprovider extends ChangeNotifier {
/// Show Cupertino Date Picker
void showDatePickerDialog(BuildContext context) {
DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day);
// Normalize selected date (strip time)
if (_selectedDate == null) {
setSelectedDate(DateTime.now());
setSelectedDate(today);
} else {
_selectedDate = DateTime(
_selectedDate!.year,
_selectedDate!.month,
_selectedDate!.day,
);
}
// Always reset before showing
_selectedDate = today;
setSelectedDate(today);
showCupertinoModalPopup<void>(
context: context,
......@@ -452,7 +465,13 @@ class Attendancelistprovider extends ChangeNotifier {
),
),
onPressed: () {
setSelectedDate(_selectedDate ?? DateTime.now());
// Ensure we save only date without time
final pickedDate = _selectedDate ?? today;
setSelectedDate(DateTime(
pickedDate.year,
pickedDate.month,
pickedDate.day,
));
Navigator.pop(context);
},
),
......@@ -463,12 +482,15 @@ class Attendancelistprovider extends ChangeNotifier {
Expanded(
child: CupertinoDatePicker(
dateOrder: DatePickerDateOrder.dmy,
initialDateTime: _selectedDate ?? DateTime.now(),
initialDateTime: _selectedDate ?? today,
minimumDate: today.subtract(const Duration(days: 2)),
maximumDate: today,
mode: CupertinoDatePickerMode.date,
use24hFormat: true,
showDayOfWeek: true,
onDateTimeChanged: (DateTime newDate) {
setSelectedDate(newDate);
// Always normalize new date to midnight
setSelectedDate(DateTime(newDate.year, newDate.month, newDate.day));
},
),
),
......@@ -478,4 +500,5 @@ class Attendancelistprovider extends ChangeNotifier {
),
);
}
}
......@@ -20,6 +20,12 @@ import 'package:location/location.dart' as loc;
import '../Utils/app_colors.dart';
import 'inventory/InventoryScreen.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/flutter_html.dart' as html;
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
......@@ -42,6 +48,7 @@ class _MyHomePageState extends State<MyHomePage> {
});
var prov = Provider.of<HomescreenNotifier>(context, listen: false);
var prof_prov = Provider.of<ProfileNotifer>(context, listen: false);
// var jobDisc_prov = Provider.of<fetchJobDescription>(context, listen: false);
Future.microtask(() {
prov.DashboardApiFunction(context);
});
......@@ -157,7 +164,7 @@ class _MyHomePageState extends State<MyHomePage> {
"assets/svg/home/home_order_ic.svg",
"assets/svg/home/home_service_ic.svg",
"assets/svg/home/home_gentracker_ic.svg",
"assets/svg/home/home_erp_ic.svg",
"assets/svg/hrm/pie-chart.svg",
];
final icons = [
......@@ -1871,28 +1878,43 @@ class _MyHomePageState extends State<MyHomePage> {
child: Align(
alignment: Alignment.centerLeft,
child: InkWell(
onTap: () {
showJobDescriptionSheet(context, [
"Statewise End to end sales activities reg booking and dispatches and payment collection and branch visit every month & quarterly basis.",
"Conducting monthly/Quarterly/Annually– sales meeting, review of targets and achievements of total team.",
"Team CRM Tracking, Order Update Track and as well as payment entry in CRM by Team.",
"If required special Price to be taken from Prasad, Madhavi Madam/MD Sir.",
"Preparation of MIS reports on monthly basis (Rating wise data, employee wise data, TIV etc.).",
"Dispatch co-ordination with factory team- Anuradha / Sai Ram (commercial clearance with Susmitha / Rajeevi).",
"Commercial / Technical Support to BDE team order finalisation. If required client visit.",
"Team tour bills approvals in CRM.",
"Level -1 approvals to be given to sales team orders.",
"Outstanding payment collection followed on regular basis.",
]);
onTap: () async {
final profileNotifier = Provider.of<ProfileNotifer>(context, listen: false);
// Call API
await profileNotifier.fetchJobDescription(
Provider.of<HomescreenNotifier>(context, listen: false),
context,
);
// fetching, check response
if (profileNotifier.response != null &&
profileNotifier.response!.jobDescription != null) {
if (profileNotifier.response!.jobDescription!.jobDescription != null && profileNotifier.response!.jobDescription!.jobDescription != "") {
showJobDescriptionSheet(
context: context,
htmlData: profileNotifier.response!.jobDescription!.jobDescription ?? "<p>No description</p>",
title: "Job Description",//profileNotifier.response!.jobDescription!.name ??
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(profileNotifier.errorMessage ?? "Failed to fetch job description"),
),
);
}
},
// no click for others
child: Text(
itemText,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
color: index == 2 ? AppColors.semi_black : AppColors.semi_black, // highlight clickable
color: index == 2 ? AppColors.semi_black : AppColors.semi_black,
decoration: index == 2 ? TextDecoration.underline : null,
decorationStyle: TextDecorationStyle.dotted,
),
),
),
......@@ -1966,10 +1988,17 @@ class _MyHomePageState extends State<MyHomePage> {
}
Future<void> showJobDescriptionSheet(
BuildContext context,
List<String> jobPoints,
) {
// Job Descriptions
Future<void> showJobDescriptionSheet({
required BuildContext context,
required String htmlData, // pass details_articles!.description
String title = "Job Description",
}) {
return showModalBottomSheet(
useSafeArea: true,
isDismissible: true,
......@@ -1985,7 +2014,7 @@ class _MyHomePageState extends State<MyHomePage> {
bottom: 15,
left: 15,
right: 15,
top: 30,
top: 15,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
......@@ -1997,47 +2026,76 @@ class _MyHomePageState extends State<MyHomePage> {
children: [
/// Heading
Text(
"Job Description",
title,
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 16,
color: AppColors.app_blue, // same as Logout "Yes, Logout" button
fontSize: 18,
color: AppColors.app_blue,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 15),
const SizedBox(height: 5),
/// Bullet points list
...jobPoints.map(
(point) => Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"• ",
style: TextStyle(
fontSize: 14,
color: AppColors.semi_black,
),
),
Expanded(
child: Text(
point,
style: TextStyle(
fontSize: 14,
color: AppColors.semi_black,
fontFamily: "JakartaRegular",
height: 1.4, // line spacing
),
),
),
],
/// HTML description
Html(
data: htmlData,
style: {
"h2": Style(
wordSpacing: 0,
letterSpacing: 0,
fontSize: FontSize(16),
fontFamily: "JakartaMedium",
color: AppColors.semi_black,
),
),
"h3": Style(
wordSpacing: 0,
letterSpacing: 0,
fontSize: FontSize(12),
fontFamily: "JakartaMedium",
color: AppColors.semi_black,
),
"p": Style(
wordSpacing: 0,
letterSpacing: 0,
fontSize: FontSize(12),
fontFamily: "JakartaMedium",
color: AppColors.grey_semi,
lineHeight: LineHeight.number(2.4),
),
"ul": Style(
wordSpacing: 0,
letterSpacing: 0,
fontSize: FontSize(15),
fontFamily: "JakartaMedium",
color: AppColors.grey_semi,
padding: HtmlPaddings.only(left: 10, right: 8), // fixed for v3.0.0
lineHeight: LineHeight.number(1.4),
),
"li": Style(
wordSpacing: 0,
letterSpacing: 0,
fontSize: FontSize(14),
fontFamily: "JakartaMedium",
color: Colors.black,
padding: HtmlPaddings.only(left: 4),
lineHeight: LineHeight.number(1.4), // bullet text line height
margin: Margins.only(bottom: 10),
),
"a": Style(
color: Colors.blue,
textDecoration: TextDecoration.underline,
),
},
onLinkTap: (url, _, __) {
debugPrint("Link tapped: $url");
if (url != null) {
// launchUrl(Uri.parse(url)); // needs url_launcher
}
},
),
const SizedBox(height: 20),
const SizedBox(height: 6),
/// Close button
InkWell(
......@@ -2075,6 +2133,118 @@ class _MyHomePageState extends State<MyHomePage> {
}
// Future<void> showJobDescriptionSheet(
// BuildContext context,
// List<String> jobPoints,
// ) {
// return showModalBottomSheet(
// useSafeArea: true,
// isDismissible: true,
// isScrollControlled: true,
// showDragHandle: true,
// enableDrag: true,
// backgroundColor: Colors.white,
// context: context,
// builder: (context) {
// return SafeArea(
// child: Container(
// margin: const EdgeInsets.only(
// bottom: 15,
// left: 15,
// right: 15,
// top: 30,
// ),
// padding: EdgeInsets.only(
// bottom: MediaQuery.of(context).viewInsets.bottom,
// ),
// child: SingleChildScrollView(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// /// Heading
// Text(
// "Job Description",
// style: TextStyle(
// fontFamily: "JakartaMedium",
// fontSize: 16,
// color: AppColors.app_blue, // same as Logout "Yes, Logout" button
// fontWeight: FontWeight.w600,
// ),
// ),
// const SizedBox(height: 15),
//
// /// Bullet points list
// ...jobPoints.map(
// (point) => Padding(
// padding: const EdgeInsets.symmetric(vertical: 6),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// "• ",
// style: TextStyle(
// fontSize: 14,
// color: AppColors.semi_black,
// ),
// ),
// Expanded(
// child: Text(
// point,
// style: TextStyle(
// fontSize: 14,
// color: AppColors.semi_black,
// fontFamily: "JakartaRegular",
// height: 1.4, // line spacing
// ),
// ),
// ),
// ],
// ),
// ),
// ),
//
// const SizedBox(height: 20),
//
// /// Close button
// InkWell(
// onTap: () => Navigator.pop(context),
// child: Container(
// alignment: Alignment.center,
// height: 45,
// margin: const EdgeInsets.symmetric(
// horizontal: 5.0,
// vertical: 5.0,
// ),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(15.0),
// ),
// child: Center(
// child: Text(
// "Close",
// textAlign: TextAlign.center,
// style: TextStyle(
// color: AppColors.app_blue,
// fontFamily: "JakartaMedium",
// fontSize: 15,
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// );
// },
// );
// }
Future<void> _showLogoutBottomSheet(BuildContext context) {
return showModalBottomSheet(
useSafeArea: true,
......
......@@ -282,13 +282,13 @@ class _AddLeaveRequestState extends State<AddLeaveRequest> {
leaveTypeError = null;
reasonError = null;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Leave request submitted successfully!"),
backgroundColor: Colors.black87,
),
);
Navigator.pop(context, true);
}
},
child: Container(
......
......@@ -212,6 +212,7 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
_showSnack(context, "Attendance Submitted Successfully!");
_autoFetchLocation();
Navigator.pop(context, true);
}
void _showSnack(BuildContext context, String msg) {
......
......@@ -69,14 +69,49 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
WidgetsBinding.instance.addPostFrameCallback((_) {
_fetchInitialLocation();
});
// Add listeners to text controllers to clear errors when user types
checkInLocation.addListener(_clearCheckInLocError);
checkInDescription.addListener(_clearCheckInDescError);
checkOutLocation.addListener(_clearCheckOutLocError);
checkOutDescription.addListener(_clearCheckOutDescError);
}
@override
void dispose() {
_connectivity.disposeStream();
checkInLocation.removeListener(_clearCheckInLocError);
checkInDescription.removeListener(_clearCheckInDescError);
checkOutLocation.removeListener(_clearCheckOutLocError);
checkOutDescription.removeListener(_clearCheckOutDescError);
super.dispose();
}
// Error clearing methods
void _clearCheckInLocError() {
if (checkInLocError != null && checkInLocation.text.isNotEmpty) {
setState(() => checkInLocError = null);
}
}
void _clearCheckInDescError() {
if (checkInDescError != null && checkInDescription.text.isNotEmpty) {
setState(() => checkInDescError = null);
}
}
void _clearCheckOutLocError() {
if (checkOutLocError != null && checkOutLocation.text.isNotEmpty) {
setState(() => checkOutLocError = null);
}
}
void _clearCheckOutDescError() {
if (checkOutDescError != null && checkOutDescription.text.isNotEmpty) {
setState(() => checkOutDescError = null);
}
}
Future<void> _fetchInitialLocation() async {
String loc = await getCurrentLocation();
setState(() {
......@@ -112,10 +147,18 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
}
}
Future<void> _pickTime(TextEditingController controller) async {
Future<void> _pickTime(TextEditingController controller, bool isCheckIn) async {
final TimeOfDay? picked =
await showTimePicker(context: context, initialTime: TimeOfDay.now());
if (picked != null) controller.text = picked.format(context);
if (picked != null) {
controller.text = picked.format(context);
// Clear error when time is selected
if (isCheckIn) {
if (checkInTimeError != null) setState(() => checkInTimeError = null);
} else {
if (checkOutTimeError != null) setState(() => checkOutTimeError = null);
}
}
}
Future<void> _pickFile(bool isCheckIn) async {
......@@ -138,8 +181,13 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
await picker.pickImage(source: ImageSource.camera);
if (file != null) {
setState(() {
if (isCheckIn) checkInProof = file;
else checkOutProof = file;
if (isCheckIn) {
checkInProof = file;
if (checkInProofError != null) setState(() => checkInProofError = null);
} else {
checkOutProof = file;
if (checkOutProofError != null) setState(() => checkOutProofError = null);
}
});
}
Navigator.pop(context);
......@@ -153,8 +201,13 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
await picker.pickImage(source: ImageSource.gallery);
if (file != null) {
setState(() {
if (isCheckIn) checkInProof = file;
else checkOutProof = file;
if (isCheckIn) {
checkInProof = file;
if (checkInProofError != null) setState(() => checkInProofError = null);
} else {
checkOutProof = file;
if (checkOutProofError != null) setState(() => checkOutProofError = null);
}
});
}
Navigator.pop(context);
......@@ -337,9 +390,6 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
);
}
}
// it's date picker need to take day before yesterday, yesterday and today
Future<bool> _onBackPressed(BuildContext context) async {
Navigator.pop(context, true);
......@@ -389,9 +439,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TextWidget(context, "Date"),
// Date field with error clearing
GestureDetector(
onTap: () => provider.showDatePickerDialog(context),
onTap: () {
provider.showDatePickerDialog(context);
if (dateError != null) {
setState(() => dateError = null);
}
},
child: AbsorbPointer(
child: textControllerWidget(
context,
......@@ -410,6 +465,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
),
errorWidget(context, dateError),
// Type dropdown with error clearing
TextWidget(context, "Type"),
DropdownButtonHideUnderline(
child: Row(
......@@ -426,7 +482,12 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
.toList(),
value: selectedType,
onChanged: (val) {
setState(() => selectedType = val);
setState(() {
selectedType = val;
if (typeError != null) {
typeError = null;
}
});
},
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
......@@ -489,9 +550,9 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TextWidget(context, "$title Time"),
// Time field with error clearing
GestureDetector(
onTap: () => _pickTime(timeCtrl), // ⏰ open time picker
onTap: () => _pickTime(timeCtrl, isCheckIn),
child: AbsorbPointer(
child: textControllerWidget(
context,
......@@ -510,6 +571,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
),
errorWidget(context, isCheckIn ? checkInTimeError : checkOutTimeError),
// Location field (errors cleared via listener)
textControllerWidget(
context,
locCtrl,
......@@ -525,6 +587,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
),
errorWidget(context, isCheckIn ? checkInLocError : checkOutLocError),
// Description field (errors cleared via listener)
textControllerWidget(
context,
descCtrl,
......@@ -540,6 +603,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
),
errorWidget(context, isCheckIn ? checkInDescError : checkOutDescError),
// Proof attachment with error clearing
InkResponse(
onTap: () => _pickFile(isCheckIn),
child: Container(
......@@ -589,5 +653,17 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
],
);
}
}
// Helper widget to display errors
Widget errorWidget(BuildContext context, String? error) {
if (error == null) return const SizedBox(height: 8);
return Padding(
padding: const EdgeInsets.only(bottom: 8, left: 4),
child: Text(
error,
style: const TextStyle(color: Colors.red, fontSize: 12),
),
);
}
\ No newline at end of file
......@@ -441,11 +441,13 @@ class _AddBillScreenState extends State<AddBillScreen> {
if (!validateFields()) {
return;
}
String formattedDate = "";
final provider = Provider.of<TourExpensesProvider>(context, listen: false);
provider.dateController.clear();
tourDateError = null;
final parsedDate = DateFormat("dd MMM yyyy").parse(provider.dateController.text);
formattedDate = DateFormat("yyyy-MM-dd").format(parsedDate);
final success = await provider.addTourBill(
......@@ -453,7 +455,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
placeOfVisit: placeController.text,
daAmount: selectedDAAmount ?? "",
tourType: selectedTourType ?? "",
tourDate: provider.dateController.text,
tourDate: formattedDate,
travelExpenses: travelExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
hotelExpenses: hotelExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
otherExpenses: otherExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
......@@ -461,6 +463,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
hotelImages: hotelImages,
otherImages: otherImages,
);
provider.dateController.clear();
print("image================== $travelImages");
if (success) {
......@@ -537,6 +540,26 @@ class _AddBillScreenState extends State<AddBillScreen> {
);
}
String _getTravelIcon(String? travelType) {
switch (travelType?.toLowerCase()) {
case "flight":
return "assets/svg/hrm/airplane_ic.svg";
case "train":
return "assets/svg/hrm/train_ic.svg";
case "bus":
return "assets/svg/hrm/bus_ic.svg";
case "car":
return "assets/svg/hrm/car_ic.svg";
case "auto":
return "assets/svg/hrm/truck_ic.svg";
case "bike":
return "assets/svg/hrm/motorcycle_ic.svg";
default:
return "assets/svg/hrm/travel_ic.svg"; // fallback
}
}
Widget travelExpenseList(List<Map<String, String>> items) {
return Container(
height: 90,
......@@ -565,7 +588,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
),
child: Center(
child: SvgPicture.asset(
"assets/svg/hrm/travel_ic.svg",
_getTravelIcon(exp["travel_type"]),
height: 20,
),
),
......
......@@ -90,6 +90,10 @@ class _AttendanceRequestDetailScreenState
}
final details = provider.response!.requestDetails!;
final checkInTime = details.status == "Requested" ? "--" : details.checkInTime;
/// scr
return SingleChildScrollView(
......@@ -200,7 +204,9 @@ class _AttendanceRequestDetailScreenState
_buildSectionHeader("Check In/Out Details", scaleFactor),
_buildDate_TimeTile("Check In Date & Time", details.date, details.checkInTime, scaleFactor),
_buildDate_TimeTile("Check Out Date & Time", details.date, details.checkOutTime, scaleFactor),
_buildDetailTile("Original Check In", details.checkInTime, scaleFactor),
_buildDetailTile("Original Check In", checkInTime, scaleFactor),
_buildDetailTile("Original Check Out", "--", scaleFactor),
_buildDetailTile("Original Check In Location", details.checkInLocation, scaleFactor),
_buildDetailTile("Original Check Out Location", details.checkOutLocation, scaleFactor),
......