From 4264357d0478cb9397235a4a9a594ae3bc8fdf2f Mon Sep 17 00:00:00 2001 From: Jens Luedicke Date: Mon, 14 Jul 2025 11:11:50 +0200 Subject: [PATCH] Fix favicon not showing issue - Use url_for() for all favicon and icon references in layout.html - Add specific routes for favicon files to ensure proper serving - Create dynamic webmanifest route with correct icon paths - Import send_from_directory for serving static files - This ensures favicons work correctly in all deployment scenarios --- app.py | 43 +++++++++++++++++++++++++++++- static/android-chrome-192x192.png | Bin 0 -> 3623 bytes static/android-chrome-512x512.png | Bin 0 -> 11578 bytes static/apple-touch-icon.png | Bin 0 -> 3288 bytes static/favicon-16x16.png | Bin 0 -> 560 bytes static/favicon-32x32.png | Bin 0 -> 900 bytes static/favicon.ico | Bin 0 -> 15406 bytes static/site.webmanifest | 1 + templates/layout.html | 38 +++++++++++++++----------- 9 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 static/android-chrome-192x192.png create mode 100644 static/android-chrome-512x512.png create mode 100644 static/apple-touch-icon.png create mode 100644 static/favicon-16x16.png create mode 100644 static/favicon-32x32.png create mode 100644 static/favicon.ico create mode 100644 static/site.webmanifest diff --git a/app.py b/app.py index d1dff8a..8424108 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, render_template, request, redirect, url_for, jsonify, flash, session, g, Response, send_file, abort +from flask import Flask, render_template, request, redirect, url_for, jsonify, flash, session, g, Response, send_file, abort, send_from_directory from flask_migrate import Migrate from models import db, TimeEntry, WorkConfig, User, SystemSettings, Team, Role, Project, Company, CompanyWorkConfig, CompanySettings, UserPreferences, WorkRegion, AccountType, ProjectCategory, Task, SubTask, TaskStatus, TaskPriority, TaskDependency, Sprint, SprintStatus, Announcement, SystemEvent, WidgetType, UserDashboard, DashboardWidget, WidgetTemplate, Comment, CommentVisibility, BrandingSettings, CompanyInvitation, Note, NoteFolder, NoteShare from data_formatting import ( @@ -397,6 +397,47 @@ def sitemap_xml(): return Response(sitemap_xml, mimetype='application/xml') +@app.route('/site.webmanifest') +def serve_webmanifest(): + """Serve web manifest with correct icon paths""" + manifest = { + "name": "TimeTrack", + "short_name": "TimeTrack", + "icons": [ + { + "src": url_for('static', filename='android-chrome-192x192.png'), + "sizes": "192x192", + "type": "image/png" + }, + { + "src": url_for('static', filename='android-chrome-512x512.png'), + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#667eea", + "background_color": "#ffffff", + "display": "standalone" + } + return jsonify(manifest) + +# Favicon routes for compatibility +@app.route('/favicon.ico') +def favicon(): + return send_from_directory(app.static_folder, 'favicon.ico', mimetype='image/x-icon') + +@app.route('/favicon-32x32.png') +def favicon_32(): + return send_from_directory(app.static_folder, 'favicon-32x32.png', mimetype='image/png') + +@app.route('/favicon-16x16.png') +def favicon_16(): + return send_from_directory(app.static_folder, 'favicon-16x16.png', mimetype='image/png') + +@app.route('/apple-touch-icon.png') +def apple_touch_icon(): + return send_from_directory(app.static_folder, 'apple-touch-icon.png', mimetype='image/png') + @app.route('/') def home(): if g.user: diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..46d658a7c442e7557e2960605e2d9d500420fcd5 GIT binary patch literal 3623 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 WsWkMWU@hkZ2v{DqHGODIP5K|Wmo(A< literal 0 HcmV?d00001 diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2f14bbd132d5e19d2b8becc2cc7e2c96c237ba GIT binary patch literal 11578 zcmeHN2T)Vnx?Tx{Py~WVQB;DcAV@hDdI_K+2N9)+N>x0dQWfbXiFg#LdQ?ylf)zvr zEc6zYqN1Q85~M{Cks>70A_VeQ_U7JsGq2uz-@Ehfyvqy&YwxxH_5I&p*1yX6J-aQ% zMOTOd0K~0!ZnFab3;)FeVIlZuGVH@F07PK5&CDUp?Rz)*b&2-@Mb<>PvzU$9*GErw zzC0*z&}Xh9@pG@|vy$3ri_I2R%brsnUf86)`L`P~YD#uRR~X0M7N1ZhE~|J2t(zUDB!cp1h*CIPUx0XxS_KZz(g;w2>OxL{;;ML32x{(a=QAc(CGN zcvQ03*mw}HEGzaAwKKBm^SZ&bA63uovJ^X`&7z{Mql|THG}CMP#yrlxRaNBK5Y+Ki!Q>cZX$@go& zF9LK^pUdHzP2&p36AEhwRDKp`s!dx^00tW=x=l!xc76|Qgq=Od9(ncDdnVt0%HLIh zZZp8rzwx8`;raF*PFfS$?!hJTQbZDkJ}Y=PO=>Joo0Y(RGTm6HfhRM35?rzLxmTaX zZn4{ObZ1Y2mTzrU!6F3Mon%Qp*LQ;DUf+)I-78^II%y&+4%l8b>U~sR`u@qhqo*PS zXbKp<0`jiRr^1-h`ptd1jT!iH7g5iPATUV3YEu19l}37mb(Cw7L(oSh5+An0(lEW# z^ar-;0}Vc}o>o7Y>D~hB1bDxb-CikpUQ|rlq3Pe9ILl{+M5NNAr38DV&6tDA!bTtR zXkHkPhze7a3%o+lel5S^@I|19skS!bSLQCBWDUt0?~?@Mn&;$SIb5c5 zpUvr3NBsS+JRF6yi)Y<`FWx=L)z$4c?-cb-ew&V0@@WOsHsMoYz7>WhRx>HRZW0SV z;%C$_#MRuwc>Fh7f_SujlFdCczUqR)*Y`3P!k97kE~IZImu9c)0dAOnl>M@wFBx%S zv)50p7_&wCCCh~oW4^^WSLp}NK8+mjJdY(AaoiPfF&p>IbSzX`GLsR0JiMue+l0fM z&QLN!Y6jn}nw9{Tk_)c3!QVi zdUYuRA^Q*d{E1A8Q++TtCdj|K1H=5b#8j5; z-#-@R3*zo`tGTB(@P3h)yj$D9W!?}O=G#UBP4uefvPntktP4%$B`2E^7u1fKdaH7i z;y%DbB zy_Nv%YdrP7P>EhC409;MucHA8E;qa!ETlR(Gsumc4RdbT_3=UJ;PfyV4Ef!jIYJC3zN?Khb)^sK;KF3IaK%1*w z_x^PILZ&tvL+43GjNTQs8^68r76&I@_9oEwy^?d8RC!rfj5=kF8tY2gHr8(^&NEFT zmV6Ou0d+n+r$+ZK^8^G0;l(;a%UG>`k67TyasiUd1n&}CvbB&Ktc*}0cv7TmwW0{O zAV-iA#vRXJ&%JD~*5bN+J0}#Ei3~swJ$Ru;t8I6(~^1V|IwwS^Dm@>msp{!cpt9Fk$R= zES;ZGC#-+Ya}qcyXdWV7aA1BuXC3}@YJiz#>5h#{;JL`y9$7f}-m7>!8i6ZC>N>sL zR>|QizP|$mIo{8}Doy75+TD^!BEH~4T+K0EDu;`hzl9<808VXRhTQt`1Ce|#i_Xy} zNm8b3D+Z*>414gbs@R#vHeO#4ru7Q7dG%g-oc}>b4^B-9& z0b(sW5zCh5sY~?rlMBzskdIx+Dz-vlUH%b^XV3DIE(#XhSC>X4>dL3 z7>~}0$B~F96s1u>kz9r$I#2kC34_io8vKwyYg7vgQmPqU=MiMS&LqH?=8k3|t+Q7V5Z#is=g=A47mFp8oF6`iu=JWh0A57>Gf3kIG}R*;2UC=! zvlO5$@KOnB5Hl!XPw>rid%tHN-(HUpKoY}XvVYG@M>`L|5nkbsATdtL{+$BenmgK{ z8lQw34+uOmMp|#pN#N*>y!8m7`^zD{KQJAuk=9WqB6zaL5eW(5d>0bf|C8dIf&hC0 zQ69|AL*sm(CK2REkxDEPt`7m2HiIe zQ19Se+C7h*7|~EBf{p#YGN@EFDAlpQXgS(Sgn|+uJEA_52i?^%>A4r$+60kpYTgG+ zI=Y(RU3Yt(>Id(VD1f<=i1?*|s4x(aaBZ3r5+v^Skl7skqZb;qwORRXos2{1AP^9uHZKW5)tU(Q2-POfMU_U36Te* zQ~+`m7Ef`cg3F8@eX~gapme- zhd=i|?&O$4XJc~|Hw?@VDw3}&hd>VunMeHc=M59%<9jR1q^MmOkDg$? zgNeU_quJ>OAdFr5bh&-$ZLp`^zIXv!E^<@`^VX5dG1uDX;cNY3Jw{t@&cR zg&ut8haU5`30M&ZxxMqwN#SnaFcb5r<&)3;DeV}M4olwHijY5iB(bD|@PeBe30bbM zoNF20>h3kQmuU-4(H~2W`%}G5N-vYA$#at&@0lw1PR8tedZq3f>Lm*ekMs=$wT$D!%JAe;6J zmM)s@cW5t6S9|>vG@zSpq!@i#ilrZwR=nko@krE9`EUnlzkeb(>xS zXI~8b0`uivDgo@s;K5E;i+8K{6k_S-Z&MFA!0dgw^RO5kQH+>Uat3IB zs%!k_1mr!Nm4i0`BLhFhp}g?-Vqojm_WeGudDX(e$4Kt`&{~+0tR}l=60ul{wDK(q zxNsuRb7n0_H0G`E76Uf>Wxhk_Ked`Na37ky%}Qn&%v#G~s!6n8RjGpU82za`~fLiU3Cg0-|=-^4`h%nO$W$B*X~%R)UgE)}I5gl{#hf@{{p zuv)$eD!DwzAjB3+XG{dVuLf_=IKFF!Jq9uRYbxOEk?CNDq3d7RO9C(S+8#zO1r1r` zOJg|7`uzA1n3)VD=|9>apyAu1qM(@y6(Kd;OYXh|w5Pclr?kM9Lyk`#!|5>`q!z-7 z%t6I*4+xYv0xPUdyMsrw1St;(dv8Z#vPJIS%!Fc^1&X4A;dEwj?=+SYMErLcq1ipD zcU+m)@l(f13Y6&UR+?18Ib<{!6&{F#jEbK15OajW@~+3*Kw>BUJu!`%6{p(`;qbOk z6Cu;fb3T=;V6rE`#$J99J|I(^TEk4)Yqi%c>nvF$3Cf?)cdZ?@P zzU_vP!BydC z?9TJ>hF?v9O`3dBd0B#Bkfejb5IeUiejhv)Wz*6+Q!WCcyB>Vn2U#7tKl=lk=f~F} zr)A)MO4th_97U-ys{#@-6*jj;1x%hOJ?;zzJ}4Y+g8tr=k>kD>>@@9DQdkDgu8bVM zi=%w#|K55Xylw2x^MgQ3YVx$;WVJCMD`q=}I3IV;cMp(1IeITc7TBef+6G}silO&Q zU>WggHm{}%77$h8vobi!r1I)VW*Cnb4|Dtvf}O@aCU5?6KvvY!&AO&oS1SiaLC&pC z`?=V1Z&65jy?lGy8BkOZ&ahcUb-`pOpI1XG{aVK{H?V(TzwhuFNWKWBJ31Kt9p3S1 zUR(rp(r!p(sS&|i6ZN}J7I&St3ss7MSn;UyAvnsq%MTttft)=ln>q-s@!)rSz7|-b zH;FkY3xwoLLV~!^BV%#r!DB53lTaDIQYVq#dZ9@Nq_ukMcr_tJL;9$u&8{YN`x*s%z(k_ z*-~o-1Ck%BP!E3S4#NNow!`6|yY7J8^*c1eP=(=WQz3^$>H!$3FmRpZ2q5oL@?Mrp zt)T^A^yq7U8#nJbwg*e!?IO`bf!t7){QMHI^pESkYJ*@%>i?SD@dtc-=a}CSI5q4L z`Ypo{)-8r7^uq)o=|X3p6hqdWGp^1z!<_I{Ro}}RK2E(`e6d;-C@jD1H?|h8;_3#N z;&3Lhm483PX`KvFExiO=D(`}Ni(#tq$xMv?t`2*t55{;y&%VC$?@oxCDlDo0;UQhx?MwfssT(>gniXH2RZt7-<(hl(^Dx0KY%YpjEScd-HgLt?FmeBr|G&EC`6qS% zOVnk5<=Sq4*t%8B|8XiPdQ;vpRnDK8cA_2rLYw5 zfH~h++SSYyEjkwqVYDtL_W$4)fx}k(dKcMgI)$4T2I}&sH5`z6MU8<>GnB+8e*KxJ z!Y{M`vLfrB0RP`Jcrr@>|L)_V_K$bla$Gl(r9rB$ZS75PA*RkkM-?p5pZ;JY2JSU> z=ICRxQz{)hVFlqA?da|X7py%-^YK{HtdwL&HqidUu-DZ9w^s+yz6w%I#`gKa6648~ zV{|xNG=@)1s*8dlOQR#PSo#G|+wLdeLPS+`x-^(Ab1r@WR~8?grUu|_G4Q6fP!-%( zWM2>$1s2K1!L3-*FnjvgZt$(&zpVroUC!=pY0&xqCqSAdrl$h1WQur=_ zLPuT;FM+l861`Iz$RPz>Eb1e#1%=@1RA^;IDzd5iZ#R089coxqNc_c{wtU#sdI7o_ zQBgwp0lLjww4VPYJ-t*8+4a@Vg9;3PnX=&{w18#5MT+|b9Fbw^5up?sVb<=~#IL+_ zyvGq39=6cWZS_Kx5#-MNBN8Ly$i*WP7&DR2%F)v-#v@qX4-9pnC&&zYxH&G}+>J7v z3PV7{wxtK%M9zZpvjWGUA*fmK{D<9Ytn2ap4MdWmcmq9%rH{cbV_sus2#Y#!A?q7+ zW(8Ev3RC;;l$D=PF(mNda2}$A;67-}{8QQ`+mYS}At;UDHq;R6a2>GEK)w?_;L(6E zQY+5;L@GPp8Ph=z;KO%aN z)Zr5RN`3`OOg+RHf6mhfX=Pu5!T#$$c!FRj%&D`E|K)h!66gl4rxEw~o7`YOccosU zOpc^%IePFF1M!(gs-x##{;;7NA%-^o=iU@WQ(NCXyZ62HMywKKK&i1{Xsa;Cc*5uE zX=8%C6ZG}aX#>6!P^s`W^;}^v-?ws=ir!dP!M!}M!oT43gdbNQ;JMCm)jTuQ-f;iT z*Vm)O8fhJeOT4Yi+K7n%DZp|;M@PGJ9n#tg&9@@{I2t8MBG-05eJV&aK-Je916tC+nW%pS}nacB&A;ZH0ShQMYG94`J_6 zFn+fEnvQ{9Cv-{r8mv7CTf5Jo_{DKq^a_vQJ|%4&1%FsY?!jSQ9XK{MNqCp(R-2Z` zLI=jjZdmfsURUl+b-hsbfB#%8?w+@vhR{Wvxgj2`@xJQA?%*YIe* z$6Z1z*&4IE9UEtgUhlzRU*aTM)CW3JOujYF0TadED4!o^i_s%I;mbeB1?u=TV|bD1 zH;QCq6DYi8jsp848;4&=adDP#;~fQI?)p_~1wQjW<<1{h@p(^F)i!=xFInzyiDesZ zbem5;8Q6IX!#sO3tmEe$ZcLN{?@x!)e~21!12<@u)vWBADArx5Z^V#w)90sei~B6z z&rluM46hC(sKhnmDI@(Y<2Ni80W6D4Gw+#G9`J~$BAbJ-z1;8!S)$1*CQM^|2y3O| zZ0FPD8aD%4v^luCz?2hMr%)V%Izl_nKLyVlj~Gp{E#ug_NHT{x3C>3mr^8^&1>x-t z-Nsg4Y1S{G%CJC`Gif)LOs>*)>Z}NVM2Z@HTxV&9+`95uLOs|2lUF<2e3DhaS%@;E z)qj&zy6xAph$WKfl@2Nw%N|{LaDq+KHLYpQap9S2icZ3NF09i2?1UeezM&_Ax8=gL zv)IvAF5JPO!6l&8v>_5>vhpSU4z-mgy<#miEp-&j&R?+XE9SMEmbYwP5TehdK3DHM zKr!r7?AO5X@0P%Tq|4&^p7NU5t-L1K)6g478OrADWa9fx1G)}BpGK!hVIwtGK;JEL zq4A~qo8_H@!_f23{g`m$}DO%>z4gZy@G7=Vt7=DM2$AxiQ-i@ znN^)8k9Fn)?JIFU0#QNSEM{kaXH$y$aPMN&)#JvJN9Nssaz^H9KKRE1bceMjGOSl+ z&kGw%d!K|k%ktTWx-_p3By*oj*4guThcw^q#xPX{s|>~_#n{!lxMs%?^fuU06&A@z zvsNjlqs6as@efEtqu13N$p(6x^k;!j@MP-3Q0*erx%|X zR0wr_%SNq8T15?G)oPlImA2vA*id0c^4>2}d4rJhRG&!lA_!Av0Tab=F>hD~WIP8qgKz}tey zF5XJO&HF};#8cY_3y6GEFX7*Fd(ql(tUZ3=EAhSRVRKTyqA_96yEEa>Jw5@r$wmPr1L|ozo~F(&u?pzQ3r9C z;W%(VkX^YSco`a`bO_+FZrXD(Ue#sYhBc-u$W>+A1&$+EsHjJ*bFS!l1j=~UnA`k_L93ayib1Xm|oE_Cj0lpbWC;$>QY4}Aw%`|Zco&uJyPYj9g` zb+p$B)ttEJ^#ILLAJ-5hXUR)Vm+?+kHS=1>Rq-_E2zOU3-P5K4cP2|(i5clBU6@oG zc_3=LW*}P7!AoWAnl35Hg<5&Z1;rGxS?;02-IYR=M%`7k6=8cRRcbnu0_>UIPhxdw z*^^DByRzkH)Zy>_6H2reo!r`>mu*muaV|`^2iD#iPb?hQkMLp^j(1%{uN+ciu(T9B zgSXmrjJLz6b$)21>8bI2$;q!*oR)*Esu`;HT2G>a4K8s+Fd2ne&FF%TCE4w6FkX5-t68K Sf>{%QKUUj!Z!0kOIQ=hLPT%4H literal 0 HcmV?d00001 diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2a23eecf85db6d5b21513f5e23f4d830d82056c6 GIT binary patch literal 3288 zcmV;}3@7u6P)gHR2&Eyh6Ht*Lh}xF6T3aeur3gM41usE~*jnO?rLBsBJ`7Ziwpv=G zV6~#edjgtAA4~&jt8pmSEA*nJ(ovH5(k9X*lg#Y?*PNL+b7r4&)?RyE_xf)*oaD^9 zegE&bzx}PX_CBW&?V~KlL{_g987)Q5MYT)Sdm(Z<-ba>*ti(J1%OiUQ6a|1m_dxM- zTI4X^52DV$Q1v~$zl!&FCq*W}-65c*)uI-FV^XeIF0vVgH=?7j;I$SnFwBDrI8#6Y zydST>;2%4WifkK`;>e)h`U1UO%ApTMzJo$fqoMVK8sp!ofI|g7nG(5SgUFt1q`*I` zkDfr^E9K}?k=s%2CcIAhyt+DZv;w<*+tf7y*Crl$Dgg3SO7bMKg-Eta*Qz@Fon z*L6d^0O(&L%>em35ScHu(4m_qYR;hD45C-7Dj(up*`wxrfy32zN-;6l=Lw)^Cx8#* zgInnpk1k=TwQXWp1a)mkwFpdd zF@#(05_t^U+2sh<^;z`b>XGw z2&jOu0{f6lUs7z9aud$rXXo;1sak=bAwnuoCh z%=3++@_2K3UEBHw=p>(Hb2u`BRZW<$&M+MPa*y}V<3W$Toh{7mGf zE3ppyr{3$(KX?!8&}-|os#i7!`;Y#&WB(_6^~P+oRFHLOCHm;M^ub$faPOJo7tRv- z-f#3I`uocwZ)%p+Yq3+RoD$jpmWawFtBzu5*8XL6TGcE2#dAb1{gqzXzwQuu>$iGk z>y%P~;()RrU|T&jzISm3=qT@nFjQjQH$-k6*Q@;JUyJPev0m9!N{xP7H%f#o$CQI92UCuaXQ1W2lSw&rCS*Egy7Xhp!IZ=DDHXOk0!^SB5g6M% znLrchMnK0_IbxvAZo9NHDKyC4VsUITIkY3eA_m&bVk@%Y z>fd`)-^2ZD^pDW7W&9e}6X=jYYdFYp5vClR6go!CZ}SA&7to%rcFds@$)R-@9++}4 z<>1!0->ag#-qaV#Ur31rW~$Q z4$oU|OgWfxG)y_-x-1cB0^JbkIu}IuWeIfqf$sObaRNDXy(<8LZa>id!s0-nJ*U8p zLwI&TcZDn4lfu;eKM?4~gn4ctJD|JtwGFgq_ciX0KzA+MdHOz>#*XXN0D*SBZ0F2% z)eSR3Gl%9Xhv$>dWp|9wjL_A5#gu#0n3)miwgRoOQ_Xuh2Hnfy@>=4iZB7cc@8xjg z0NbrHLbo+SYmmYS%?Pc5N!TJjS2=2=w%$Zxgibj^R}keBXm6C(=!ih440MH~2{hNC zHP)dQFB!ymxmA1aJN(Z2ILk=M8Cm91MU)Xj>m1G>N&ymW=0{L{xprY7~urcx?< z`ya5Hau~Qh#_P6$8LSeA02ZT1QNE&DpA$Ss)sFpyT*{#X!fKI?Q z9AX0n2y_GSST#Nc2(%5Kgt`;Q#@Jid27&hEQ0DG_geK5_bZ*oOPX>MY2(-RdESZ1; z1UdmHaftc~^agssM5p>P827fQzAP-6ssfDAsd|p%u2g_P6O2|VK%iUYP8vg?$v~?V zXd%#?n6`@0n#Qyc=$Z=TR6K(%dIFsj(7LuJ3_gL@bu!C&Q=rND6b;ZiM)bd@fw{9c z;v()S8lWTAsMSN$2_z{A;0EZnsg#mOGasuJpg&Iq_;p#C^Ay~C1@vKzLi77NgO8U3 zpaT6AIHG_)fD&u`>%?g8U-Q=Y_^ASVFU-84^`_Fm926KYwo3Up=5RNsX>F!ao|Eog zxIUqP-UNM~MF}MnkDL@}*NIVLC*u0zeksq!D#b4Naa~Tnq^+$}U>~m6mlR`Cjw}~> z5hv?qu1w@p%dV7VyK@SF-&e3)ckN7?fr;T3ygf>Js6fIB+;W%5V>3V_O0Pha{wMx( zYQhF_=$R^j+-W-y_9G^FOWJ zOqqrH1r$7==|}odx6A^yJv8SRhN#S0)`5x^-*EvN W{=-^_3^e}$00005Iu7@xB-ihPC*C~qvior5NvFeSZHP8i%1a5HH$?aA!@6otd=5*1Rp?5;THa2 zE84iocgHhxzq>zSXW8%P-nnPanK_^Qf^G(2LxC#qh<*WtH|0a%&mvZUz@*5%6ruI@ zA=ac0yh60f?Ec|^+!R78Plv#Cg{qZ6ivWE4KfHWlRZ1$J+=-HMD{du`m4<;yLU@+j*C@?Y) zj4c2s>lFBuihukJ%xwV=XA#X~#q(_itrvwvp#&)i5MVV5vK(6mzOMp@YneR>lm6n4 zpm_vb?{`a#T|FqJep>-13D8(eTJt!Ub^~tO0PW5sfby)1nplY#Uk%PcNXv)8_^}5x z8^Av@NMlQeAOIyef?WieflDx5md)IyUByj9aDC8ebcGx20h?%N%_F>jU5=EH7mZ7dDBqE5g}3Kqypb1oJ((=zizP zY!y@Bc1k|V4PZjb>Tl()+CE-OC88hUrTsm56GdOCrRwNjp60MZ+3y*w)SN#Yv$RTR yiG9x8+hATblXtrOJBF9b--JDv)M-?{)ZPI`7SCoN5%EI+0000&v;JyHk02BVp_?mihn$T=g z+3+2Fk38~=v?v~dJQo;o?wci`FP3BX=W2;P{3`@9d0I1I-YfMQ~aE+e|unrupW0#TfS=H=HbpTg8* z%L5>t&7K1eooFgWVEZF5{s$btSlSk8wZ&V>^v^c!H+-Ms1=ZlHu=@^JxZ@ZHN`LJN z@OKZmNg)1X0~xLZgR21mx(alJ*|WgGd2M|99xz8%HeUjxZ+d*^Gc`j7j$P1WGpB$v z?5n$*z}HuLd~XNX`H}=+ezcd{T_GcPfz`{v)(6{(tFO65;1;PKu5rcJn$u`&z*Lj* z+XavkU55aA1^`)0?4ueb?_?{eLh2{n+_8W3c(*g*o1l>*6t*XZpS$yQtmOfirX zfUreK16lTF3|9l{YvQaB-;8t}n;Q7RD$t8Joh$oh25j1bolvbvJ5Pzw&4SNBI8~K4 zBPnRt2Yi7~$UtV4q2b3YKcg%Q0HMvw91AiKDX-2Vt6-z7g2qOar_TeGcDip>CmgW% ze}7+!&IM4uyBf$yf>kiiycQ=Sz-J(ITvK$L0M^Ms!*NS7kUGJzTVnnaFteb#+wZM_ zs0;@OI>5;u@M}o62GTZtwk#QFdCYF!Tc);Xl>*aijIG9VU}Rg+0NQwntk2e!LwUfj zITU0dzJaM!DF?B%#d9v_@mgkF1SW+DBNvml>8z&5`+e=nXQQ~7*jKZ*ai_5J;_88s z=p%p3_a~OWNDktuiP7G4z1zRcYp1%N)A<8t_OQBlJ3CgjttU@6cCdt|G=}u5qnXBjWJ@0000kgGCoAE5ZtoXao|P()sslt-0+rvuF06{a-}O1N-c~XV$FmTi;qU z``;HK8lqne3<%s0ihIWiaf1+Ia8R93xj=}u*fwpN?w>5g$OIv#pbZYe5vm<`!9Nf~ zi!;$Y4q_>^aHBmmmI3tPzHhla&rCbB!8RJRIBU>Yw8y@T#zx;%1KMm}gvl(E+w|0Ds@Tq_JOMrRXY`f8eG;g5~t1%znpZm^+ zzXrH{Yd&6TsI@UMQrny@IevexH>~>#@oBtjlelPabhPnkd>Nzc*V+=k9B;;GKUP!Z zLdSD9<@k6`I2q~!!vuQY28|lWhFvlh*a6lyfmIx~pdOx$RFiv59rMka<9;aW2~CYqVy;qFyjWqO$0CAMa zYaIREhS#u&Ppjdq4a#=&4`>_K+u>fuiPj<74F2plbD#biWzIRiZ1c1=b`Gv*Bl}pJ z!PoIi{y{%Dr#QZY!SvMaRx{78&>q5$s_96ypHA1i*Yu@FCF^>6Lvyz}DV_^2)CXvY;aS31UQTTc9F+vj0& ze;hv$e+;9Po5mmG_0KWcacd@<|9o9yHl~$ziPoQhFK4XM z-SXkM{J4Ohs6S%K`y7s`{mOcc=u^m10iW~s<6p1hm+LRLD?fHHZ+;EnPP`{G+b6#& zpHJ<{+o+H3K`vS4wk;V^wtEh^?K6-U*TEhKw0u=xZYfXB1(8h6VZUZXl~ z`K?=YJy_hB9>`}p*3g3O)f-)FFT?na?fmV~GRJoRj_N0#mDr3EufNK10Szn1Ff40} zwS>5;7QDK$HlcCUR$?Ei^J+cHV7N~Lp7$! zldnOpnam@P)#HcHsPJCUyZ=HPjxFPtJ}NZzwehe*F{=Bop+&MU!QS{#_36hQIJZ7y z-09xe-hUsU`!OE7!SnYL-};W_f%9QGAsk=W0qgzGqjgD%og)XbLtp~=5DlKK%6!A@p!&k z^@TB0YA?j0vW>3+{yZ%?$2!MnaLqL!R-o=fcgXV+`$`^l$I`R8x?`-p%Dv*;ya%5L ze%ijTPIwf@*3WZucd>5rHN}aG)uPjmy41%la`%0voD+B4qI0$2BU-N=%x7B{^MU=zhiwPJjicKeq(%{vE9~=*V*VT6Pufx%gkDojI4;J|wj(m)N+zx-=NAR4jqp^6a_y_&EHPGq;|H8aXz?Ij? zF7Ssg@Q+@v%iiNrjEVe>K4$OW)#hLEdkT5+-#rpDR>#OcGwc5sf%;F$V-kN|%P}4) zI3b%v{T;o1KS})goGF=?v3bfcd2UkcC&r(AWg-6E)|v5lxO7v0dVfgQ->KEVpXpmx zhes^lNIq;141dB7{Qh_6tH$)PLi)$_V!U17yuM<`gip1{VmJKh4kp0g(J02L7Jr`` z<5KX?=E;O-0hWKRzNMw_Y0b9jdw?Uyi9Ns{#{f2dm-iW)$94f+_zb}KCjlP9@0(4# z+0!@6qkkzMbRSCJ%9=j2U$wV*Z7=ZkV`Jx6)g))>79C+z)rf4v{Il6yK%*yx+)iK_w5!~1l~4~?Pw^yt`tf6{=S zO$0SBt0A2O`W}43O2{t7clmXe_tsk`G$0-=6g3am3xu?2Cu6ZHM-f5Ro+ityv_;u3OyVz>- zuFMBpS0ZyYC6=^zVAWW@<|)|zn7Zf09oMU)b;kwmEA@`&uiaRYKfXU*x--ZplGFBW zD{|OI{K$UvHy*i2m^G%$H8`jG%^fixkr|)OZ{GCyt69xVS@&x9h literal 0 HcmV?d00001 diff --git a/static/site.webmanifest b/static/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/static/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html index 53aaf4c..9bc8cd1 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -4,14 +4,14 @@ {% if title == 'Home' %}{{ g.branding.app_name if g.branding else 'TimeTrack' }} - Enterprise Time Tracking & Project Management Software{% else %}{{ title }} - {{ g.branding.app_name if g.branding else 'TimeTrack' }}{% endif %}{% if g.company %} - {{ g.company.name }}{% endif %} - + - + @@ -21,7 +21,7 @@ {% if g.branding and g.branding.logo_filename %} {% endif %} - + @@ -38,7 +38,7 @@ - + @@ -54,6 +54,12 @@ {% endif %} {% if g.branding and g.branding.favicon_filename %} + {% else %} + + + + + {% endif %}