Spaces:
Sleeping
Sleeping
pierrelissope
commited on
Commit
·
9a9d08c
1
Parent(s):
c3e46dc
feat: added front core
Browse files- .idea/.gitignore +5 -0
- .idea/PoCInnovation.iml +12 -0
- .idea/codeStyles/Project.xml +28 -0
- .idea/codeStyles/codeStyleConfig.xml +5 -0
- .idea/dbnavigator.xml +401 -0
- .idea/inspectionProfiles/Project_Default.xml +6 -0
- .idea/modules.xml +8 -0
- .idea/prettier.xml +7 -0
- .idea/vcs.xml +6 -0
- front/.gitignore +2 -2
- front/components.json +20 -0
- front/dist/assets/index-CwlTocwK.css +0 -1
- front/dist/assets/index-IWZEvq7A.js +0 -0
- front/dist/assets/react-CHdo91hT.svg +0 -1
- front/dist/index.html +1 -1
- front/package-lock.json +0 -0
- front/package.json +19 -1
- front/postcss.config.js +6 -0
- front/src/App.css +2 -41
- front/src/App.tsx +18 -28
- front/src/Homescene.tsx +64 -0
- front/src/VerificationScene.tsx +163 -0
- front/src/components/BoxContainer.tsx +20 -0
- front/src/components/DarkVideoWrapper.tsx +105 -0
- front/src/components/ResultContainer.tsx +16 -0
- front/src/components/VideoWrapper.tsx +106 -0
- front/src/components/ui/button.tsx +57 -0
- front/src/index.css +7 -0
- front/src/lib/utils.ts +6 -0
- front/tailwind.config.js +52 -3
- front/tsconfig.app.json +6 -1
- front/tsconfig.app.tsbuildinfo +1 -1
- front/tsconfig.json +7 -1
- front/vite.config.ts +9 -4
.idea/.gitignore
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Default ignored files
|
| 2 |
+
/shelf/
|
| 3 |
+
/workspace.xml
|
| 4 |
+
# Editor-based HTTP Client requests
|
| 5 |
+
/httpRequests/
|
.idea/PoCInnovation.iml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<module type="WEB_MODULE" version="4">
|
| 3 |
+
<component name="NewModuleRootManager">
|
| 4 |
+
<content url="file://$MODULE_DIR$">
|
| 5 |
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
| 6 |
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
| 7 |
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
| 8 |
+
</content>
|
| 9 |
+
<orderEntry type="inheritedJdk" />
|
| 10 |
+
<orderEntry type="sourceFolder" forTests="false" />
|
| 11 |
+
</component>
|
| 12 |
+
</module>
|
.idea/codeStyles/Project.xml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<component name="ProjectCodeStyleConfiguration">
|
| 2 |
+
<code_scheme name="Project" version="173">
|
| 3 |
+
<DBN-PSQL>
|
| 4 |
+
<case-options enabled="true">
|
| 5 |
+
<option name="KEYWORD_CASE" value="lower" />
|
| 6 |
+
<option name="FUNCTION_CASE" value="lower" />
|
| 7 |
+
<option name="PARAMETER_CASE" value="lower" />
|
| 8 |
+
<option name="DATATYPE_CASE" value="lower" />
|
| 9 |
+
<option name="OBJECT_CASE" value="preserve" />
|
| 10 |
+
</case-options>
|
| 11 |
+
<formatting-settings enabled="false" />
|
| 12 |
+
</DBN-PSQL>
|
| 13 |
+
<DBN-SQL>
|
| 14 |
+
<case-options enabled="true">
|
| 15 |
+
<option name="KEYWORD_CASE" value="lower" />
|
| 16 |
+
<option name="FUNCTION_CASE" value="lower" />
|
| 17 |
+
<option name="PARAMETER_CASE" value="lower" />
|
| 18 |
+
<option name="DATATYPE_CASE" value="lower" />
|
| 19 |
+
<option name="OBJECT_CASE" value="preserve" />
|
| 20 |
+
</case-options>
|
| 21 |
+
<formatting-settings enabled="false">
|
| 22 |
+
<option name="STATEMENT_SPACING" value="one_line" />
|
| 23 |
+
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
| 24 |
+
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
| 25 |
+
</formatting-settings>
|
| 26 |
+
</DBN-SQL>
|
| 27 |
+
</code_scheme>
|
| 28 |
+
</component>
|
.idea/codeStyles/codeStyleConfig.xml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<component name="ProjectCodeStyleConfiguration">
|
| 2 |
+
<state>
|
| 3 |
+
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
| 4 |
+
</state>
|
| 5 |
+
</component>
|
.idea/dbnavigator.xml
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="DBNavigator.Project.DatabaseFileManager">
|
| 4 |
+
<open-files />
|
| 5 |
+
</component>
|
| 6 |
+
<component name="DBNavigator.Project.Settings">
|
| 7 |
+
<connections />
|
| 8 |
+
<browser-settings>
|
| 9 |
+
<general>
|
| 10 |
+
<display-mode value="TABBED" />
|
| 11 |
+
<navigation-history-size value="100" />
|
| 12 |
+
<show-object-details value="false" />
|
| 13 |
+
<enable-sticky-paths value="true" />
|
| 14 |
+
</general>
|
| 15 |
+
<filters>
|
| 16 |
+
<object-type-filter>
|
| 17 |
+
<object-type name="SCHEMA" enabled="true" />
|
| 18 |
+
<object-type name="USER" enabled="true" />
|
| 19 |
+
<object-type name="ROLE" enabled="true" />
|
| 20 |
+
<object-type name="PRIVILEGE" enabled="true" />
|
| 21 |
+
<object-type name="CHARSET" enabled="true" />
|
| 22 |
+
<object-type name="TABLE" enabled="true" />
|
| 23 |
+
<object-type name="VIEW" enabled="true" />
|
| 24 |
+
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
| 25 |
+
<object-type name="NESTED_TABLE" enabled="true" />
|
| 26 |
+
<object-type name="COLUMN" enabled="true" />
|
| 27 |
+
<object-type name="INDEX" enabled="true" />
|
| 28 |
+
<object-type name="CONSTRAINT" enabled="true" />
|
| 29 |
+
<object-type name="DATASET_TRIGGER" enabled="true" />
|
| 30 |
+
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
| 31 |
+
<object-type name="SYNONYM" enabled="true" />
|
| 32 |
+
<object-type name="SEQUENCE" enabled="true" />
|
| 33 |
+
<object-type name="PROCEDURE" enabled="true" />
|
| 34 |
+
<object-type name="FUNCTION" enabled="true" />
|
| 35 |
+
<object-type name="PACKAGE" enabled="true" />
|
| 36 |
+
<object-type name="TYPE" enabled="true" />
|
| 37 |
+
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
| 38 |
+
<object-type name="ARGUMENT" enabled="true" />
|
| 39 |
+
<object-type name="DIMENSION" enabled="true" />
|
| 40 |
+
<object-type name="CLUSTER" enabled="true" />
|
| 41 |
+
<object-type name="DBLINK" enabled="true" />
|
| 42 |
+
</object-type-filter>
|
| 43 |
+
</filters>
|
| 44 |
+
<sorting>
|
| 45 |
+
<object-type name="COLUMN" sorting-type="NAME" />
|
| 46 |
+
<object-type name="FUNCTION" sorting-type="NAME" />
|
| 47 |
+
<object-type name="PROCEDURE" sorting-type="NAME" />
|
| 48 |
+
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
| 49 |
+
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
| 50 |
+
</sorting>
|
| 51 |
+
<default-editors>
|
| 52 |
+
<object-type name="VIEW" editor-type="SELECTION" />
|
| 53 |
+
<object-type name="PACKAGE" editor-type="SELECTION" />
|
| 54 |
+
<object-type name="TYPE" editor-type="SELECTION" />
|
| 55 |
+
</default-editors>
|
| 56 |
+
</browser-settings>
|
| 57 |
+
<navigation-settings>
|
| 58 |
+
<lookup-filters>
|
| 59 |
+
<lookup-objects>
|
| 60 |
+
<object-type name="SCHEMA" enabled="true" />
|
| 61 |
+
<object-type name="USER" enabled="false" />
|
| 62 |
+
<object-type name="ROLE" enabled="false" />
|
| 63 |
+
<object-type name="PRIVILEGE" enabled="false" />
|
| 64 |
+
<object-type name="CHARSET" enabled="false" />
|
| 65 |
+
<object-type name="TABLE" enabled="true" />
|
| 66 |
+
<object-type name="VIEW" enabled="true" />
|
| 67 |
+
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
| 68 |
+
<object-type name="INDEX" enabled="true" />
|
| 69 |
+
<object-type name="CONSTRAINT" enabled="true" />
|
| 70 |
+
<object-type name="DATASET TRIGGER" enabled="true" />
|
| 71 |
+
<object-type name="DATABASE TRIGGER" enabled="true" />
|
| 72 |
+
<object-type name="SYNONYM" enabled="false" />
|
| 73 |
+
<object-type name="SEQUENCE" enabled="true" />
|
| 74 |
+
<object-type name="PROCEDURE" enabled="true" />
|
| 75 |
+
<object-type name="FUNCTION" enabled="true" />
|
| 76 |
+
<object-type name="PACKAGE" enabled="true" />
|
| 77 |
+
<object-type name="TYPE" enabled="true" />
|
| 78 |
+
<object-type name="DIMENSION" enabled="false" />
|
| 79 |
+
<object-type name="CLUSTER" enabled="false" />
|
| 80 |
+
<object-type name="DBLINK" enabled="true" />
|
| 81 |
+
</lookup-objects>
|
| 82 |
+
<force-database-load value="false" />
|
| 83 |
+
<prompt-connection-selection value="true" />
|
| 84 |
+
<prompt-schema-selection value="true" />
|
| 85 |
+
</lookup-filters>
|
| 86 |
+
</navigation-settings>
|
| 87 |
+
<dataset-grid-settings>
|
| 88 |
+
<general>
|
| 89 |
+
<enable-zooming value="true" />
|
| 90 |
+
<enable-column-tooltip value="true" />
|
| 91 |
+
</general>
|
| 92 |
+
<sorting>
|
| 93 |
+
<nulls-first value="true" />
|
| 94 |
+
<max-sorting-columns value="4" />
|
| 95 |
+
</sorting>
|
| 96 |
+
<audit-columns>
|
| 97 |
+
<column-names value="" />
|
| 98 |
+
<visible value="true" />
|
| 99 |
+
<editable value="false" />
|
| 100 |
+
</audit-columns>
|
| 101 |
+
</dataset-grid-settings>
|
| 102 |
+
<dataset-editor-settings>
|
| 103 |
+
<text-editor-popup>
|
| 104 |
+
<active value="false" />
|
| 105 |
+
<active-if-empty value="false" />
|
| 106 |
+
<data-length-threshold value="100" />
|
| 107 |
+
<popup-delay value="1000" />
|
| 108 |
+
</text-editor-popup>
|
| 109 |
+
<values-actions-popup>
|
| 110 |
+
<show-popup-button value="true" />
|
| 111 |
+
<element-count-threshold value="1000" />
|
| 112 |
+
<data-length-threshold value="250" />
|
| 113 |
+
</values-actions-popup>
|
| 114 |
+
<general>
|
| 115 |
+
<fetch-block-size value="100" />
|
| 116 |
+
<fetch-timeout value="30" />
|
| 117 |
+
<trim-whitespaces value="true" />
|
| 118 |
+
<convert-empty-strings-to-null value="true" />
|
| 119 |
+
<select-content-on-cell-edit value="true" />
|
| 120 |
+
<large-value-preview-active value="true" />
|
| 121 |
+
</general>
|
| 122 |
+
<filters>
|
| 123 |
+
<prompt-filter-dialog value="true" />
|
| 124 |
+
<default-filter-type value="BASIC" />
|
| 125 |
+
</filters>
|
| 126 |
+
<qualified-text-editor text-length-threshold="300">
|
| 127 |
+
<content-types>
|
| 128 |
+
<content-type name="Text" enabled="true" />
|
| 129 |
+
<content-type name="XML" enabled="true" />
|
| 130 |
+
<content-type name="DTD" enabled="true" />
|
| 131 |
+
<content-type name="HTML" enabled="true" />
|
| 132 |
+
<content-type name="XHTML" enabled="true" />
|
| 133 |
+
<content-type name="CSS" enabled="true" />
|
| 134 |
+
<content-type name="SQL" enabled="true" />
|
| 135 |
+
<content-type name="PL/SQL" enabled="true" />
|
| 136 |
+
<content-type name="JavaScript" enabled="true" />
|
| 137 |
+
<content-type name="JSON" enabled="true" />
|
| 138 |
+
<content-type name="JSON5" enabled="true" />
|
| 139 |
+
<content-type name="YAML" enabled="true" />
|
| 140 |
+
</content-types>
|
| 141 |
+
</qualified-text-editor>
|
| 142 |
+
<record-navigation>
|
| 143 |
+
<navigation-target value="VIEWER" />
|
| 144 |
+
</record-navigation>
|
| 145 |
+
</dataset-editor-settings>
|
| 146 |
+
<code-editor-settings>
|
| 147 |
+
<general>
|
| 148 |
+
<show-object-navigation-gutter value="false" />
|
| 149 |
+
<show-spec-declaration-navigation-gutter value="true" />
|
| 150 |
+
<enable-spellchecking value="true" />
|
| 151 |
+
<enable-reference-spellchecking value="false" />
|
| 152 |
+
</general>
|
| 153 |
+
<confirmations>
|
| 154 |
+
<save-changes value="false" />
|
| 155 |
+
<revert-changes value="true" />
|
| 156 |
+
<exit-on-changes value="ASK" />
|
| 157 |
+
</confirmations>
|
| 158 |
+
</code-editor-settings>
|
| 159 |
+
<code-completion-settings>
|
| 160 |
+
<filters>
|
| 161 |
+
<basic-filter>
|
| 162 |
+
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
| 163 |
+
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
| 164 |
+
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
| 165 |
+
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
| 166 |
+
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
| 167 |
+
<filter-element type="OBJECT" id="schema" selected="true" />
|
| 168 |
+
<filter-element type="OBJECT" id="role" selected="true" />
|
| 169 |
+
<filter-element type="OBJECT" id="user" selected="true" />
|
| 170 |
+
<filter-element type="OBJECT" id="privilege" selected="true" />
|
| 171 |
+
<user-schema>
|
| 172 |
+
<filter-element type="OBJECT" id="table" selected="true" />
|
| 173 |
+
<filter-element type="OBJECT" id="view" selected="true" />
|
| 174 |
+
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
| 175 |
+
<filter-element type="OBJECT" id="index" selected="true" />
|
| 176 |
+
<filter-element type="OBJECT" id="constraint" selected="true" />
|
| 177 |
+
<filter-element type="OBJECT" id="trigger" selected="true" />
|
| 178 |
+
<filter-element type="OBJECT" id="synonym" selected="false" />
|
| 179 |
+
<filter-element type="OBJECT" id="sequence" selected="true" />
|
| 180 |
+
<filter-element type="OBJECT" id="procedure" selected="true" />
|
| 181 |
+
<filter-element type="OBJECT" id="function" selected="true" />
|
| 182 |
+
<filter-element type="OBJECT" id="package" selected="true" />
|
| 183 |
+
<filter-element type="OBJECT" id="type" selected="true" />
|
| 184 |
+
<filter-element type="OBJECT" id="dimension" selected="true" />
|
| 185 |
+
<filter-element type="OBJECT" id="cluster" selected="true" />
|
| 186 |
+
<filter-element type="OBJECT" id="dblink" selected="true" />
|
| 187 |
+
</user-schema>
|
| 188 |
+
<public-schema>
|
| 189 |
+
<filter-element type="OBJECT" id="table" selected="false" />
|
| 190 |
+
<filter-element type="OBJECT" id="view" selected="false" />
|
| 191 |
+
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
| 192 |
+
<filter-element type="OBJECT" id="index" selected="false" />
|
| 193 |
+
<filter-element type="OBJECT" id="constraint" selected="false" />
|
| 194 |
+
<filter-element type="OBJECT" id="trigger" selected="false" />
|
| 195 |
+
<filter-element type="OBJECT" id="synonym" selected="false" />
|
| 196 |
+
<filter-element type="OBJECT" id="sequence" selected="false" />
|
| 197 |
+
<filter-element type="OBJECT" id="procedure" selected="false" />
|
| 198 |
+
<filter-element type="OBJECT" id="function" selected="false" />
|
| 199 |
+
<filter-element type="OBJECT" id="package" selected="false" />
|
| 200 |
+
<filter-element type="OBJECT" id="type" selected="false" />
|
| 201 |
+
<filter-element type="OBJECT" id="dimension" selected="false" />
|
| 202 |
+
<filter-element type="OBJECT" id="cluster" selected="false" />
|
| 203 |
+
<filter-element type="OBJECT" id="dblink" selected="false" />
|
| 204 |
+
</public-schema>
|
| 205 |
+
<any-schema>
|
| 206 |
+
<filter-element type="OBJECT" id="table" selected="true" />
|
| 207 |
+
<filter-element type="OBJECT" id="view" selected="true" />
|
| 208 |
+
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
| 209 |
+
<filter-element type="OBJECT" id="index" selected="true" />
|
| 210 |
+
<filter-element type="OBJECT" id="constraint" selected="true" />
|
| 211 |
+
<filter-element type="OBJECT" id="trigger" selected="true" />
|
| 212 |
+
<filter-element type="OBJECT" id="synonym" selected="true" />
|
| 213 |
+
<filter-element type="OBJECT" id="sequence" selected="true" />
|
| 214 |
+
<filter-element type="OBJECT" id="procedure" selected="true" />
|
| 215 |
+
<filter-element type="OBJECT" id="function" selected="true" />
|
| 216 |
+
<filter-element type="OBJECT" id="package" selected="true" />
|
| 217 |
+
<filter-element type="OBJECT" id="type" selected="true" />
|
| 218 |
+
<filter-element type="OBJECT" id="dimension" selected="true" />
|
| 219 |
+
<filter-element type="OBJECT" id="cluster" selected="true" />
|
| 220 |
+
<filter-element type="OBJECT" id="dblink" selected="true" />
|
| 221 |
+
</any-schema>
|
| 222 |
+
</basic-filter>
|
| 223 |
+
<extended-filter>
|
| 224 |
+
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
| 225 |
+
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
| 226 |
+
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
| 227 |
+
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
| 228 |
+
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
| 229 |
+
<filter-element type="OBJECT" id="schema" selected="true" />
|
| 230 |
+
<filter-element type="OBJECT" id="user" selected="true" />
|
| 231 |
+
<filter-element type="OBJECT" id="role" selected="true" />
|
| 232 |
+
<filter-element type="OBJECT" id="privilege" selected="true" />
|
| 233 |
+
<user-schema>
|
| 234 |
+
<filter-element type="OBJECT" id="table" selected="true" />
|
| 235 |
+
<filter-element type="OBJECT" id="view" selected="true" />
|
| 236 |
+
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
| 237 |
+
<filter-element type="OBJECT" id="index" selected="true" />
|
| 238 |
+
<filter-element type="OBJECT" id="constraint" selected="true" />
|
| 239 |
+
<filter-element type="OBJECT" id="trigger" selected="true" />
|
| 240 |
+
<filter-element type="OBJECT" id="synonym" selected="true" />
|
| 241 |
+
<filter-element type="OBJECT" id="sequence" selected="true" />
|
| 242 |
+
<filter-element type="OBJECT" id="procedure" selected="true" />
|
| 243 |
+
<filter-element type="OBJECT" id="function" selected="true" />
|
| 244 |
+
<filter-element type="OBJECT" id="package" selected="true" />
|
| 245 |
+
<filter-element type="OBJECT" id="type" selected="true" />
|
| 246 |
+
<filter-element type="OBJECT" id="dimension" selected="true" />
|
| 247 |
+
<filter-element type="OBJECT" id="cluster" selected="true" />
|
| 248 |
+
<filter-element type="OBJECT" id="dblink" selected="true" />
|
| 249 |
+
</user-schema>
|
| 250 |
+
<public-schema>
|
| 251 |
+
<filter-element type="OBJECT" id="table" selected="true" />
|
| 252 |
+
<filter-element type="OBJECT" id="view" selected="true" />
|
| 253 |
+
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
| 254 |
+
<filter-element type="OBJECT" id="index" selected="true" />
|
| 255 |
+
<filter-element type="OBJECT" id="constraint" selected="true" />
|
| 256 |
+
<filter-element type="OBJECT" id="trigger" selected="true" />
|
| 257 |
+
<filter-element type="OBJECT" id="synonym" selected="true" />
|
| 258 |
+
<filter-element type="OBJECT" id="sequence" selected="true" />
|
| 259 |
+
<filter-element type="OBJECT" id="procedure" selected="true" />
|
| 260 |
+
<filter-element type="OBJECT" id="function" selected="true" />
|
| 261 |
+
<filter-element type="OBJECT" id="package" selected="true" />
|
| 262 |
+
<filter-element type="OBJECT" id="type" selected="true" />
|
| 263 |
+
<filter-element type="OBJECT" id="dimension" selected="true" />
|
| 264 |
+
<filter-element type="OBJECT" id="cluster" selected="true" />
|
| 265 |
+
<filter-element type="OBJECT" id="dblink" selected="true" />
|
| 266 |
+
</public-schema>
|
| 267 |
+
<any-schema>
|
| 268 |
+
<filter-element type="OBJECT" id="table" selected="true" />
|
| 269 |
+
<filter-element type="OBJECT" id="view" selected="true" />
|
| 270 |
+
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
| 271 |
+
<filter-element type="OBJECT" id="index" selected="true" />
|
| 272 |
+
<filter-element type="OBJECT" id="constraint" selected="true" />
|
| 273 |
+
<filter-element type="OBJECT" id="trigger" selected="true" />
|
| 274 |
+
<filter-element type="OBJECT" id="synonym" selected="true" />
|
| 275 |
+
<filter-element type="OBJECT" id="sequence" selected="true" />
|
| 276 |
+
<filter-element type="OBJECT" id="procedure" selected="true" />
|
| 277 |
+
<filter-element type="OBJECT" id="function" selected="true" />
|
| 278 |
+
<filter-element type="OBJECT" id="package" selected="true" />
|
| 279 |
+
<filter-element type="OBJECT" id="type" selected="true" />
|
| 280 |
+
<filter-element type="OBJECT" id="dimension" selected="true" />
|
| 281 |
+
<filter-element type="OBJECT" id="cluster" selected="true" />
|
| 282 |
+
<filter-element type="OBJECT" id="dblink" selected="true" />
|
| 283 |
+
</any-schema>
|
| 284 |
+
</extended-filter>
|
| 285 |
+
</filters>
|
| 286 |
+
<sorting enabled="true">
|
| 287 |
+
<sorting-element type="RESERVED_WORD" id="keyword" />
|
| 288 |
+
<sorting-element type="RESERVED_WORD" id="datatype" />
|
| 289 |
+
<sorting-element type="OBJECT" id="column" />
|
| 290 |
+
<sorting-element type="OBJECT" id="table" />
|
| 291 |
+
<sorting-element type="OBJECT" id="view" />
|
| 292 |
+
<sorting-element type="OBJECT" id="materialized view" />
|
| 293 |
+
<sorting-element type="OBJECT" id="index" />
|
| 294 |
+
<sorting-element type="OBJECT" id="constraint" />
|
| 295 |
+
<sorting-element type="OBJECT" id="trigger" />
|
| 296 |
+
<sorting-element type="OBJECT" id="synonym" />
|
| 297 |
+
<sorting-element type="OBJECT" id="sequence" />
|
| 298 |
+
<sorting-element type="OBJECT" id="procedure" />
|
| 299 |
+
<sorting-element type="OBJECT" id="function" />
|
| 300 |
+
<sorting-element type="OBJECT" id="package" />
|
| 301 |
+
<sorting-element type="OBJECT" id="type" />
|
| 302 |
+
<sorting-element type="OBJECT" id="dimension" />
|
| 303 |
+
<sorting-element type="OBJECT" id="cluster" />
|
| 304 |
+
<sorting-element type="OBJECT" id="dblink" />
|
| 305 |
+
<sorting-element type="OBJECT" id="schema" />
|
| 306 |
+
<sorting-element type="OBJECT" id="role" />
|
| 307 |
+
<sorting-element type="OBJECT" id="user" />
|
| 308 |
+
<sorting-element type="RESERVED_WORD" id="function" />
|
| 309 |
+
<sorting-element type="RESERVED_WORD" id="parameter" />
|
| 310 |
+
</sorting>
|
| 311 |
+
<format>
|
| 312 |
+
<enforce-code-style-case value="true" />
|
| 313 |
+
</format>
|
| 314 |
+
</code-completion-settings>
|
| 315 |
+
<execution-engine-settings>
|
| 316 |
+
<statement-execution>
|
| 317 |
+
<fetch-block-size value="100" />
|
| 318 |
+
<execution-timeout value="20" />
|
| 319 |
+
<debug-execution-timeout value="600" />
|
| 320 |
+
<focus-result value="false" />
|
| 321 |
+
<prompt-execution value="false" />
|
| 322 |
+
</statement-execution>
|
| 323 |
+
<script-execution>
|
| 324 |
+
<command-line-interfaces />
|
| 325 |
+
<execution-timeout value="300" />
|
| 326 |
+
</script-execution>
|
| 327 |
+
<method-execution>
|
| 328 |
+
<execution-timeout value="30" />
|
| 329 |
+
<debug-execution-timeout value="600" />
|
| 330 |
+
<parameter-history-size value="10" />
|
| 331 |
+
</method-execution>
|
| 332 |
+
</execution-engine-settings>
|
| 333 |
+
<operation-settings>
|
| 334 |
+
<transactions>
|
| 335 |
+
<uncommitted-changes>
|
| 336 |
+
<on-project-close value="ASK" />
|
| 337 |
+
<on-disconnect value="ASK" />
|
| 338 |
+
<on-autocommit-toggle value="ASK" />
|
| 339 |
+
</uncommitted-changes>
|
| 340 |
+
<multiple-uncommitted-changes>
|
| 341 |
+
<on-commit value="ASK" />
|
| 342 |
+
<on-rollback value="ASK" />
|
| 343 |
+
</multiple-uncommitted-changes>
|
| 344 |
+
</transactions>
|
| 345 |
+
<session-browser>
|
| 346 |
+
<disconnect-session value="ASK" />
|
| 347 |
+
<kill-session value="ASK" />
|
| 348 |
+
<reload-on-filter-change value="false" />
|
| 349 |
+
</session-browser>
|
| 350 |
+
<compiler>
|
| 351 |
+
<compile-type value="KEEP" />
|
| 352 |
+
<compile-dependencies value="ASK" />
|
| 353 |
+
<always-show-controls value="false" />
|
| 354 |
+
</compiler>
|
| 355 |
+
</operation-settings>
|
| 356 |
+
<ddl-file-settings>
|
| 357 |
+
<extensions>
|
| 358 |
+
<mapping file-type-id="VIEW" extensions="vw" />
|
| 359 |
+
<mapping file-type-id="TRIGGER" extensions="trg" />
|
| 360 |
+
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
| 361 |
+
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
| 362 |
+
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
| 363 |
+
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
| 364 |
+
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
| 365 |
+
<mapping file-type-id="TYPE" extensions="tpe" />
|
| 366 |
+
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
| 367 |
+
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
| 368 |
+
</extensions>
|
| 369 |
+
<general>
|
| 370 |
+
<lookup-ddl-files value="true" />
|
| 371 |
+
<create-ddl-files value="false" />
|
| 372 |
+
<synchronize-ddl-files value="true" />
|
| 373 |
+
<use-qualified-names value="false" />
|
| 374 |
+
<make-scripts-rerunnable value="true" />
|
| 375 |
+
</general>
|
| 376 |
+
</ddl-file-settings>
|
| 377 |
+
<general-settings>
|
| 378 |
+
<regional-settings>
|
| 379 |
+
<date-format value="MEDIUM" />
|
| 380 |
+
<number-format value="UNGROUPED" />
|
| 381 |
+
<locale value="SYSTEM_DEFAULT" />
|
| 382 |
+
<use-custom-formats value="false" />
|
| 383 |
+
</regional-settings>
|
| 384 |
+
<environment>
|
| 385 |
+
<environment-types>
|
| 386 |
+
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
| 387 |
+
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
| 388 |
+
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
| 389 |
+
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
| 390 |
+
</environment-types>
|
| 391 |
+
<visibility-settings>
|
| 392 |
+
<connection-tabs value="true" />
|
| 393 |
+
<dialog-headers value="true" />
|
| 394 |
+
<object-editor-tabs value="true" />
|
| 395 |
+
<script-editor-tabs value="false" />
|
| 396 |
+
<execution-result-tabs value="true" />
|
| 397 |
+
</visibility-settings>
|
| 398 |
+
</environment>
|
| 399 |
+
</general-settings>
|
| 400 |
+
</component>
|
| 401 |
+
</project>
|
.idea/inspectionProfiles/Project_Default.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<component name="InspectionProjectProfileManager">
|
| 2 |
+
<profile version="1.0">
|
| 3 |
+
<option name="myName" value="Project Default" />
|
| 4 |
+
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
| 5 |
+
</profile>
|
| 6 |
+
</component>
|
.idea/modules.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="ProjectModuleManager">
|
| 4 |
+
<modules>
|
| 5 |
+
<module fileurl="file://$PROJECT_DIR$/.idea/PoCInnovation.iml" filepath="$PROJECT_DIR$/.idea/PoCInnovation.iml" />
|
| 6 |
+
</modules>
|
| 7 |
+
</component>
|
| 8 |
+
</project>
|
.idea/prettier.xml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="PrettierConfiguration">
|
| 4 |
+
<option name="myConfigurationMode" value="AUTOMATIC" />
|
| 5 |
+
<option name="myRunOnSave" value="true" />
|
| 6 |
+
</component>
|
| 7 |
+
</project>
|
.idea/vcs.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<project version="4">
|
| 3 |
+
<component name="VcsDirectoryMappings">
|
| 4 |
+
<mapping directory="" vcs="Git" />
|
| 5 |
+
</component>
|
| 6 |
+
</project>
|
front/.gitignore
CHANGED
|
@@ -8,10 +8,10 @@ pnpm-debug.log*
|
|
| 8 |
lerna-debug.log*
|
| 9 |
|
| 10 |
node_modules
|
|
|
|
|
|
|
| 11 |
*.local
|
| 12 |
|
| 13 |
-
|
| 14 |
-
|
| 15 |
# Editor directories and files
|
| 16 |
.vscode/*
|
| 17 |
!.vscode/extensions.json
|
|
|
|
| 8 |
lerna-debug.log*
|
| 9 |
|
| 10 |
node_modules
|
| 11 |
+
dist
|
| 12 |
+
dist-ssr
|
| 13 |
*.local
|
| 14 |
|
|
|
|
|
|
|
| 15 |
# Editor directories and files
|
| 16 |
.vscode/*
|
| 17 |
!.vscode/extensions.json
|
front/components.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://ui.shadcn.com/schema.json",
|
| 3 |
+
"style": "new-york",
|
| 4 |
+
"rsc": false,
|
| 5 |
+
"tsx": true,
|
| 6 |
+
"tailwind": {
|
| 7 |
+
"config": "tailwind.config.js",
|
| 8 |
+
"css": "src/index.css",
|
| 9 |
+
"baseColor": "gray",
|
| 10 |
+
"cssVariables": true,
|
| 11 |
+
"prefix": ""
|
| 12 |
+
},
|
| 13 |
+
"aliases": {
|
| 14 |
+
"components": "@/components",
|
| 15 |
+
"utils": "@/lib/utils",
|
| 16 |
+
"ui": "@/components/ui",
|
| 17 |
+
"lib": "@/lib",
|
| 18 |
+
"hooks": "@/hooks"
|
| 19 |
+
}
|
| 20 |
+
}
|
front/dist/assets/index-CwlTocwK.css
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
#root{max-width:1280px;margin:0 auto;padding:2rem;text-align:center}.logo{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.react:hover{filter:drop-shadow(0 0 2em #61dafbaa)}@keyframes logo-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: no-preference){a:nth-of-type(2) .logo{animation:logo-spin infinite 20s linear}}.card{padding:2em}.read-the-docs{color:#888}@tailwind base;@tailwind components;@tailwind utilities;
|
|
|
|
|
|
front/dist/assets/index-IWZEvq7A.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
front/dist/assets/react-CHdo91hT.svg
DELETED
front/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Vite + React + TS</title>
|
| 8 |
-
<script type="module" crossorigin src="/assets/index-
|
| 9 |
<link rel="stylesheet" crossorigin href="/assets/index-CwlTocwK.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
|
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Vite + React + TS</title>
|
| 8 |
+
<script type="module" crossorigin src="/assets/index-PKNFqN2i.js"></script>
|
| 9 |
<link rel="stylesheet" crossorigin href="/assets/index-CwlTocwK.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
front/package-lock.json
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
front/package.json
CHANGED
|
@@ -10,18 +10,36 @@
|
|
| 10 |
"preview": "vite preview"
|
| 11 |
},
|
| 12 |
"dependencies": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
"react": "^18.3.1",
|
| 14 |
-
"react-dom": "^18.3.1"
|
|
|
|
|
|
|
|
|
|
| 15 |
},
|
| 16 |
"devDependencies": {
|
| 17 |
"@eslint/js": "^9.9.0",
|
|
|
|
| 18 |
"@types/react": "^18.3.3",
|
| 19 |
"@types/react-dom": "^18.3.0",
|
| 20 |
"@vitejs/plugin-react": "^4.3.1",
|
|
|
|
| 21 |
"eslint": "^9.9.0",
|
| 22 |
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
| 23 |
"eslint-plugin-react-refresh": "^0.4.9",
|
| 24 |
"globals": "^15.9.0",
|
|
|
|
| 25 |
"tailwindcss": "^3.4.13",
|
| 26 |
"typescript": "^5.5.3",
|
| 27 |
"typescript-eslint": "^8.0.1",
|
|
|
|
| 10 |
"preview": "vite preview"
|
| 11 |
},
|
| 12 |
"dependencies": {
|
| 13 |
+
"@emotion/css": "^11.13.0",
|
| 14 |
+
"@emotion/react": "^11.13.3",
|
| 15 |
+
"@emotion/styled": "^11.13.0",
|
| 16 |
+
"@mui/icons-material": "^6.1.1",
|
| 17 |
+
"@mui/material": "^6.1.1",
|
| 18 |
+
"@radix-ui/react-icons": "^1.3.0",
|
| 19 |
+
"@radix-ui/react-slot": "^1.1.0",
|
| 20 |
+
"@ramonak/react-progress-bar": "^5.3.0",
|
| 21 |
+
"class-variance-authority": "^0.7.0",
|
| 22 |
+
"clsx": "^2.1.1",
|
| 23 |
+
"lucide-react": "^0.446.0",
|
| 24 |
+
"prettier": "^3.3.3",
|
| 25 |
"react": "^18.3.1",
|
| 26 |
+
"react-dom": "^18.3.1",
|
| 27 |
+
"react-router-dom": "^6.26.2",
|
| 28 |
+
"tailwind-merge": "^2.5.2",
|
| 29 |
+
"tailwindcss-animate": "^1.0.7"
|
| 30 |
},
|
| 31 |
"devDependencies": {
|
| 32 |
"@eslint/js": "^9.9.0",
|
| 33 |
+
"@types/node": "^22.7.3",
|
| 34 |
"@types/react": "^18.3.3",
|
| 35 |
"@types/react-dom": "^18.3.0",
|
| 36 |
"@vitejs/plugin-react": "^4.3.1",
|
| 37 |
+
"autoprefixer": "^10.4.20",
|
| 38 |
"eslint": "^9.9.0",
|
| 39 |
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
| 40 |
"eslint-plugin-react-refresh": "^0.4.9",
|
| 41 |
"globals": "^15.9.0",
|
| 42 |
+
"postcss": "^8.4.47",
|
| 43 |
"tailwindcss": "^3.4.13",
|
| 44 |
"typescript": "^5.5.3",
|
| 45 |
"typescript-eslint": "^8.0.1",
|
front/postcss.config.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export default {
|
| 2 |
+
plugins: {
|
| 3 |
+
tailwindcss: {},
|
| 4 |
+
autoprefixer: {},
|
| 5 |
+
},
|
| 6 |
+
}
|
front/src/App.css
CHANGED
|
@@ -1,42 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
margin: 0 auto;
|
| 4 |
-
padding: 2rem;
|
| 5 |
-
text-align: center;
|
| 6 |
-
}
|
| 7 |
-
|
| 8 |
-
.logo {
|
| 9 |
-
height: 6em;
|
| 10 |
-
padding: 1.5em;
|
| 11 |
-
will-change: filter;
|
| 12 |
-
transition: filter 300ms;
|
| 13 |
-
}
|
| 14 |
-
.logo:hover {
|
| 15 |
-
filter: drop-shadow(0 0 2em #646cffaa);
|
| 16 |
-
}
|
| 17 |
-
.logo.react:hover {
|
| 18 |
-
filter: drop-shadow(0 0 2em #61dafbaa);
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
-
@keyframes logo-spin {
|
| 22 |
-
from {
|
| 23 |
-
transform: rotate(0deg);
|
| 24 |
-
}
|
| 25 |
-
to {
|
| 26 |
-
transform: rotate(360deg);
|
| 27 |
-
}
|
| 28 |
-
}
|
| 29 |
-
|
| 30 |
-
@media (prefers-reduced-motion: no-preference) {
|
| 31 |
-
a:nth-of-type(2) .logo {
|
| 32 |
-
animation: logo-spin infinite 20s linear;
|
| 33 |
-
}
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
.card {
|
| 37 |
-
padding: 2em;
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
.read-the-docs {
|
| 41 |
-
color: #888;
|
| 42 |
}
|
|
|
|
| 1 |
+
body {
|
| 2 |
+
background-color: "#000000";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
}
|
front/src/App.tsx
CHANGED
|
@@ -1,35 +1,25 @@
|
|
| 1 |
-
import
|
| 2 |
-
import
|
| 3 |
-
import
|
| 4 |
-
import
|
| 5 |
|
| 6 |
-
function
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
|
|
|
| 9 |
return (
|
| 10 |
<>
|
| 11 |
-
<
|
| 12 |
-
<
|
| 13 |
-
|
| 14 |
-
</a>
|
| 15 |
-
<a href="https://react.dev" target="_blank">
|
| 16 |
-
<img src={reactLogo} className="logo react" alt="React logo" />
|
| 17 |
-
</a>
|
| 18 |
-
</div>
|
| 19 |
-
<h1>Vite + React</h1>
|
| 20 |
-
<div className="card">
|
| 21 |
-
<button onClick={() => setCount((count) => count + 1)}>
|
| 22 |
-
count is {count}
|
| 23 |
-
</button>
|
| 24 |
-
<p>
|
| 25 |
-
Edit <code>src/App.tsx</code> and save to test Valentin
|
| 26 |
-
</p>
|
| 27 |
-
</div>
|
| 28 |
-
<p className="read-the-docs">
|
| 29 |
-
Click on the Vite and React logos to learn more
|
| 30 |
-
</p>
|
| 31 |
</>
|
| 32 |
-
)
|
| 33 |
}
|
| 34 |
|
| 35 |
-
export default App
|
|
|
|
| 1 |
+
import "./App.css";
|
| 2 |
+
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
| 3 |
+
import HomeScene from "./Homescene";
|
| 4 |
+
import VerificationScene from "./VerificationScene";
|
| 5 |
|
| 6 |
+
function PrivateApp() {
|
| 7 |
+
return (
|
| 8 |
+
<Routes>
|
| 9 |
+
<Route path="/" element={<HomeScene />} />
|
| 10 |
+
<Route path="/verification" element={<VerificationScene />} />
|
| 11 |
+
</Routes>
|
| 12 |
+
);
|
| 13 |
+
}
|
| 14 |
|
| 15 |
+
function App() {
|
| 16 |
return (
|
| 17 |
<>
|
| 18 |
+
<Router>
|
| 19 |
+
<PrivateApp />
|
| 20 |
+
</Router>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
</>
|
| 22 |
+
);
|
| 23 |
}
|
| 24 |
|
| 25 |
+
export default App;
|
front/src/Homescene.tsx
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState, useRef } from "react";
|
| 2 |
+
|
| 3 |
+
export default function HomeScene() {
|
| 4 |
+
const [, setSelectedFile] = useState<File | null>(null);
|
| 5 |
+
const fileInputRef = useRef<HTMLInputElement | null>(null); // Référence pour l'input fichier
|
| 6 |
+
|
| 7 |
+
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
| 8 |
+
if (event.target.files && event.target.files.length > 0) {
|
| 9 |
+
const file = event.target.files[0];
|
| 10 |
+
setSelectedFile(file);
|
| 11 |
+
handleUpload(file);
|
| 12 |
+
}
|
| 13 |
+
};
|
| 14 |
+
|
| 15 |
+
const handleUpload = async (file: File) => {
|
| 16 |
+
const formData = new FormData();
|
| 17 |
+
formData.append("file", file);
|
| 18 |
+
|
| 19 |
+
try {
|
| 20 |
+
const response = await fetch("https://your-backend-api/upload", {
|
| 21 |
+
method: "POST",
|
| 22 |
+
body: formData,
|
| 23 |
+
});
|
| 24 |
+
|
| 25 |
+
if (response.ok) {
|
| 26 |
+
console.log("Fichier uploadé avec succès");
|
| 27 |
+
} else {
|
| 28 |
+
console.error("Erreur lors de l'upload du fichier");
|
| 29 |
+
}
|
| 30 |
+
} catch (error) {
|
| 31 |
+
console.error("Erreur lors de l'upload du fichier :", error);
|
| 32 |
+
}
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
const handleButtonClick = () => {
|
| 36 |
+
if (fileInputRef.current) {
|
| 37 |
+
fileInputRef.current.click();
|
| 38 |
+
}
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
return (
|
| 42 |
+
<div className="flex h-screen bg-gray-100 items-center justify-center">
|
| 43 |
+
<a href="verification" className="mr-4">
|
| 44 |
+
<button className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
|
| 45 |
+
Verify Your Identity
|
| 46 |
+
</button>
|
| 47 |
+
</a>
|
| 48 |
+
|
| 49 |
+
<input
|
| 50 |
+
type="file"
|
| 51 |
+
ref={fileInputRef}
|
| 52 |
+
className="hidden"
|
| 53 |
+
onChange={handleFileChange}
|
| 54 |
+
/>
|
| 55 |
+
|
| 56 |
+
<button
|
| 57 |
+
onClick={handleButtonClick}
|
| 58 |
+
className="bg-purple-600 text-white px-4 py-2 rounded shadow-lg hover:bg-purple-700 transition"
|
| 59 |
+
>
|
| 60 |
+
Upload Private Document
|
| 61 |
+
</button>
|
| 62 |
+
</div>
|
| 63 |
+
);
|
| 64 |
+
}
|
front/src/VerificationScene.tsx
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from "react";
|
| 2 |
+
import BoxContainer from "./components/BoxContainer";
|
| 3 |
+
import VideoWrapper from "@/components/VideoWrapper.tsx";
|
| 4 |
+
import ResultContainer from "@/components/ResultContainer.tsx";
|
| 5 |
+
import DarkVideoWrapper from "@/components/DarkVideoWrapper.tsx";
|
| 6 |
+
|
| 7 |
+
enum StepType {
|
| 8 |
+
takeId,
|
| 9 |
+
verifyId,
|
| 10 |
+
takeFrontPic,
|
| 11 |
+
verifyProfile,
|
| 12 |
+
result,
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
const stepsArray: StepType[] = [
|
| 16 |
+
StepType.takeId,
|
| 17 |
+
StepType.verifyId,
|
| 18 |
+
StepType.takeFrontPic,
|
| 19 |
+
StepType.verifyProfile,
|
| 20 |
+
StepType.result,
|
| 21 |
+
];
|
| 22 |
+
|
| 23 |
+
export default function VerificationScene() {
|
| 24 |
+
const [currentStep, setCurrentStep] = useState<StepType>(StepType.takeId);
|
| 25 |
+
const [idCardPicture, setIdCardPicture] = useState<string>();
|
| 26 |
+
const [profilePicture, setProfilePicture] = useState<string>();
|
| 27 |
+
|
| 28 |
+
const handleNextStep = () => {
|
| 29 |
+
if (currentStep == StepType.result) return;
|
| 30 |
+
setCurrentStep((currentStep + 1) % stepsArray.length);
|
| 31 |
+
};
|
| 32 |
+
const handlePrevStep = () => {
|
| 33 |
+
if (currentStep == StepType.takeId) return;
|
| 34 |
+
setCurrentStep((currentStep - 1) % stepsArray.length);
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
const sendImageToServer = async (
|
| 38 |
+
imageDataUrl: string,
|
| 39 |
+
setLoading: (n: boolean) => void,
|
| 40 |
+
) => {
|
| 41 |
+
try {
|
| 42 |
+
const response = await fetch("YOUR_BACKEND_URL/api/upload", {
|
| 43 |
+
method: "POST",
|
| 44 |
+
headers: {
|
| 45 |
+
"Content-Type": "application/json",
|
| 46 |
+
},
|
| 47 |
+
body: JSON.stringify({ image: imageDataUrl }),
|
| 48 |
+
});
|
| 49 |
+
|
| 50 |
+
if (!response.ok) {
|
| 51 |
+
throw new Error("Erreur lors de l'envoi de l'image");
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
const data = await response.json();
|
| 55 |
+
console.log("Image envoyée avec succès:", data);
|
| 56 |
+
setLoading(true);
|
| 57 |
+
} catch (error) {
|
| 58 |
+
console.error("Erreur:", error);
|
| 59 |
+
setLoading(false);
|
| 60 |
+
}
|
| 61 |
+
};
|
| 62 |
+
|
| 63 |
+
let stepContent = undefined;
|
| 64 |
+
|
| 65 |
+
if (currentStep == StepType.takeId) {
|
| 66 |
+
stepContent = (
|
| 67 |
+
<>
|
| 68 |
+
<h1 className="text-black text-2xl mt-20 text-center px-28">
|
| 69 |
+
Take a picture of the Capture the front side of your ID Card
|
| 70 |
+
</h1>
|
| 71 |
+
<VideoWrapper
|
| 72 |
+
handleNextStep={handleNextStep}
|
| 73 |
+
setImage={setIdCardPicture}
|
| 74 |
+
className="shadow-lg mt-20"
|
| 75 |
+
height="250px"
|
| 76 |
+
width="400px"
|
| 77 |
+
/>
|
| 78 |
+
</>
|
| 79 |
+
);
|
| 80 |
+
}
|
| 81 |
+
if (currentStep == StepType.verifyId) {
|
| 82 |
+
stepContent = (
|
| 83 |
+
<>
|
| 84 |
+
<div className="overflow-hidden w-2/3 h-2/4 mt-10">
|
| 85 |
+
<img src={idCardPicture} alt="captured" />
|
| 86 |
+
</div>
|
| 87 |
+
<h1 className="text-2xl font-bold">Is This Picture Correct ?</h1>
|
| 88 |
+
<div className="mt-32 space-x-20">
|
| 89 |
+
<button
|
| 90 |
+
onClick={handlePrevStep}
|
| 91 |
+
className="bg-red-600 transition text-white rounded-2xl text-xl hover:bg-red-800 w-40 h-16"
|
| 92 |
+
>
|
| 93 |
+
No
|
| 94 |
+
</button>
|
| 95 |
+
<button
|
| 96 |
+
onClick={handleNextStep}
|
| 97 |
+
className="bg-blue-600 transition text-white rounded-2xl text-xl hover:bg-gray-800 w-40 h-16"
|
| 98 |
+
>
|
| 99 |
+
Yes
|
| 100 |
+
</button>
|
| 101 |
+
</div>
|
| 102 |
+
</>
|
| 103 |
+
);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
if (currentStep == StepType.takeFrontPic) {
|
| 107 |
+
stepContent = (
|
| 108 |
+
<>
|
| 109 |
+
<h1 className="mt-5 font-bold text-lg">Center your face</h1>
|
| 110 |
+
<DarkVideoWrapper
|
| 111 |
+
setImage={setProfilePicture}
|
| 112 |
+
className="mt-20 w-2/4 h-3/5 overflow-hidden"
|
| 113 |
+
handleNextStep={handleNextStep}
|
| 114 |
+
/>
|
| 115 |
+
</>
|
| 116 |
+
);
|
| 117 |
+
}
|
| 118 |
+
if (currentStep == StepType.verifyProfile) {
|
| 119 |
+
stepContent = (
|
| 120 |
+
<>
|
| 121 |
+
<div className="overflow-hidden w-2/3 h-2/4 mt-10">
|
| 122 |
+
<img src={profilePicture} alt="captured" />
|
| 123 |
+
</div>
|
| 124 |
+
<h1 className="text-2xl font-bold">Is This Picture Correct ?</h1>
|
| 125 |
+
<div className="mt-32 space-x-20">
|
| 126 |
+
<button
|
| 127 |
+
onClick={handlePrevStep}
|
| 128 |
+
className="bg-red-600 transition text-white rounded-2xl text-xl hover:bg-red-800 w-40 h-16"
|
| 129 |
+
>
|
| 130 |
+
No
|
| 131 |
+
</button>
|
| 132 |
+
<button
|
| 133 |
+
onClick={handleNextStep}
|
| 134 |
+
className="bg-blue-600 transition text-white rounded-2xl text-xl hover:bg-gray-800 w-40 h-16"
|
| 135 |
+
>
|
| 136 |
+
Yes (Submit)
|
| 137 |
+
</button>
|
| 138 |
+
</div>
|
| 139 |
+
</>
|
| 140 |
+
);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
if (currentStep == StepType.result) {
|
| 144 |
+
stepContent = (
|
| 145 |
+
<ResultContainer
|
| 146 |
+
sendImageToServer={sendImageToServer}
|
| 147 |
+
idCardPicture={idCardPicture ?? ""}
|
| 148 |
+
/>
|
| 149 |
+
);
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
return (
|
| 153 |
+
<>
|
| 154 |
+
<div className="bg-gray-100">
|
| 155 |
+
<BoxContainer headerName="Identity Verification Required">
|
| 156 |
+
<div className="h-full w-full flex flex-col items-center overflow-hidden">
|
| 157 |
+
{stepContent}
|
| 158 |
+
</div>
|
| 159 |
+
</BoxContainer>
|
| 160 |
+
</div>
|
| 161 |
+
</>
|
| 162 |
+
);
|
| 163 |
+
}
|
front/src/components/BoxContainer.tsx
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
|
| 3 |
+
export default function BoxContainer({
|
| 4 |
+
children,
|
| 5 |
+
headerName,
|
| 6 |
+
}: {
|
| 7 |
+
children?: React.ReactNode | React.ReactNode[];
|
| 8 |
+
headerName?: string;
|
| 9 |
+
}) {
|
| 10 |
+
return (
|
| 11 |
+
<div className="flex items-center justify-center h-screen">
|
| 12 |
+
<div className="flex flex-col bg-white h-3/4 w-[40%] mt-0 rounded-xl border-gray-700 shadow-lg">
|
| 13 |
+
<div className="ml-0 border-b items-center p-4 font-bold bg-gray-50">
|
| 14 |
+
{headerName}
|
| 15 |
+
</div>
|
| 16 |
+
{children}
|
| 17 |
+
</div>
|
| 18 |
+
</div>
|
| 19 |
+
);
|
| 20 |
+
}
|
front/src/components/DarkVideoWrapper.tsx
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useEffect, useRef } from "react";
|
| 2 |
+
interface VideoWrapperProps {
|
| 3 |
+
width?: string | number;
|
| 4 |
+
height?: string | number;
|
| 5 |
+
className?: string;
|
| 6 |
+
handleNextStep: () => void; // Function to handle the next step
|
| 7 |
+
setImage: (imageDataUrl: string) => void; // Function to set the image data URL
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
const DarkVideoWrapper: React.FC<VideoWrapperProps> = ({
|
| 11 |
+
width,
|
| 12 |
+
height,
|
| 13 |
+
className,
|
| 14 |
+
handleNextStep,
|
| 15 |
+
setImage,
|
| 16 |
+
}) => {
|
| 17 |
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
| 18 |
+
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
| 19 |
+
|
| 20 |
+
useEffect(() => {
|
| 21 |
+
const startCamera = async () => {
|
| 22 |
+
try {
|
| 23 |
+
const stream = await navigator.mediaDevices.getUserMedia({
|
| 24 |
+
video: true,
|
| 25 |
+
});
|
| 26 |
+
if (videoRef.current) {
|
| 27 |
+
videoRef.current.srcObject = stream;
|
| 28 |
+
}
|
| 29 |
+
} catch (error) {
|
| 30 |
+
console.error("Erreur lors de l'accès à la caméra :", error);
|
| 31 |
+
}
|
| 32 |
+
};
|
| 33 |
+
|
| 34 |
+
startCamera();
|
| 35 |
+
|
| 36 |
+
return () => {
|
| 37 |
+
if (videoRef.current) {
|
| 38 |
+
const stream = videoRef.current.srcObject as MediaStream;
|
| 39 |
+
if (stream) {
|
| 40 |
+
const tracks = stream.getTracks();
|
| 41 |
+
tracks.forEach((track) => track.stop());
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
};
|
| 45 |
+
}, []);
|
| 46 |
+
|
| 47 |
+
const captureImage = async () => {
|
| 48 |
+
const canvas = canvasRef.current;
|
| 49 |
+
const video = videoRef.current;
|
| 50 |
+
|
| 51 |
+
if (canvas && video) {
|
| 52 |
+
const context = canvas.getContext("2d");
|
| 53 |
+
if (context) {
|
| 54 |
+
canvas.width = video.videoWidth; // Width of the video
|
| 55 |
+
canvas.height = video.videoHeight; // Height of the video
|
| 56 |
+
context.drawImage(video, 0, 0, canvas.width, canvas.height); // Draw the video on the canvas
|
| 57 |
+
|
| 58 |
+
return canvas.toDataURL("image/png"); // Return the image as a Data URL
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
};
|
| 62 |
+
|
| 63 |
+
return (
|
| 64 |
+
<>
|
| 65 |
+
<div
|
| 66 |
+
className={`relative shadow-blue-200 ${className}`}
|
| 67 |
+
style={{
|
| 68 |
+
width,
|
| 69 |
+
height,
|
| 70 |
+
backgroundColor: "black",
|
| 71 |
+
display: "flex",
|
| 72 |
+
justifyContent: "center",
|
| 73 |
+
alignItems: "center",
|
| 74 |
+
overflow: "hidden",
|
| 75 |
+
}}
|
| 76 |
+
>
|
| 77 |
+
<video
|
| 78 |
+
ref={videoRef}
|
| 79 |
+
autoPlay
|
| 80 |
+
muted
|
| 81 |
+
style={{
|
| 82 |
+
display: "block",
|
| 83 |
+
width: "100%",
|
| 84 |
+
height: "100%",
|
| 85 |
+
objectFit: "cover",
|
| 86 |
+
}}
|
| 87 |
+
/>
|
| 88 |
+
<canvas ref={canvasRef} style={{ display: "none" }} />{" "}
|
| 89 |
+
{/* Hidden canvas */}
|
| 90 |
+
</div>
|
| 91 |
+
<button
|
| 92 |
+
onClick={async () => {
|
| 93 |
+
const imageDataUrl = await captureImage(); // Capture the image
|
| 94 |
+
setImage(imageDataUrl ?? ""); // Set the captured image
|
| 95 |
+
handleNextStep(); // Proceed to the next step
|
| 96 |
+
}}
|
| 97 |
+
className="bg-blue-600 transition text-white rounded-2xl text-xl hover:bg-gray-800 mt-16 w-40 h-16"
|
| 98 |
+
>
|
| 99 |
+
Continue
|
| 100 |
+
</button>
|
| 101 |
+
</>
|
| 102 |
+
);
|
| 103 |
+
};
|
| 104 |
+
|
| 105 |
+
export default DarkVideoWrapper;
|
front/src/components/ResultContainer.tsx
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect, useState } from "react";
|
| 2 |
+
|
| 3 |
+
export default function ResultContainer({
|
| 4 |
+
sendImageToServer,
|
| 5 |
+
idCardPicture,
|
| 6 |
+
}: {
|
| 7 |
+
sendImageToServer: (pic: string, setLoading: (n: boolean) => void) => void;
|
| 8 |
+
idCardPicture: string;
|
| 9 |
+
}) {
|
| 10 |
+
const [loading, setLoading] = useState<boolean>(true);
|
| 11 |
+
|
| 12 |
+
useEffect(() => {
|
| 13 |
+
sendImageToServer(idCardPicture ?? "", setLoading);
|
| 14 |
+
}, []);
|
| 15 |
+
return <>{loading ? <>Fetching</> : <>Perfect</>}</>;
|
| 16 |
+
}
|
front/src/components/VideoWrapper.tsx
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useEffect, useRef } from "react";
|
| 2 |
+
interface VideoWrapperProps {
|
| 3 |
+
width?: string | number;
|
| 4 |
+
height?: string | number;
|
| 5 |
+
className?: string;
|
| 6 |
+
handleNextStep: () => void; // Function to handle the next step
|
| 7 |
+
setImage: (imageDataUrl: string) => void; // Function to set the image data URL
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// VideoWrapper component
|
| 11 |
+
const VideoWrapper: React.FC<VideoWrapperProps> = ({
|
| 12 |
+
width,
|
| 13 |
+
height,
|
| 14 |
+
className,
|
| 15 |
+
handleNextStep,
|
| 16 |
+
setImage,
|
| 17 |
+
}) => {
|
| 18 |
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
| 19 |
+
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
| 20 |
+
|
| 21 |
+
useEffect(() => {
|
| 22 |
+
const startCamera = async () => {
|
| 23 |
+
try {
|
| 24 |
+
const stream = await navigator.mediaDevices.getUserMedia({
|
| 25 |
+
video: true,
|
| 26 |
+
});
|
| 27 |
+
if (videoRef.current) {
|
| 28 |
+
videoRef.current.srcObject = stream;
|
| 29 |
+
}
|
| 30 |
+
} catch (error) {
|
| 31 |
+
console.error("Erreur lors de l'accès à la caméra :", error);
|
| 32 |
+
}
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
startCamera();
|
| 36 |
+
|
| 37 |
+
return () => {
|
| 38 |
+
if (videoRef.current) {
|
| 39 |
+
const stream = videoRef.current.srcObject as MediaStream;
|
| 40 |
+
if (stream) {
|
| 41 |
+
const tracks = stream.getTracks();
|
| 42 |
+
tracks.forEach((track) => track.stop());
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
};
|
| 46 |
+
}, []);
|
| 47 |
+
|
| 48 |
+
const captureImage = async () => {
|
| 49 |
+
const canvas = canvasRef.current;
|
| 50 |
+
const video = videoRef.current;
|
| 51 |
+
|
| 52 |
+
if (canvas && video) {
|
| 53 |
+
const context = canvas.getContext("2d");
|
| 54 |
+
if (context) {
|
| 55 |
+
canvas.width = video.videoWidth; // Width of the video
|
| 56 |
+
canvas.height = video.videoHeight; // Height of the video
|
| 57 |
+
context.drawImage(video, 0, 0, canvas.width, canvas.height); // Draw the video on the canvas
|
| 58 |
+
|
| 59 |
+
return canvas.toDataURL("image/png"); // Return the image as a Data URL
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
return (
|
| 65 |
+
<>
|
| 66 |
+
<div
|
| 67 |
+
className={`relative shadow-blue-200 ${className}`}
|
| 68 |
+
style={{
|
| 69 |
+
width,
|
| 70 |
+
height,
|
| 71 |
+
backgroundColor: "black",
|
| 72 |
+
display: "flex",
|
| 73 |
+
justifyContent: "center",
|
| 74 |
+
alignItems: "center",
|
| 75 |
+
overflow: "hidden",
|
| 76 |
+
}}
|
| 77 |
+
>
|
| 78 |
+
<video
|
| 79 |
+
ref={videoRef}
|
| 80 |
+
autoPlay
|
| 81 |
+
muted
|
| 82 |
+
style={{
|
| 83 |
+
display: "block",
|
| 84 |
+
width: "100%",
|
| 85 |
+
height: "100%",
|
| 86 |
+
objectFit: "cover",
|
| 87 |
+
}}
|
| 88 |
+
/>
|
| 89 |
+
<canvas ref={canvasRef} style={{ display: "none" }} />{" "}
|
| 90 |
+
{/* Hidden canvas */}
|
| 91 |
+
</div>
|
| 92 |
+
<button
|
| 93 |
+
onClick={async () => {
|
| 94 |
+
const imageDataUrl = await captureImage(); // Capture the image
|
| 95 |
+
setImage(imageDataUrl ?? ""); // Set the captured image
|
| 96 |
+
handleNextStep(); // Proceed to the next step
|
| 97 |
+
}}
|
| 98 |
+
className="bg-blue-600 transition text-white rounded-2xl text-xl hover:bg-gray-800 mt-32 w-40 h-16"
|
| 99 |
+
>
|
| 100 |
+
Continue
|
| 101 |
+
</button>
|
| 102 |
+
</>
|
| 103 |
+
);
|
| 104 |
+
};
|
| 105 |
+
|
| 106 |
+
export default VideoWrapper;
|
front/src/components/ui/button.tsx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react";
|
| 2 |
+
import { Slot } from "@radix-ui/react-slot";
|
| 3 |
+
import { cva, type VariantProps } from "class-variance-authority";
|
| 4 |
+
|
| 5 |
+
import { cn } from "@/lib/utils";
|
| 6 |
+
|
| 7 |
+
const buttonVariants = cva(
|
| 8 |
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
| 9 |
+
{
|
| 10 |
+
variants: {
|
| 11 |
+
variant: {
|
| 12 |
+
default:
|
| 13 |
+
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
| 14 |
+
destructive:
|
| 15 |
+
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
| 16 |
+
outline:
|
| 17 |
+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
| 18 |
+
secondary:
|
| 19 |
+
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
| 20 |
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
| 21 |
+
link: "text-primary underline-offset-4 hover:underline",
|
| 22 |
+
},
|
| 23 |
+
size: {
|
| 24 |
+
default: "h-9 px-4 py-2",
|
| 25 |
+
sm: "h-8 rounded-md px-3 text-xs",
|
| 26 |
+
lg: "h-10 rounded-md px-8",
|
| 27 |
+
icon: "h-9 w-9",
|
| 28 |
+
},
|
| 29 |
+
},
|
| 30 |
+
defaultVariants: {
|
| 31 |
+
variant: "default",
|
| 32 |
+
size: "default",
|
| 33 |
+
},
|
| 34 |
+
},
|
| 35 |
+
);
|
| 36 |
+
|
| 37 |
+
export interface ButtonProps
|
| 38 |
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
| 39 |
+
VariantProps<typeof buttonVariants> {
|
| 40 |
+
asChild?: boolean;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
| 44 |
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
| 45 |
+
const Comp = asChild ? Slot : "button";
|
| 46 |
+
return (
|
| 47 |
+
<Comp
|
| 48 |
+
className={cn(buttonVariants({ variant, size, className }))}
|
| 49 |
+
ref={ref}
|
| 50 |
+
{...props}
|
| 51 |
+
/>
|
| 52 |
+
);
|
| 53 |
+
},
|
| 54 |
+
);
|
| 55 |
+
Button.displayName = "Button";
|
| 56 |
+
|
| 57 |
+
export { Button, buttonVariants };
|
front/src/index.css
CHANGED
|
@@ -1,3 +1,10 @@
|
|
| 1 |
@tailwind base;
|
| 2 |
@tailwind components;
|
| 3 |
@tailwind utilities;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
@tailwind base;
|
| 2 |
@tailwind components;
|
| 3 |
@tailwind utilities;
|
| 4 |
+
|
| 5 |
+
.face {
|
| 6 |
+
clip-path: polygon(51% 0, 83% 15%, 92% 44%, 86% 75%, 76% 92%, 54% 100%, 29% 94%, 17% 81%, 9% 42%, 18% 14%);
|
| 7 |
+
border-color: aqua;
|
| 8 |
+
border-width: 2px;;
|
| 9 |
+
|
| 10 |
+
}
|
front/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { clsx, type ClassValue } from "clsx"
|
| 2 |
+
import { twMerge } from "tailwind-merge"
|
| 3 |
+
|
| 4 |
+
export function cn(...inputs: ClassValue[]) {
|
| 5 |
+
return twMerge(clsx(inputs))
|
| 6 |
+
}
|
front/tailwind.config.js
CHANGED
|
@@ -1,8 +1,57 @@
|
|
| 1 |
/** @type {import('tailwindcss').Config} */
|
| 2 |
module.exports = {
|
| 3 |
-
|
|
|
|
| 4 |
theme: {
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
},
|
| 7 |
-
plugins: [],
|
| 8 |
};
|
|
|
|
| 1 |
/** @type {import('tailwindcss').Config} */
|
| 2 |
module.exports = {
|
| 3 |
+
darkMode: ["class"],
|
| 4 |
+
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
| 5 |
theme: {
|
| 6 |
+
extend: {
|
| 7 |
+
borderRadius: {
|
| 8 |
+
lg: 'var(--radius)',
|
| 9 |
+
md: 'calc(var(--radius) - 2px)',
|
| 10 |
+
sm: 'calc(var(--radius) - 4px)'
|
| 11 |
+
},
|
| 12 |
+
colors: {
|
| 13 |
+
background: 'hsl(var(--background))',
|
| 14 |
+
foreground: 'hsl(var(--foreground))',
|
| 15 |
+
card: {
|
| 16 |
+
DEFAULT: 'hsl(var(--card))',
|
| 17 |
+
foreground: 'hsl(var(--card-foreground))'
|
| 18 |
+
},
|
| 19 |
+
popover: {
|
| 20 |
+
DEFAULT: 'hsl(var(--popover))',
|
| 21 |
+
foreground: 'hsl(var(--popover-foreground))'
|
| 22 |
+
},
|
| 23 |
+
primary: {
|
| 24 |
+
DEFAULT: 'hsl(var(--primary))',
|
| 25 |
+
foreground: 'hsl(var(--primary-foreground))'
|
| 26 |
+
},
|
| 27 |
+
secondary: {
|
| 28 |
+
DEFAULT: 'hsl(var(--secondary))',
|
| 29 |
+
foreground: 'hsl(var(--secondary-foreground))'
|
| 30 |
+
},
|
| 31 |
+
muted: {
|
| 32 |
+
DEFAULT: 'hsl(var(--muted))',
|
| 33 |
+
foreground: 'hsl(var(--muted-foreground))'
|
| 34 |
+
},
|
| 35 |
+
accent: {
|
| 36 |
+
DEFAULT: 'hsl(var(--accent))',
|
| 37 |
+
foreground: 'hsl(var(--accent-foreground))'
|
| 38 |
+
},
|
| 39 |
+
destructive: {
|
| 40 |
+
DEFAULT: 'hsl(var(--destructive))',
|
| 41 |
+
foreground: 'hsl(var(--destructive-foreground))'
|
| 42 |
+
},
|
| 43 |
+
border: 'hsl(var(--border))',
|
| 44 |
+
input: 'hsl(var(--input))',
|
| 45 |
+
ring: 'hsl(var(--ring))',
|
| 46 |
+
chart: {
|
| 47 |
+
'1': 'hsl(var(--chart-1))',
|
| 48 |
+
'2': 'hsl(var(--chart-2))',
|
| 49 |
+
'3': 'hsl(var(--chart-3))',
|
| 50 |
+
'4': 'hsl(var(--chart-4))',
|
| 51 |
+
'5': 'hsl(var(--chart-5))'
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
},
|
| 56 |
+
plugins: [require("tailwindcss-animate")],
|
| 57 |
};
|
front/tsconfig.app.json
CHANGED
|
@@ -18,7 +18,12 @@
|
|
| 18 |
"strict": true,
|
| 19 |
"noUnusedLocals": true,
|
| 20 |
"noUnusedParameters": true,
|
| 21 |
-
"noFallthroughCasesInSwitch": true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
},
|
| 23 |
"include": ["src"]
|
| 24 |
}
|
|
|
|
| 18 |
"strict": true,
|
| 19 |
"noUnusedLocals": true,
|
| 20 |
"noUnusedParameters": true,
|
| 21 |
+
"noFallthroughCasesInSwitch": true,
|
| 22 |
+
|
| 23 |
+
"baseUrl": ".",
|
| 24 |
+
"paths": {
|
| 25 |
+
"@/*": ["./src/*"]
|
| 26 |
+
}
|
| 27 |
},
|
| 28 |
"include": ["src"]
|
| 29 |
}
|
front/tsconfig.app.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"root":["./src/
|
|
|
|
| 1 |
+
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts"],"version":"5.6.2"}
|
front/tsconfig.json
CHANGED
|
@@ -3,5 +3,11 @@
|
|
| 3 |
"references": [
|
| 4 |
{ "path": "./tsconfig.app.json" },
|
| 5 |
{ "path": "./tsconfig.node.json" }
|
| 6 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
}
|
|
|
|
| 3 |
"references": [
|
| 4 |
{ "path": "./tsconfig.app.json" },
|
| 5 |
{ "path": "./tsconfig.node.json" }
|
| 6 |
+
],
|
| 7 |
+
"compilerOptions": {
|
| 8 |
+
"baseUrl": ".",
|
| 9 |
+
"paths": {
|
| 10 |
+
"@/*": ["./src/*"]
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
}
|
front/vite.config.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
| 1 |
-
import { defineConfig } from
|
| 2 |
-
import react from
|
|
|
|
| 3 |
|
| 4 |
-
// https://vitejs.dev/config/
|
| 5 |
export default defineConfig({
|
| 6 |
plugins: [react()],
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from "vite";
|
| 2 |
+
import react from "@vitejs/plugin-react";
|
| 3 |
+
import path from "path";
|
| 4 |
|
|
|
|
| 5 |
export default defineConfig({
|
| 6 |
plugins: [react()],
|
| 7 |
+
resolve: {
|
| 8 |
+
alias: {
|
| 9 |
+
"@": path.resolve(__dirname, "src"),
|
| 10 |
+
},
|
| 11 |
+
},
|
| 12 |
+
});
|