diff --git a/backend/cli/ascii.txt b/backend/cli/ascii.txt index 14c6881..297384f 100644 --- a/backend/cli/ascii.txt +++ b/backend/cli/ascii.txt @@ -1,82 +1,42 @@ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -█████████████████████████████████████████████████████████████████████▓▓▒▒▒▒▒░░▒░▒▒░░░░░░░░░░░░░░░░▒▒▒▓▓███████████████████████████████████████████████ -████████████████████████████████████████████████████████████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒░░░░░░░░░░░▒▒▓████████████████████████████████████████ -██████████████████████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▓▓▓████████████████████████████████▓▓▒░░░░░░░░░░▒▓████████████████████████████████████ -█████████████████████████████████████████████████▓▒▒▒▒▓▓██████████████████████████████████████████████████▒░░░░░░░░░▓█████████████████████████████████ -████████████████████████████████████████████▓▒▒▒▓████████████████████████████████████████████████████████████▓░░░░░░░░▓███████████████████████████████ -████████████████████████████████████████▓▒▒█████████████████████████████████████████████████████████████████████▒▒░░░░░▒██████████████████████████████ -█████████████████████████████████████▓▓████████████████████████████████▓▓▓▓▓█████████████████████████████████████▓▒░░░░░░▓████████████████████████████ -███████████████████████████████████████████████████████████████████▒▒▒▒▒▒░░▒▒░▒▓███▓▓▓▓▓██████████████████████████▓▒░░░░░░▓███████████████████████████ -██████████████████████████████████████████████████▓▓▒▒▒▓▓█████▓▓▓▒▒▒▒░░░░░░░░░░▒▒▒▒░░░▒▒▒▒▓████████████████████████▒░░░░░░▒███████████████████████████ -███████████████████████████████████████████████▒▒▒░░░░░░░░▒▓▒▒▒▒░░░▒░░░░░░░░░░░░░░░░░░░░░░▒▒███████████████████████▒░░░░░▒▒███████████████████████████ -█████████████████████████████████████████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒█████████████████████▒░░░░░░▒▒███████████████████████████ -███████████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒██████████████████▓░░░░░░░▒▒▓███████████████████████████ -███████████████████████████████████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒████████████████▓░░░░░░░░▒▒▒████████████████████████████ -██████████████████████████████████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒█████████████▓▒░░░░░░░░▒▒▒▒█████████████████████████████ -████████████████████████████████████████▓▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▓███████▓▒░░░░░░░░░░▒▒▒▒▒██████████████████████████████ -██████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░░▒▒▒▓▓▒░░░░░░░░░░░░░▒▒▒▒▒▓███████████████████████████████ -█████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒▒▒▒▒▓█████████████████████████████████ -████████████████████████████████████▒▒▒▒░░░░░░░░░░░░░▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▓███████████████████████████████████ -██████████████████████████████████▓▒▒▒░░░░░░░░░░░░▒▒░░░░░░░░░░░▒░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░▒░▒▒░░░░▒▒▒▒▒▒▒▒▒▓██████████████████████████████████████ -█████████████████████████████████▒▒▒▒░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░▒▒░░░░░░░░▒░░▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████ -█████████████████████████████████▒▒▒░░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░░░░░▒▒▒▒░░░░░░░░▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒█████████████████████████████████████████████ -████████████████████████████████▒▒▒▒░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░░▒░░░░░░░░░░░░▒▒▒░░░░░░▒▒▒░░░░▒▒▒▒▒▓█████████████████████████████████████████████████ -████████████████████████████████▒▒▒▒░░░░░░▒░░▒▒▒░░░░░░░▒░░░░░░░░░░░▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░▒░░░▒▒▒████████████████████████████████████████████████████ -████████████████████████████████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░▒▒░░░░░░░░░░░░▒░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░▒░░▒▒▒▒████████████████████████████████████████████████████ -█████████████████████████████████▒▒▒▒░░░░▒▒▒▒▒▒▒░░░░░▒░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒▒█████████████████████████████████████████████████████ -█████████████████████████████████▓▒▒▒▒▒░░░▒▒▒▒▒▒▒░░░░▒▒░░░░░░░░░░░▒░░░░░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████ -███████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▓███████████████████████████████████████████████████████ -██████████████████████████████████████▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░▒▒▒▒▒▓██████████████████████████████████████████████████████████ -██████████████████████████████████████▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒░░░░░░▒▒░░░░░░░░░░░▒▒▒█████████████████████████████████████████████████████████████ -██████████████████████████████████████▓▒▒▒░░░░▒▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░▒▒░░░░░░░░▒▒▒▒▓█████████████████████████████████████████████████████████████ -████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░▒▒░░░░░░▒▒▒▒▒▓██████████████████████████████████████████████████████████████ -██████████████████████████████████████████▓▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓███████████████████████████████████████████████████████████████ -███████████████████████████████████████████████▓▒▒▒░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████ -████████████████████████████████████████████████▓▒▒▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓███▓▓▓▓▓█████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████████████████████████████████████████████████ -████████████████████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ -██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ \ No newline at end of file +████████████████████████████████████████████████████████████████████████████████████████████████████ +████████████████████████████████████████████████████████████████████████████████████████████████████ +████████████████████████████████████████████████████████████████████████████████████████████████████ +█████████████████████████████████████████████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▓▓████████████████████████████ +███████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░▒▒▒████████████████████ +████████████████████████████▓▒▒▒▒▒▒▒▒▓▓████████████████████████████████▓▒▒▒▒▒▒░░░░░▒▓███████████████ +██████████████████████▓▒▒▒▒▓██████████████████████████████████████████████████▒▒▒▒░░░░░▒████████████ +█████████████████▓▒▒▓████████████████████████████████████████████████████████████▓▒▒▒░░░░▒██████████ +█████████████▓▓▓████████████████████████████████████████████████████████████████████▒▒▒░░░░▒████████ +██████████▓██████████████████████████████████████████████████████████████████████████▓▒▒░░░░▒███████ +███████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████▓▒░░░░░▒██████ +████████████████████████▓▓▓▓█████████▓▒▒▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒█████████████████████████▒▒░░░░▒▓█████ +███████████████████▓▒▒▒▒░░░░░░▒▓▓▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░▒▒██████████████████████▓▒░░░░░▒▒█████ +█████████████████▓▒▒▒░░░░░░░░░░░░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒█████████████████████▒░░░░░▒▒▓█████ +████████████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒███████████████████▒░░░░░▒▒▒▓█████ +███████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒████████████████▓▒░░░░░░▒▒▒▒██████ +███████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒██████████████▒░░░░░░░▒▒▒▒▒███████ +█████████████▓▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░▒▒▒▒▒▓███████▓▒░░░░░░░░░▒▒▒▒▒▓████████ +███████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒░░░░░░░░░░░░▒▒▒▒▓▓▒░░░░░░░░░░░░▒▒▒▒▒▒██████████ +██████████▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒░░░░░░░░░░░░▒▒▒▒░░░░░░░░░░▒▒▒▒▒▒▒▒▓███████████ +█████████▒▒▒▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒▒░░░░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▓██████████████ +███████▒▒▒▒░░░░░░░░░░▒▒▒▒▒░░░░░░░░▒▒▒░░░░░░░░░░░░░░▒▒▒▒░░░░░▒░░░░▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████ +██████▒▒▒▒░░░░░░░░░░▒▒▒░░░░░░░░░░░░░░▒▒░░░░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████ +█████▒▒▒▒░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░▒▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████████ +█████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░░░▒▒░░░░░░░░▒▒░░░░░░░░░░▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓████████████████████████████ +█████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░▒▒░░░░░░░░░░▒▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████████████████████ +█████▒▒▒▒░░░░▒▒▒░▒▒▒▒░░░░▒▒░░░░░░░░░░░▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████ +█████▓▒▒▒▒▒░░▒▒▒▒▒▒▒▒░░░░▒▒░░░░░░░░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████ +██████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████████████████ +████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████████ +██████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████ +███████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████ +███████████▓▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████████████████████████████████ +█████████████▓▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█████████████████████████████████████████ +███████████████████▓▒▒▒▒░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████████████████ +████████████████████▓▒▒▒▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▓█████████████████████████████████████████████ +█████████████████████▓▒▒▒▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████ +███████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████████████████████████████████████████████████████ +███████████████████████████▓▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████ +████████████████████████████████████████████████████████████████████████████████████████████████████ +████████████████████████████████████████████████████████████████████████████████████████████████████ +████████████████████████████████████████████████████████████████████████████████████████████████████ \ No newline at end of file diff --git a/backend/cli/interactive.py b/backend/cli/interactive.py new file mode 100644 index 0000000..0fd7a13 --- /dev/null +++ b/backend/cli/interactive.py @@ -0,0 +1,322 @@ +""" +Interactive CLI interface for NimbusFlow. +""" + +import sys +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .base import NimbusFlowCLI + +from .commands import ( + cmd_members_list, cmd_members_show, + cmd_schedules_list, cmd_schedules_show, cmd_schedules_accept, cmd_schedules_decline, + cmd_services_list, +) + + +def load_ascii_art() -> str: + """Load ASCII art from file.""" + ascii_file = Path(__file__).parent / "ascii.txt" + if ascii_file.exists(): + with open(ascii_file, 'r', encoding='utf-8') as f: + content = f.read() + # Use only the cloud portion (middle section) for better display + lines = content.strip().split('\n') + if len(lines) > 30: + # Take a smaller portion of the cloud art + start = len(lines) // 3 + end = start + 15 + return '\n'.join(lines[start:end]) + return content + return "🎵 NimbusFlow 🎵" # Fallback if file doesn't exist + + +def display_welcome(): + """Display welcome screen with ASCII art.""" + print("\033[2J\033[H") # Clear screen and move cursor to top + + # Display the cloud ASCII art + ascii_art = load_ascii_art() + print(ascii_art) + print() + + # Add the NimbusFlow branding + welcome_text = """ +╔═══════════════════════════════════════════════════════════════════════════════╗ +║ ║ +║ ███╗ ██╗██╗███╗ ███╗██████╗ ██╗ ██╗███████╗ ███████╗██╗ ██████╗ ██╗ ██╗ ║ +║ ████╗ ██║██║████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔════╝██║ ██╔═══██╗██║ ██║ ║ +║ ██╔██╗ ██║██║██╔████╔██║██████╔╝██║ ██║███████╗ █████╗ ██║ ██║ ██║██║ █╗ ██║ ║ +║ ██║╚██╗██║██║██║╚██╔╝██║██╔══██╗██║ ██║╚════██║ ██╔══╝ ██║ ██║ ██║██║███╗██║ ║ +║ ██║ ╚████║██║██║ ╚═╝ ██║██████╔╝╚██████╔╝███████║ ██║ ███████╗╚██████╔╝╚███╔███╔╝ ║ +║ ╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ║ +║ ║ +║ 🎵 Choir Scheduling System 🎵 ║ +╚═══════════════════════════════════════════════════════════════════════════════╝ +""" + print(welcome_text) + print() + + +def display_main_menu(): + """Display the main menu options.""" + print("🎯 " + "="*60) + print(" MAIN MENU - What would you like to manage?") + print("🎯 " + "="*60) + print() + print(" 1️⃣ 👥 Members - Manage choir members") + print(" 2️⃣ 📅 Schedules - View and manage schedules") + print(" 3️⃣ 🎼 Services - Manage services and events") + print(" 4️⃣ ❌ Exit - Close NimbusFlow CLI") + print() + + +def display_members_menu(): + """Display members submenu.""" + print("\n👥 " + "="*50) + print(" MEMBERS MENU") + print("👥 " + "="*50) + print() + print(" 1️⃣ 📋 List all members") + print(" 2️⃣ ✅ List active members only") + print(" 3️⃣ 🎵 List by classification") + print(" 4️⃣ 👤 Show member details") + print(" 5️⃣ 🔙 Back to main menu") + print() + + +def display_schedules_menu(): + """Display schedules submenu.""" + print("\n📅 " + "="*50) + print(" SCHEDULES MENU") + print("📅 " + "="*50) + print() + print(" 1️⃣ 📋 List all schedules") + print(" 2️⃣ ⏳ List pending schedules") + print(" 3️⃣ ✅ List accepted schedules") + print(" 4️⃣ ❌ List declined schedules") + print(" 5️⃣ 👤 Show schedule details") + print(" 6️⃣ ✨ Accept a schedule (interactive)") + print(" 7️⃣ 🚫 Decline a schedule (interactive)") + print(" 8️⃣ 🔙 Back to main menu") + print() + + +def display_services_menu(): + """Display services submenu.""" + print("\n🎼 " + "="*50) + print(" SERVICES MENU") + print("🎼 " + "="*50) + print() + print(" 1️⃣ 📋 List all services") + print(" 2️⃣ 🔮 List upcoming services") + print(" 3️⃣ 📅 List services by date") + print(" 4️⃣ 🔙 Back to main menu") + print() + + +def get_user_choice(max_options: int) -> int: + """Get user menu choice with validation.""" + while True: + try: + choice = input(f"🎯 Enter your choice (1-{max_options}): ").strip() + if not choice: + continue + choice_int = int(choice) + if 1 <= choice_int <= max_options: + return choice_int + else: + print(f"❌ Please enter a number between 1 and {max_options}") + except ValueError: + print("❌ Please enter a valid number") + except (KeyboardInterrupt, EOFError): + print("\n🛑 Goodbye!") + sys.exit(0) + + +def get_text_input(prompt: str, required: bool = True) -> str: + """Get text input from user.""" + while True: + try: + value = input(f"📝 {prompt}: ").strip() + if value or not required: + return value + print("❌ This field is required") + except (KeyboardInterrupt, EOFError): + print("\n🛑 Operation cancelled") + return "" + + +def get_date_input(prompt: str = "Enter date (YYYY-MM-DD)") -> str: + """Get date input from user.""" + while True: + try: + date_str = input(f"📅 {prompt}: ").strip() + if not date_str: + print("❌ Date is required") + continue + # Basic date format validation + if len(date_str) == 10 and date_str.count('-') == 2: + parts = date_str.split('-') + if len(parts[0]) == 4 and len(parts[1]) == 2 and len(parts[2]) == 2: + return date_str + print("❌ Please use format YYYY-MM-DD (e.g., 2025-09-07)") + except (KeyboardInterrupt, EOFError): + print("\n🛑 Operation cancelled") + return "" + + +class MockArgs: + """Mock args object for interactive commands.""" + def __init__(self, **kwargs): + for key, value in kwargs.items(): + setattr(self, key, value) + + +def handle_members_menu(cli: "NimbusFlowCLI"): + """Handle members menu interactions.""" + while True: + display_members_menu() + choice = get_user_choice(5) + + if choice == 1: # List all members + print("\n🔍 Listing all members...") + cmd_members_list(cli, MockArgs(active=False, classification=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 2: # List active members + print("\n🔍 Listing active members...") + cmd_members_list(cli, MockArgs(active=True, classification=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 3: # List by classification + classification = get_text_input("Enter classification (Soprano, Alto / Mezzo, Tenor, Baritone)", True) + if classification: + print(f"\n🔍 Listing {classification} members...") + cmd_members_list(cli, MockArgs(active=False, classification=classification)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 4: # Show member details + member_id = get_text_input("Enter member ID", True) + if member_id.isdigit(): + print(f"\n🔍 Showing details for member {member_id}...") + cmd_members_show(cli, MockArgs(member_id=int(member_id))) + else: + print("❌ Invalid member ID") + input("\n⏸️ Press Enter to continue...") + + elif choice == 5: # Back to main menu + break + + +def handle_schedules_menu(cli: "NimbusFlowCLI"): + """Handle schedules menu interactions.""" + while True: + display_schedules_menu() + choice = get_user_choice(8) + + if choice == 1: # List all schedules + print("\n🔍 Listing all schedules...") + cmd_schedules_list(cli, MockArgs(service_id=None, status=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 2: # List pending schedules + print("\n🔍 Listing pending schedules...") + cmd_schedules_list(cli, MockArgs(service_id=None, status="pending")) + input("\n⏸️ Press Enter to continue...") + + elif choice == 3: # List accepted schedules + print("\n🔍 Listing accepted schedules...") + cmd_schedules_list(cli, MockArgs(service_id=None, status="accepted")) + input("\n⏸️ Press Enter to continue...") + + elif choice == 4: # List declined schedules + print("\n🔍 Listing declined schedules...") + cmd_schedules_list(cli, MockArgs(service_id=None, status="declined")) + input("\n⏸️ Press Enter to continue...") + + elif choice == 5: # Show schedule details + schedule_id = get_text_input("Enter schedule ID", True) + if schedule_id.isdigit(): + print(f"\n🔍 Showing details for schedule {schedule_id}...") + cmd_schedules_show(cli, MockArgs(schedule_id=int(schedule_id))) + else: + print("❌ Invalid schedule ID") + input("\n⏸️ Press Enter to continue...") + + elif choice == 6: # Accept schedule + date = get_date_input("Enter date for interactive accept") + if date: + print(f"\n✨ Starting interactive accept for {date}...") + cmd_schedules_accept(cli, MockArgs(date=date, schedule_id=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 7: # Decline schedule + date = get_date_input("Enter date for interactive decline") + if date: + reason = get_text_input("Enter decline reason (optional)", False) + print(f"\n🚫 Starting interactive decline for {date}...") + cmd_schedules_decline(cli, MockArgs(date=date, schedule_id=None, reason=reason)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 8: # Back to main menu + break + + +def handle_services_menu(cli: "NimbusFlowCLI"): + """Handle services menu interactions.""" + while True: + display_services_menu() + choice = get_user_choice(4) + + if choice == 1: # List all services + print("\n🔍 Listing all services...") + cmd_services_list(cli, MockArgs(date=None, upcoming=False, limit=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 2: # List upcoming services + print("\n🔍 Listing upcoming services...") + cmd_services_list(cli, MockArgs(date=None, upcoming=True, limit=20)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 3: # List by date + date = get_date_input("Enter date to filter services") + if date: + print(f"\n🔍 Listing services for {date}...") + cmd_services_list(cli, MockArgs(date=date, upcoming=False, limit=None)) + input("\n⏸️ Press Enter to continue...") + + elif choice == 4: # Back to main menu + break + + +def run_interactive_mode(cli: "NimbusFlowCLI"): + """Run the main interactive CLI mode.""" + display_welcome() + + print("🎉 Welcome to the NimbusFlow Interactive CLI!") + print(" Navigate through menus to manage your choir scheduling system.") + print() + input("⏸️ Press Enter to continue...") + + while True: + print("\033[2J\033[H") # Clear screen + display_main_menu() + + choice = get_user_choice(4) + + if choice == 1: # Members + handle_members_menu(cli) + + elif choice == 2: # Schedules + handle_schedules_menu(cli) + + elif choice == 3: # Services + handle_services_menu(cli) + + elif choice == 4: # Exit + print("\n🎵 Thank you for using NimbusFlow!") + print(" Have a wonderful day! 🌟") + break \ No newline at end of file diff --git a/backend/cli/main.py b/backend/cli/main.py index dd613b9..dc229e3 100644 --- a/backend/cli/main.py +++ b/backend/cli/main.py @@ -15,6 +15,7 @@ from .commands import ( # Service commands cmd_services_list, setup_services_parser, ) +from .interactive import run_interactive_mode def setup_parser() -> argparse.ArgumentParser: @@ -41,7 +42,22 @@ def main(): args = parser.parse_args() if not args.command: - parser.print_help() + # Launch interactive mode when no command is provided + try: + cli = NimbusFlowCLI() + run_interactive_mode(cli) + except CLIError as e: + print(f"❌ Error: {e}") + return 1 + except KeyboardInterrupt: + print("\n🛑 Interrupted by user") + return 1 + except Exception as e: + print(f"❌ Unexpected error: {e}") + return 1 + finally: + if 'cli' in locals(): + cli.close() return try: