diff --git a/team-checkin-app/.gitignore b/team-checkin-app/.gitignore
new file mode 100644
index 0000000..723ef36
--- /dev/null
+++ b/team-checkin-app/.gitignore
@@ -0,0 +1 @@
+.idea
\ No newline at end of file
diff --git a/team-checkin-app/LICENSE b/team-checkin-app/LICENSE
new file mode 100644
index 0000000..77a8049
--- /dev/null
+++ b/team-checkin-app/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 pavan-elisetty
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/team-checkin-app/Procfile b/team-checkin-app/Procfile
new file mode 100644
index 0000000..645733f
--- /dev/null
+++ b/team-checkin-app/Procfile
@@ -0,0 +1 @@
+web: sh setup.sh && streamlit run app.py
\ No newline at end of file
diff --git a/team-checkin-app/README.md b/team-checkin-app/README.md
new file mode 100644
index 0000000..f206b70
--- /dev/null
+++ b/team-checkin-app/README.md
@@ -0,0 +1,50 @@
+# A *simple* team attendence/checkin application
+
+- This repository consists the python code that is used to build.
+- It is developed with streamlit.
+- Hosted on heroku for temp deployment
+
+## Application description :
+ - Application is used to enter and maintain the log of the team members.
+ - This also produce a general stats for that week
+ - Every team member is assigned a unique passphrase (just like password) , only with that particular passphrase , the member can checkin.
+ - This makes it difficult for doing proxy
+
+## Functionality :
+ - The `record.csv` is used to maintain the entire log of team members
+ - `week_log.csv` is used to maintain log of a particular week and will be recycled for every weekend.
+ - `app.py` is the main functional app
+ - `data.csv` contains the user details and pass phrases . (*this can be hidden or make the repo private*)
+ - `Procfile`,`setup.sh` is used for the deployment
+ - *all the remaining files are support files*
+
+## ScreenShots :
+LightMode
+
+DarkMode
+
+
+## Deployment :
+[app](https://team-checkin-application.herokuapp.com/)
+
+### Steps to Run the app:
+
+1. Create a python virtual environment and activate it:
+ ```
+ python3 -m venv app
+ source app/bin/activate
+ ```
+2. Install the required libraries:
+ ```
+ pip install -r requirements.txt
+ ```
+3. Run the app:
+ ```
+ streamlit run app.py
+ ```
+ *app runs on the local server*
+
+4. Enter `CTRL+C` once you are done.
+
+
+[MIT License](https://github.com/pavan-elisetty/team-checkin-app/blob/main/LICENSE)
diff --git a/team-checkin-app/app.py b/team-checkin-app/app.py
new file mode 100644
index 0000000..30f4221
--- /dev/null
+++ b/team-checkin-app/app.py
@@ -0,0 +1,190 @@
+import streamlit as st
+import pandas as pd
+import base64
+import os
+import datetime
+import sqlalchemy as sa
+from pathlib import Path
+import psycopg2
+
+#creating sql alchemy engine
+engine = sa.create_engine('',echo=False) #add your heroku postgres url
+def check_if_weekend(today):
+ try:
+ isinstance(today, datetime.datetime)
+ upper_limit = today + datetime.timedelta(days=(6 - today.weekday()))
+ lower_limit = today + datetime.timedelta(days=(5 - today.weekday()))
+ if today >= lower_limit <= upper_limit:
+ return True
+ else:
+ return False
+ except ValueError:
+ pass
+
+
+today_date = datetime.datetime.today()
+weekend = check_if_weekend(today_date)
+
+
+if weekend==True:
+ os.remove('week_log.csv')
+ try:
+ engine.execute('DROP TABLE table2')
+ except:
+ pass
+ new_week_log = pd.DataFrame(columns=['Name', 'Time', 'Days', 'Hours', 'Reason', 'Team'],index=None)
+ new_week_log.to_csv('week_log.csv', mode='w', header=True,index=None)
+ new_week_log.to_sql('table2',con=engine,index=False,index_label=None,if_exists='replace')
+else:
+ try:
+ new_week_log=pd.read_sql('table2',con=engine,index_col=None)
+ except:
+ new_week_log = pd.DataFrame(columns=['Name', 'Time', 'Days', 'Hours', 'Reason', 'Team'])
+ new_week_log.to_sql('table2', con=engine, index=False, index_label=None, if_exists='replace')
+ new_week_log = pd.read_sql('table2', con=engine, index_col=None)
+
+
+st.title('Work Checkin System')
+
+st.sidebar.image('logo.jpg')
+st.sidebar.markdown("""
+ ***XYZ Team***
+""")
+
+data=pd.read_csv('data.csv',header=[0])
+if os.path.exists('record.csv'):
+ try:
+ record=pd.read_sql('table1',con=engine,index_col=None)
+ except:
+ record=pd.read_csv('record.csv',index_col=None)
+ record.to_sql('table1',con=engine,index=False,index_label=None,if_exists='append')
+else:
+ record = pd.DataFrame(columns=['Name', 'Time', 'Days', 'Hours', 'Reason', 'Team'],index=None)
+ record.to_csv('record.csv', mode='w', header=True,index=None)
+ record.to_sql('table1',con=engine,index=False,index_label=None,if_exists='replace')
+st.write(record)
+#st.write(pd.read_sql('table1',con=engine,index_col=None))
+
+days=['mon','tue','wed','thurs','fri','sat','sun']
+teams=['Development','PR','management']
+st.warning('Avoid duplication, ignore if not applicable')
+st.error('During the time of weekend it will reset itself and you wont be able to do any changes , dont checkin during the weekends')
+
+
+def input_values():
+ data2 = pd.read_csv('data.csv', header=[0])
+
+ if st.sidebar.checkbox('Work for this week'):
+ selected_name = st.sidebar.selectbox('Name', options=data['Members'])
+ days_selected=st.sidebar.multiselect('Days free to work',options=days)
+ hours=st.sidebar.slider('No.of hours per week will be able to work',1.0,1.0,8.0)
+ team_willing=st.sidebar.multiselect('Team willing to work in',options=teams)
+ password=str(st.sidebar.text_input('enter the passphrase')).lower()
+
+ if st.sidebar.button('Submit details'):
+ y=data2.loc[data2.Members == str(selected_name)]
+ z=y.iloc[:,-1].values
+ if password==str(z[0]):
+ st.balloons()
+ input_data={
+ 'Name':[str(selected_name)],
+ 'Time':[str(datetime.datetime.today())],
+ 'Days':[str(days_selected)],
+ 'Hours':[str(hours)],
+ 'Reason':['None'],
+ 'Team':[str(team_willing)]
+ }
+ input_df=pd.DataFrame(input_data)
+ input_df.to_csv('record.csv', mode='a', header=False,index=None)
+ input_df.to_sql('table1',if_exists='append',con=engine,index=False,index_label=None)
+ record_changed = pd.read_sql('table1',con=engine,index_col=None)
+ record_reverse = record_changed.iloc[::-1]
+ st.subheader('Continous Log')
+ st.write(record_reverse.head())
+ input_df.to_csv('week_log.csv', mode='a', header=False,index=None)
+ input_df.to_sql('table2', if_exists='append', con=engine, index=False, index_label=None)
+ record_changed_wl = pd.read_sql('table2',con=engine,index_col=None)
+ record_reverse_wl = record_changed_wl.iloc[::-1]
+ st.subheader('Weekly Log')
+ st.write(record_reverse_wl.head())
+ else:
+ st.sidebar.warning('Wrong passphrase')
+ elif st.sidebar.checkbox('Cannot Work this week'):
+ selected_name = st.sidebar.selectbox('Name', options=data['Members'])
+ reason=st.sidebar.text_input('Reason')
+ password = str(st.sidebar.text_input('enter the passphrase')).lower()
+ if st.sidebar.button('Submit details'):
+ y = data2.loc[data2.Members == str(selected_name)]
+ z = y.iloc[:, -1].values
+ if password == str(z[0]):
+ st.balloons()
+ input_data={
+ 'Name':[str(selected_name)],
+ 'Time':[str(datetime.datetime.today())],
+ 'Days':['None'],
+ 'Hours':0,
+ 'Reason':[str(reason)],
+ 'Team':['None']
+ }
+ input_df=pd.DataFrame(input_data)
+ input_df.to_csv('record.csv', mode='a', header=False,index=None)
+ input_df.to_sql('table1', if_exists='append', con=engine, index=False, index_label=None)
+ record_changed = pd.read_sql('table1',con=engine,index_col=None)
+ record_reverse=record_changed.iloc[::-1]
+ st.subheader('Continous Log')
+ st.write(record_reverse.head())
+ input_df.to_csv('week_log.csv', mode='a', header=False,index=None)
+ input_df.to_sql('table2', if_exists='append', con=engine, index=False, index_label=None)
+ record_changed_wl = pd.read_sql('table2',con=engine,index_col=None)
+ record_reverse_wl = record_changed_wl.iloc[::-1]
+ st.subheader('Weekly Log')
+ st.write(record_reverse_wl.head())
+ else:
+ st.sidebar.warning('Wrong passphrase')
+
+input_values() # input values function
+
+def filedownload():
+ log=pd.read_sql('table1',con=engine,index_col=None)
+ csv = log.to_csv(index=False)
+ b64 = base64.b64encode(csv.encode()).decode() # strings <-> bytes conversions
+ href = f'Download Team entire Log File'
+ return href
+
+def filedownload_week():
+ log=pd.read_sql('table2',con=engine,index_col=None)
+ csv = log.to_csv(index=False)
+ b64 = base64.b64encode(csv.encode()).decode() # strings <-> bytes conversions
+ href = f'Download Team week Log File'
+ return href
+
+new_log_df=pd.read_sql('table2',con=engine,index_col=None)
+people_data=data.copy()
+
+
+st.write('Total no.of work hours reported {}'.format(new_log_df['Hours'].sum()))
+
+col1,col2,col3=st.beta_columns(3)
+with col1:
+ st.header('Team updated')
+ unique_names=new_log_df['Name'].unique()
+ st.write(unique_names)
+with col2:
+ st.header('Team Not updated')
+ name1 = set(new_log_df['Name'])
+ name2 = set(people_data['Members'])
+ diff = sorted(name2 - name1)
+ st.write(pd.DataFrame(diff))
+with col3:
+ data={
+ 'Updated':new_log_df['Name'].nunique(),
+ 'Not-Updated':people_data['Members'].nunique()-new_log_df['Name'].nunique()
+ }
+ st.header('Comparision between updation for current week')
+ st.bar_chart(data=pd.DataFrame(data,index=[0]),use_container_width=True)
+ bar_df=pd.DataFrame(data,index=[0])
+
+
+st.markdown(filedownload_week(), unsafe_allow_html=True)
+
+st.markdown(filedownload(), unsafe_allow_html=True)
diff --git a/team-checkin-app/data.csv b/team-checkin-app/data.csv
new file mode 100644
index 0000000..e1f0442
--- /dev/null
+++ b/team-checkin-app/data.csv
@@ -0,0 +1,5 @@
+Members,Phrase
+one,charlie
+two,gamma
+three,beta
+four,delta
diff --git a/team-checkin-app/images/1.jpg b/team-checkin-app/images/1.jpg
new file mode 100644
index 0000000..5c8c696
Binary files /dev/null and b/team-checkin-app/images/1.jpg differ
diff --git a/team-checkin-app/images/2.jpg b/team-checkin-app/images/2.jpg
new file mode 100644
index 0000000..8d0bd63
Binary files /dev/null and b/team-checkin-app/images/2.jpg differ
diff --git a/team-checkin-app/logo.jpg b/team-checkin-app/logo.jpg
new file mode 100644
index 0000000..214f2c5
Binary files /dev/null and b/team-checkin-app/logo.jpg differ
diff --git a/team-checkin-app/record.csv b/team-checkin-app/record.csv
new file mode 100644
index 0000000..60e452c
--- /dev/null
+++ b/team-checkin-app/record.csv
@@ -0,0 +1 @@
+Name,Time,Days,Hours,Reason,Team
diff --git a/team-checkin-app/requirements.txt b/team-checkin-app/requirements.txt
new file mode 100644
index 0000000..27772af
--- /dev/null
+++ b/team-checkin-app/requirements.txt
@@ -0,0 +1,6 @@
+streamlit
+pandas
+base58
+datetime
+psycopg2
+SQLAlchemy
diff --git a/team-checkin-app/setup.sh b/team-checkin-app/setup.sh
new file mode 100644
index 0000000..d39033d
--- /dev/null
+++ b/team-checkin-app/setup.sh
@@ -0,0 +1,9 @@
+mkdir -p ~/.streamlit/
+
+echo "\
+[server]\n\
+port = $PORT\n\
+enableCORS = false\n\
+headless = true\n\
+\n\
+" > ~/.streamlit/config.toml
\ No newline at end of file
diff --git a/team-checkin-app/week_log.csv b/team-checkin-app/week_log.csv
new file mode 100644
index 0000000..60e452c
--- /dev/null
+++ b/team-checkin-app/week_log.csv
@@ -0,0 +1 @@
+Name,Time,Days,Hours,Reason,Team